O(n*n)的排序算法

几种基础的排序算法

学习了慕课网liuyubobobo老师的课程[https://coding.imooc.com/class/71.html],现把课程笔记整理如下,希望对各位能有所帮助。

O(n*n)的排序算法

1、选择排序

[算法思想]

首先找到数组中最小的元素,然后与i交换位置,随后重新将minIndex赋值为i,继续寻找第二小的元素,以此类推。
在这里插入图片描述

[代码实现]
template<typename T>
void selectionSort(T arr[], int n){
	for(int i=0;i<n;++i){
		int minIndex = i;
		for(int j=i+1;j<n;++j){
			if(arr[j]<arr[minIndex])
				minIndex = j;
		swap(arr[i],arr[minIndex]);
	}
}

2、 插入排序

[算法思想]

当i=0时,只有一个元素不需要排序。所以i=1开始循环,通过当前元素与之前元素的大小关系进行排序,若当前元素小于前一元素,则交换位置,以此类推。
在这里插入图片描述

[代码实现]
template<typename T>
void insertionSort1(T arr[], int n){
	for(int i=1;i<n;i++){
		for(int j=i;j>0;j--){
			if(arr[j]<arr[j-1])
				swap(arr[i],arr[j-1]);
			else
				break;
		}
	}
}

插入排序与选择排序相比,插入排序可以提前终止第二层循环,所以当数组内近乎有序时,插入排序的性能会更好

[算法改进]

代码中swap操作,比较耗时,所以将swap操作改为简单的赋值操作

template<typename T>
void insertionSort2(T arr[], int n){
	for(int i=1;i<n;i++){
		T temp = arr[i];
		int j;//j保存元素temp应该插入的位置
		for(j=i;j>0 && temp<arr[j-1];j--){
				arr[j] = arr[j-1];
		}
		arr[j] = temp;
	}				
}

3、冒泡排序

[算法思想]

比较两个相邻的元素,经过一次循环将最大的元素放在数组末尾,然后进行第二次循环,将第二大的元素放在数组的倒数第二位,以此类推。
在这里插入图片描述
(图片转自:https://www.cnblogs.com/bigdata-stone/p/10464243.html)

[代码实现]
template<typename T>
void bubbleSort1(T arr[], int n){
	for(int i = 0;i <n ;i++){
		for(int j = 0;j < n - i - 1;j++){
			if(arr[j] > arr[j+1])
				swap(arr[j],arr[j+1]);
		}
	}
}
[算法改进]

当数组近乎有序是,会增加许多次无效比较,故加入flag,表示是否有交换发生,若没有交换发生,则可进行下一轮循环

template<typename T>
void bubbleSort2(T arr[], int n){
	bool flag = false;
	for(int i = 0;i <n && flag ;i++){
		flag = false;
		for(int j = 0;j < n - i - 1;j++){
			if(arr[j] > arr[j+1]){
				swap(arr[j],arr[j+1]);
				flag = true;
			}
		}
	}
}

希尔排序

[算法思想]

先将整个待排序元素序列分割成若干子序列(由相隔某个“增量”的元素组成)分别进行直接插入排序,然后依次所见增量再进行排序,待整个序列中的元素基本有序(增量足够小)时再对全体元素进行一次直接插入排序。因为直接插入排序再元素基本有序的情况下效率是很高的,因此希尔排序在时间效率上比较高。
在这里插入图片描述

[代码实现]
template<typename T>
void shellSort(T arr[], int n) {
	int i, j, gap;
	for (gap = n / 2; gap > 0; gap /= 2) {
		for (i = gap; i < n; i++) {
			T temp = arr[i];
			for (j = i; j >= gap && temp < arr[j - gap]; j -= gap) {
				arr[j] = arr[j - gap];
			}
			arr[j] = temp;
		}
	}
}

希尔排序的复杂度和增量序列是相关的

{1,2,4,8,…}这种序列并不是很好的增量序列,使用这个增量序列的时间复杂度(最坏情形)是O(n^2)

Hibbard提出了另一个增量序列{1,3,7,…,2^k-1},这种序列的时间复杂度(最坏情形)为O(n ^1.5)

Sedgewick提出了几种增量序列,其最坏情形运行时间为O(n^1.3),其中最好的一个序列是{1,5,19,41,109,…}
(转自:https://blog.csdn.net/qq_39207948/article/details/80006224)

想说的话

最后想说一句,因为自己算是一个算法小白,也是刚接触算法,学完了老师的课程以后,觉得前面学的很多知识又忘记了,所以想通过写csdn的方式,既能整理笔记又可以巩固记忆。笔记中可能有一些错误的地方,如果大佬发现希望可以指正。还有也希望大佬们可以给我介绍介绍经验啥的,因为刚开始学习算法,真的很难受,感谢感谢。

下期整理O(nlogn)的排序算法,大家加油~

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值