普通插入排序與改良插入排序(希爾排序)

普通插入排序

手工過程:

例:10 8 6 9 7 6 5 9 2 1
(10) 8 6 9 7 6 5 9 2 1 括號中爲已經排好序的數值
8 10)6 9 7 6 5 9 2 1
6 8 10)9 7 6 5 9 2 1
(6 8 9 10)7 6 5 9 2 1
(6 7 8 9 10)6 5 9 2 1
(6 6 7 8 9 10)5 9 2 1
5 6 6 7 8 9 10)9 2 1
(5 6 6 7 8 9 9 10)2 1
(2 5 6 6 7 8 9 9 10)1
1 2 5 6 6 7 8 9 9 10)排序完成

void directInsertSort(int* arr, int count) {
	int i;//待排數據下標
	int j;//從0開始,遍歷已排數據下標
	int tmp;//用作交換數據的臨時變量

	for(i = 1; i < count; i++) {
		for(j = 0; j < i && arr[i] >= arr[j]; j++){
			;
		}//經過此循環,j停留的位置所在的數據大於當前待排數據,或j=i;
		tmp = arr[i];
		for(; j < i; i--) {
			arr[i] = arr[i - 1];
		}
		arr[j] = tmp;
	}
}

實例驗證:

void show(int* arr, int count) {
	int i;

	for(i = 0; i < count; i++) {
		printf("%d ", arr[i]);
	}
	printf("\n");
}


void main() {
	int arr[10] = {10, 8, 6, 9, 7, 6, 5, 9, 2, 1,};

	printf("排序前:");
	show(arr, 10);
	directInsertSort(arr, 10);
	printf("排序後:");
	show(arr, 10);
}

運行結果
運行結果

插入排序改良版——希爾排序

手工過程

例:
3 9 8 6 4 7 2 5 4 6 8 4 5 4 9 8 2 4 4 7 共20個數據
第一輪:以 20/2 爲步長,將下標爲:
0 與0+20/2看爲一組,進行直接插入排序;
1與1+20/2看爲一組,進行直接插入排序;
2與2+20/2看爲一組,進行直接插入排序;

9與9+20/2看爲一組,進行直接插入排序;
第二輪:以 20/2/2 = 5 爲步長,將下標爲:
0 、5、10、15看爲一組,進行直接插入排序;
1、6、11、16看爲一組,進行直接插入排序;
2、7、12、17看爲一組,進行直接插入排序;

4、9、14、19看爲一組,進行直接插入排序;

最後,以1爲步長,進行直接插入排序。

//指定起始下標、步長,進行插入排序
void insertSort(int *arr, int count, int startIndex, int step) {
	int i;
	int j;
	int tmp;

	for(i = startIndex + step; i < count; i += step) {
		for(j = startIndex; j < i && arr[i] >= arr[j]; j += step) {
		}
		tmp = arr[i];
		for(; i > j; i -= step) {
			arr[i] = arr[i - step];
		}
		arr[j] = tmp;
	}
}
void ShellSort(int *arr, int count) {
	int step = count;
	int start;

	for(step >>= 1; step > 0; step >>= 1) {
		for(start = 0; start < step; start++) {
			insertSort(arr, count, start, step);
		}
	}
}

實例驗證:

void main() {
	int arr[10] = {10, 5, 6, 5, 7, 6, 5, 9, 2, 1,};

	printf("排序前:");
	show(arr, 10);
	ShellSort(arr, 10);
	printf("排序後:");
	show(arr, 10);
}

運行結果
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章