[英]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.