算法提高 插入排序

算法提高 插入排序
排序,顧名思義,是將若干個元素按其大小關係排出一個順序。形式化描述如下:有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;
}
發佈了55 篇原創文章 · 獲贊 8 · 訪問量 3994
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章