算法提高 插入排序
排序,顧名思義,是將若干個元素按其大小關係排出一個順序。形式化描述如下:有n個元素a[1],a[2],…,a[n],從小到大排序就是將它們排成一個新順序a[i[1]]<a[i[2]]<…<a[i[n]]
i[k]爲這個新順序。
插入排序,顧名思義,是通過插入操作完成排序。其直覺和方法來源於打牌時安排牌的方法。每次摸起一張牌,你都會將其插入到現在手牌中它按順序應在的那個位置。插入排序每一步都類似這個摸牌過程。比如現在有整數數組:{3, 1, 5, 4, 2}
第一步:插入3 得到新序列{3}
第二步:插入1 得到新序列{1 3}
第三步:插入5 得到新序列{1 3 5}
第四步:插入4 得到新序列{1 3 4 5}
第五步:插入2 得到新序列{1 2 3 4 5}
爲了看程序中如何完成插入過程,我們以第五步爲例:
初始時:1 3 4 5 2
將2存入臨時變量tmp
將下標j指向2之前的元素5,然後根據tmp和a[j]的大小關係決定該元素是否應該後移。如果a[j]>tmp,則將a[j]後移到a[j+1],序列變成1 3 4 5 5。
將下標j前移
判斷a[j]>tmp,後移a[j]到a[j+1],得到1 3 4 4 5
將下標j前移
判斷a[j]>tmp,後移a[j]到a[j+1],得到1 3 3 4 5
因爲a[j]<=tmp,所以將tmp放回a[j+1],得到 1 2 3 4 5
現在,輸入n個整數,根據以上算法,輸出插入排序的全過程。
輸入格式:
第一行一個正整數n,表示元素個數
第二行爲n個整數,以空格隔開
輸出格式:
有n個元素,因此輸出部分分爲n個部分,每個部分開頭行爲:Insert element[i],i爲第幾個元素。然後對於每一個部分,輸出該部分該元素在插入排序過程中的每一步產生的新序列,初始時的序列以Init:打頭,然 後每一步後移數組元素後的元素序列以Move back:打頭,最後得到的最終結果序列以Final:打頭。序列元素間以一個空格隔開。示例請看樣例輸出。每一個部分的Insert element[i]之後的每一步的輸出行之前要縮進兩格,即輸出兩個空格。
輸入樣例:
在這裏給出一組輸入。例如:
5
3 1 5 4 2
輸出樣例:
在這裏給出相應的輸出。例如:
Insert element[1]:
Init:3
Final:3
Insert element[2]:
Init:3 1
Move back:3 3
Final:1 3
Insert element[3]:
Init:1 3 5
Final:1 3 5
Insert element[4]:
Init:1 3 5 4
Move back:1 3 5 5
Final:1 3 4 5
Insert element[5]:
Init:1 3 4 5 2
Move back:1 3 4 5 5
Move back:1 3 4 4 5
Move back:1 3 3 4 5
Final:1 2 3 4 5
數據規模和約定
n<=100
整數元素在int範圍內
方法:
這道題排序我是每次從倒數第二個向前開始循環,位置爲i,當i大於正排的數a的值的時候此時i+1就等於i的值,i就等於i-1的值,這就實現一次move back,最後還要考慮最前面的數是否大於要排的數a,如果小於,把a的值賦給數組下標0的值。然後後面就是特殊情況的考慮,數組長度小於2時要單獨考慮。(因爲i-1會越界)
代碼:
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
int main()
{
int n,a,flag=0;
cin >> n;
vector<int>arr;//排序的數組
for (int i = 0; i < n; i++)
{
cin >> a;
printf("Insert element[%d]:\n", i + 1);
arr.push_back(a);//把a插入到數組末尾
printf(" Init:");
for (int j = 0; j < arr.size(); j++)
{
if (j != 0)
cout << ' ';
cout << arr[j];
}
cout << endl;
if (arr.size() > 2)//數組長度大於2的情況
{
for (int j = arr.size() - 2; j >= 0; j--)
{
if (arr[j] > a)
{
arr[j+1] = arr[j];
arr[j] == arr[j-1];
}
else
{
arr[j+1] = a;
break;
}
cout << " Move back:";
for (int k = 0; k < arr.size(); k++)
{
if (k != 0)
cout << ' ';
cout << arr[k];
}
cout << endl;
}
if (arr[0] > a)//考慮最目前數組最小的數仍小於a(即第一個數仍小於a)
arr[0] = a;
}
else if (arr.size() == 2)//長度爲2的情況
{
if(arr[1]<arr[0])
{
arr[1] = arr[0];
cout << " Move back:"<<arr[0]<<' '<<arr[1]<<endl;
arr[0] = a;
}
}
cout << " Final:";
for (int k = 0; k < arr.size(); k++)
{
if (k != 0)
cout << ' ';
cout << arr[k];
}
cout << endl;
}
return 0;
}