排序算法(一):插入排序(直接插排、希爾排序)

插入排序

  • 基本思想:

插入排序將序列分爲已經有序暫時無序兩部分,遍歷暫時無序的部分,將該部分第一個元素插入到已經有序部分的合適位置,遍歷完畢則完成了排序,得到一個新的有序序列。

  • 排序分類:

插入排序分爲直接插入排序希爾排序

一:直接插入排序

  • 排序過程:

在這裏插入圖片描述

  • 代碼實現:

在實際實現時爲了簡化操作,將未有序部分與有序部分的最後一個元素比較,如果不滿足排序要求則交換,繼續與倒數第二個元素比較以此類推,直到滿足排序順序爲止。

C++實現:

#include <iostream>
#include <vector>
using namespace std;

void InsertSort(vector<int>& array){
	// 直接插入排序
	int sz = array.size();
	for (int disorder = 1; disorder < sz; disorder++){
		int goal = disorder; 
		// 將未排序部分的第一個元素和有序部分的最後一個元素比較
		while (goal > 0 && array[goal] < array[goal - 1]){
			swap(array[goal], array[goal - 1]);
			goal--;
		}
	}
}

int main(){
	vector<int> array = { 5, 2, 4, 6, 1, 3};
	InsertSort(array);
	for (const auto& e : array){
		cout << e << " ";
	}
	cout << endl;
}

輸出結果:1 2 3 4 5 6

C實現:

#include<stdio.h>

void Swap(int* num1, int* num2){
	int temp = *num1;
	*num1 = *num2;
	*num2 = temp;
}

void Print(int* array, int sz){
	for (int cur = 0; cur < sz; cur++){
		printf("%d ", array[cur]);
	}
	printf("\n");
}

// 插入排序傳參:數組+數組大小
void InsertSort(int* array, int sz){
	// 直接插入排序
	for (int disorder = 1; disorder < sz; disorder++){
		int goal = disorder;
		while (goal > 0 && array[goal] < array[goal-1]){
			Swap(&array[goal], &array[goal-1]);
			goal--;
		}
	}
}

int main(){
	int array[] = { 5, 2, 4, 6, 1, 3 };
	int sz = sizeof(array) / sizeof(array[0]);
	InsertSort(array, sz);
	Print(array, sz);

	return 0;
}

輸出結果:1 2 3 4 5 6
  • 特性總結:

1.時間複雜度:O(N2)
2.空間複雜度:O(1)
3.元素集合越接近有序,直接插入排序算法的時間效率越高
4.直接插入排序是一種穩定排序後2個值相等的元素的相對位置保持不變)的排序算法

二:希爾排序

希爾排序是直接插入排序的升級版本,因爲元素集合越接近有序,直接插入排序算法的時間效率越高,希爾排序旨在使用插入排序使每次排序的序列要麼足夠短,要麼就幾乎已經有序,來極大程度節省時間,提高效率。

  • 排序過程:

在這裏插入圖片描述

  • 代碼實現:

將序列按照下標的一定增量分成若干組,對每組使用直接插入排序算法進行排序,隨着增量逐漸減少,每組元素越來越多,當增量減爲1時,整個序列被分爲一組,此時整個序列接近有序,直接插入排序算法的時間效率大大提高。

C++實現:

#include<iostream>
#include<vector>
using namespace std;

void Shellsort(vector<int>& array){
	// 設置增量並逐步縮小增量
	int sz = array.size();
	for (int gap = sz / 2; gap > 0; gap /= 2){
		// 從第gap個元素,逐個對其所在組進行直接插入排序操作
		for (int disorder = gap; disorder < sz; disorder++){
			int goal = disorder;
			while (goal - gap >= 0 && array[goal] < array[goal - gap]){
				swap(array[goal], array[goal - gap]);
				goal-=gap;
			}
		}
	}
}

int main(){
	vector<int> array = { 9, 1, 2, 5, 7, 4, 8, 6, 3, 5 };
	Shellsort(array);
	for (const auto& e : array){
		cout << e << " ";
	}
	cout << endl;
}

輸出結果:1 2 3 4 5 5 6 7 8 9

C實現:

#include<stdio.h>

void Swap(int* num1, int* num2){
	int temp = *num1;
	*num1 = *num2;
	*num2 = temp;
}

void Print(int* array, int sz){
	for (int cur = 0; cur < sz; cur++){
		printf("%d ", array[cur]);
	}
	printf("\n");
}

void Shellsort(int* array, int sz){
	// 設置增量並遞減增量
	for (int gap = sz / 2; gap > 0; gap /= 2){
		// 對每組進行插入排序
		for (int disorder = gap; disorder < sz; disorder++){
			int goal = disorder;
			while (goal-gap >= 0 && array[goal] < array[goal - gap]){
				Swap(&array[goal], &array[goal - gap]);
				goal -= gap;
			}
		}
	}
}

int main(){
	int array[] = { 9, 1, 2, 5, 7, 4, 8, 6, 3, 5 };
	int sz = sizeof(array) / sizeof(array[0]);
	Shellsort(array, sz);
	Print(array, sz);
}

輸出結果:1 2 3 4 5 5 6 7 8 9
  • 特性總結:

1.時間複雜度:O(N1.3—N2
2.空間複雜度:O(1)
3.希爾排序是一種不穩定的排序算法

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