[英]Is what I'm doing an Insertion sort, I think the logic is correct but unconventional?
这段代码应该是一个插入排序,但它是这样实现的吗? 我迷路了。 第一个循环遍历数组并检查下一个元素是否小于当前元素。 嵌套循环将下一个元素 (j) 正确插入到数组已排序部分的位置。
#include <iostream>
using namespace std;
// Print array
void printArray(int array[], int arraySize)
{
for (int i = 0; i < arraySize; i++)
{
cout << array[i] << " ";
}
cout << endl;
}
int main()
{
int array1[] ={5, 3, 1, 9, 8, 2, 4, 7};
int array1Size = sizeof(array1)/sizeof(int);
printArray(array1, array1Size);
for (int i = 0; i < array1Size - 1; i++)
{
int oldNum = array1[i];
if (array1[i] > array1[i + 1])
{
array1[i] = array1[i + 1];
array1[i + 1] = oldNum;
}
int newI = array1[i];
// Check if arranged correctly
if ( i > 0)
{
// Swap bigger number and newI
for (int j = i - 1; newI < array1[j]; j--)
{
if (j < 0)
{
break;
}
array1[j + 1] = array1[j];
array1[j] = newI;
}
}
printArray(array1, array1Size);
}
return 0;
}
插入排序的关键是维护一个“排序区域”并循环扩展它。 开始区域只有一个元素,最后是所有列表。 我们在排序区域之外取一个元素,并决定它应该放置在排序区域中的哪个 position 中。
顺便说一句,循环不变式很容易理解,但功能强大且令人敬畏。 推荐的。
int main() {
int array1[] ={5, 3, 1, 9, 8, 2, 4, 7};
int array1Size = sizeof(array1)/sizeof(int);
// loop invariant: array1[0..i-1] is sorted
// array1[i] is the element to be inserted
for (size_t i = 1; i < array1Size; i++) {
int temp = array1[i];
// find the right place to insert array1[i]. Can be replaced by binary search(but moving elements is more expensive than comparing)
size_t j = i; // j is used to save the right place
for (; j > 0 && array1[j-1] > temp; j--) {
array1[j] = array1[j-1];
}
array1[j] = temp;
}
return 0;
}
这个for循环
for (int j = i - 1; newI < array1[j]; j--)
{
if (j < 0)
{
break;
}
array1[j + 1] = array1[j];
array1[j] = newI;
}
由于 for 循环条件中的此表达式,当j
等于-1
时可以调用未定义的行为
newI < array1[j]
而且代码太复杂了。 例如这个代码片段
if (array1[i] > array1[i + 1])
{
array1[i] = array1[i + 1];
array1[i + 1] = oldNum;
}
交换两个元素的地方是多余的。 而这个 if 语句
if ( i > 0)
{
也是多余的。 从 1 而不是从 0 开始外循环就足够了。
最好定义一个单独的 function。 例如,它可以通过以下方式查看
void InsertionSort( int a[], size_t n )
{
for (size_t i = 1; i < n; i++)
{
if (a[i] < a[i - 1])
{
int tmp = a[i];
size_t j = i;
for ( ; j != 0 && tmp < a[j - 1]; --j )
{
a[j] = a[j - 1];
}
a[j] = tmp;
}
}
}
请注意,运算符sizeof
会产生size_t
类型的值。 您应该将此类型size_t
用于将存储数组中元素数量的变量。 通常int
类型不足以存储 arrays 的大小。
如果您的编译器支持 C++ 17 则不要使用带有sizeof
运算符的表达式
int array1Size = sizeof(array1)/sizeof(int);
你至少可以写
#include <iterator>
//...
int array1Size = std::size( array1 );
此外,由于 function printArray 不会更改传递的数组,因此应使用限定符const
声明它的第一个参数。
void printArray(const int array[], int arraySize);
这是一个演示程序,显示了使用插入排序方法对 arrays 进行排序的单独 function 的用法。
#include <iostream>
#include <iterator>
void InsertionSort( int a[], size_t n )
{
for (size_t i = 1; i < n; i++)
{
if (a[i] < a[i - 1])
{
int tmp = a[i];
size_t j = i;
for ( ; j != 0 && tmp < a[j - 1]; --j )
{
a[j] = a[j - 1];
}
a[j] = tmp;
}
}
}
int main()
{
int array1[] ={5, 3, 1, 9, 8, 2, 4, 7};
for ( const auto &item : array1 )
{
std::cout << item << ' ';
}
std::cout << '\n';
InsertionSort( array1, std::size( array1 ) );
for ( const auto &item : array1 )
{
std::cout << item << ' ';
}
std::cout << '\n';
}
程序 output 是
5 3 1 9 8 2 4 7
1 2 3 4 5 7 8 9
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.