内排序小结

參考链接http://blog.csdn.net/hguisu/article/details/7776068

概述

排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序。而外部排序是因排序的数据非常大,一次不能容纳所有的排序记录,在排序过程中须要訪问外存。


我们这里说说八大排序就是内部排序。



当n较大,则应採用时间复杂度为O(nlog2n)的排序方法:高速排序、堆排序或归并排序序。
高速排序:是眼下基于比較的内部排序中被觉得是最好的方法,当待排序的keyword是随机分布时。高速排序的平均时间最短;

1.冒泡排序

冒泡排序是一种交换排序,基本思想是:两两比較相邻记录的keyword,假设反序则交换,直到没有反序的记录为止

代码演示样例:
#include <iostream>
using namespace std;

void BubbleSort(int array[],int length){
	//排序次数比数组长度小1
	bool flag=true; 
	for(int i=0;i<length-1&&flag;i++){ //若flag为false,则退出循环
		flag=false; //初始为fasle
		for(int j=0;j<length-i-1;j++){
			if(array[j]>array[j+1]){
				int temp=array[j];
				array[j]=array[j+1];
				array[j+1]=temp;
				flag=true; //假设发生了数据交换,则flag为true
			}
		}
	}
}
int main(){
	int array[]={12,4,16,15,17,1,19,6};
	BubbleSort(array,8);
	for(int i=0;i<8;i++){
		cout<<array[i]<<" ";
	}
	cout<<endl;
	return 0;
}

时间复杂度分析:最好时间复杂度为O(n),最坏时间复杂度为O(n^2),平均时间复杂度为O(n^2)
空间复杂度分析:O(1)
稳定性分析:稳定的排序算法

2.简单选择排序


基本思想:每一趟排序选择未排序记录keyword的最小值,然后和未排序记录的第一个位置交换数据
演示样例代码:
#include <iostream>
using namespace std;
void SimpleSelectSort(int array[],int length){
	
	int min;//最小元素下标
	//排序次数比数组长度小1
	for(int i=0;i<length-1;i++){ 
		min=i;//将当前下标定义为最小值下标
		//一趟排序找到当前未排序记录keyword的最小值
		for(int j=i+1;j<length;j++){
			if(array[min]>array[j])
				min=j;
		}
		if(min!=i){ //最小值不是当前i下标值,则交换
			int temp=array[i];
			array[i]=array[min];
			array[min]=temp;
		}
	}
}
int main(){
	int array[]={12,4,16,15,17,5,19,2};
	SimpleSelectSort(array,8); 
for(int i=0;i<8;i++){
cout<<array[i]<<" ";}
cout<<endl;
return 0;}




时间复杂度分析: 因为比較的次数都是O(n^2)次,所以最好、最坏、平均时间复杂度都是O(n^2)
空间复杂度分析:O(1)
稳定性分析:不稳定的排序算法
分析:稳定的排序方法仅仅能是相邻的keyword比較。简单选择排序每次选择未排序的最小(大)的。
样例:{ 2, 2, 1}  第一次选的时候变成 { 1, 2, 2 }, 两个2的次序就变了,所以不稳定。
简单选择排序性能上要优于冒泡排序

3.直接插入排序

基本思想:将一个记录插入到一个已经排好序的有序表中,得到一个新的、记录数加1的有序表
演示样例代码:
#include <iostream>
using namespace std;
void DirectInsertSort(int array[],int length){
	//排序次数比数组长度小1
	for(int i=1;i<length;i++){ 
		if(array[i]<array[i-1]){ //为true才须要真正排序
			int temp=array[i]; //设置哨兵
			int j=i-1;
			//寻找插入位置。当前j值的后一个位置是插入位置
			while(j>=0&&temp<array[j]){ 
				array[j+1]=array[j];
				j--;
			}
			array[j+1]=temp;
		}
	}
}
int main(){
	int array[]={12,4,16,15,17,5,19,2};
	DirectInsertSort(array,8);
	for(int i=0;i<8;i++){
		cout<<array[i]<<" ";
	}
	cout<<endl;
	return 0;
}
时间复杂度分析:最好时间复杂度O(n)、最坏和平均时间复杂度均为O(n^2)
空间复杂度分析:O(1)
稳定性分析:稳定的排序算法
相同的时间复杂度条件下,直接插入排序比冒泡排序和简单选择排序性能要好一些

4.希尔排序

希尔排序又称“缩小增量排序”,也是一种插入类型的排序方法。

直接插入排序,当待排序列基本有序,直接插入排序的效率就能够大大提高。当n值非常小时。效率也比較高。希尔排序正是从这两点分析出发对直接插入排序改进得到的一种插入排序方法。

基本思想:先将整个待排记录序列切割成为若干个子序列分别进行直接插入排序,待整个序列中的记录“基本有序”时,再对全体记录进行一次直接插入排序。
演示样例代码:參考数据结构第272页
时间复杂度分析:平均时间复杂度为O(nlogn)~O(n^2)。最好时间复杂度为O(n^1.3),最坏时间复杂度为O(n^2)
空间复杂度分析:O(1)
稳定性分析:因为keyword交换移动是跳跃式的,所以是不稳定的排序算法。


各种排序的稳定性,时间复杂度和空间复杂度总结


注:高速排序的空间复杂度,最好是O(logN),最坏是O(n)。


原文地址:https://www.cnblogs.com/yutingliuyl/p/6796953.html