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

插入排序

  • 基本思想:

插入排序将序列分为已经有序暂时无序两部分,遍历暂时无序的部分,将该部分第一个元素插入到已经有序部分的合适位置,遍历完毕则完成了排序,得到一个新的有序序列。

  • 排序分类:

插入排序分为直接插入排序希尔排序

一:直接插入排序

  • 排序过程:

在这里插入图片描述

  • 代码实现:

在实际实现时为了简化操作,将未有序部分与有序部分的最后一个元素比较,如果不满足排序要求则交换,继续与倒数第二个元素比较以此类推,直到满足排序顺序为止。

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.希尔排序是一种不稳定的排序算法

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