經典演算法之直接插入排序及其優化

wardseptember發表於2017-12-09
/************************
author's email:wardseptember@gmail.com
date:2017.12.9
直接插入排序
************************/
/*
每一趟將一個待排序的關鍵字按照其值得大小插入到已經排序好的部分有序序列的適當位置上,
直到所有待排序關鍵字都被插入到有序序列中為止。第一趟,把第一個關鍵字看做有序列的,從
第二關鍵字開始插入。
*/
#include<iostream>
#define maxSize 10
using namespace std;
void directlyInsertSort1(int D[], int n);//直接插入排序
void directlyInsertSort2(int D[], int n);//直接插入排序改進

void printArray(int D[], int n);//輸出陣列
void main() {
	int D[maxSize] = {12,15,48,46,16,78,57,88,65,48};//構造一個一維陣列
	int E[maxSize] = { 12,15,48,46,16,78,57,88,65,48 };
	directlyInsertSort1(D, maxSize);//直接插入排序陣列
	cout << "直接插入排序後,結果為:" << endl;
	printArray(D, maxSize);//輸出陣列

	directlyInsertSort2(E, maxSize);//直接插入排序,由於上面執行完D陣列已經有序,這我們構造一個與D陣列完全相同的E陣列進行測試。
	cout << "改進的直接插入排序後,結果為:"<<endl;
	printArray(E, maxSize);
}
void directlyInsertSort1(int D[], int n) {//直接插入排序,D為要排序的陣列,n為D中關鍵字的個數
	int i, j;
	int temp;
	for (i = 1; i < n; ++i) {//初始時,a[0]自成1個有序區,無序區為a[1..n-1]。令i=1
		temp = D[i];   //將待排關鍵字存入temp中
		j = i - 1;     //j為D[i]前一個關鍵字的下標

		//這個迴圈用於從待排關鍵字的前一個關鍵字開始比較,如果大於待排關鍵字就後移一位
		while (j >= 0 && temp < D[j]) {
			D[j + 1] = D[j];
			--j;
		}
		D[j + 1] = temp;//找到插入位置,將temp插入。j最後-1,所以這裡加1。

	}
}
/*
改進的思想是:在迴圈剛開始時加上一句判斷,若D[i]>=D[i-1]說明D[0...i]本身就是有序的,無需調整,否則按就第一種方法調整。顯而易見,某些情況下第二種方法比第一種方法效率要高
*/
void directlyInsertSort2(int D[], int n) {
	int i, j;
	int temp;
	for (i = 1; i < n; ++i) {    //初始時,a[0]自成1個有序區,無序區為a[1..n-1]。令i=1
		if (D[i] < D[i - 1]) {//判斷是否調整
			temp = D[i];   //將待排關鍵字存入temp中
			j = i - 1;     //j為D[i]前一個關鍵字的下標

			 //這個迴圈用於從待排關鍵字的前一個關鍵字開始比較,如果大於待排關鍵字就後移一位
			while (j >= 0 && temp < D[j]) {
				D[j + 1] = D[j];
				--j;
			}
			D[j + 1] = temp;//找到插入位置,將temp插入。j最後-1,所以這裡加1。
		}
	}
}

void printArray(int D[], int n) {
	for (int i = 0; i < n; ++i)  //輸出排序後的關鍵字
		cout << D[i] << " ";
	cout << endl;
}
以上如有錯誤,請指出,大家共同學習進步

相關文章