Я пытаюсь выяснить, как найти общее количество свопов и сравнений, используемых в функции сортировки оболочки, но я не совсем уверен, где разместить добавления свопов и сравнений.
Я добавляю дополнения к этой функции InsertSort ниже.
void insertionSortInterleaved(int numbers[], int numbersSize, int startIndex, int gap) {
int i = 0;
int j = 0;
int temp = 0;
for (i = startIndex + gap; i < numbersSize; i += gap) {
j = i;
while (j - gap >= startIndex && numbers[j] < numbers[j - 1]) {
temp = numbers[j];
numbers[j] = numbers[j - gap];
numbers[j - gap] = temp;
j = j - gap;
totalComps++; //declared globally
totalSwaps++; //declared globally
}
}
}
Я знаю, что totalSwaps хорош там, где он есть, но я не совсем уверен, куда поместить totalComps, поскольку мы также сравниваем в цикле while.
@hellow, поэтому у меня также есть функция сортировки оболочки, которая передает totalComps и totalSwaps в структуру
Не обязательно. Просто создайте структуру в начале этой функции и верните ее в конце. Вы не используете рекурсию или ранние выходы, так что это нормально.
Считаете ли вы сравнения значений в numbers или любое использование <, >, <=, >=?
Также: вы имеете в виду numbers[j] < numbers[j - gap] вместо numbers[j] < numbers[j - 1] в состоянии петли? везде вы используете gap в качестве приращения





Я думаю, что сравнение должно быть засчитано, даже если условие было ложным
Это означало только сравнение элементов массива, а не каждое сравнение в вашем коде ...
void insertionSortInterleaved(int numbers[], int numbersSize, int startIndex, int gap) {
int i = 0;
int j = 0;
int temp = 0;
for (i = startIndex + gap; i < numbersSize; i += gap) {
j = i;
while (j - gap >= startIndex) {
//each iteration is compare so increment here
totalComps++; //declared globally
if ( numbers[j] < numbers[j - 1]) {
temp = numbers[j];
numbers[j] = numbers[j - gap];
numbers[j - gap] = temp;
j = j - gap;
//had a swap
totalSwaps++; //declared globally
}
else break;
}
}
}
Увеличивайте условный счетчик каждый раз, когда проводите тест.
Компактный способ сделать это - добавить к операции увеличения перед каждым тестом префикс && (что будет успешным, поскольку счетчик положительный, так как переменная беззнаковая беззнаковая):
for (i = startIndex + gap; ++totalComps && (i < numbersSize); i += gap) {
а также
while (++totalComps && (j - gap >= startIndex) && ++totalComps && (numbers[j] < numbers[j - 1])) {
Вы можете использовать пару функциональные объекты, один для сравнения, а другой для обмена.
struct counted_less
{
int count = 0;
bool operator()(int lhs, int rhs)
{
++count;
return lhs < rhs;
}
}
struct counted_swap
{
int count = 0;
void operator()(int & lhs, int & rhs)
{
++count;
using std::swap;
swap(lhs, rhs);
}
}
std::pair<int, int> insertionSortInterleaved(int numbers[], int numbersSize, int startIndex, int gap) {
counted_less less;
counted_swap swap;
for (int i = startIndex + gap; i < numbersSize; i += gap) {
for (int j = i; j - gap >= startIndex && less(numbers[j], numbers[j - 1]); j -= gap) {
swap(numbers[j], numbers[j - gap]);
}
}
return { less.count, swap.count };
}
Глобалы - зло, избегайте их по возможности! Вместо этого верните структуру с двумя членами
totalCompsиtotalSwaps.