小言_互联网的博客

数据结构与算法9-排序1

382人阅读  评论(0)

简单排序

概述

void X_Sort(ElementType A[], int N)
//X表示排序方法的名字  A[]是输入的数组  N是元素个数
  • 简单起见,默认从小到大的整数排序
  • N是正整数,排序数的个数
  • 只讨论基于比较的排序
  • 只讨论内部排序,所有排序是在内存里一次性完成的
  • 稳定性:任意两个相等数据排序前后相对位置不变
  • 没有一种排序是任何情况下都表现好的

冒泡排序

从上到下,相邻两个元素根据大小关系交换位置,第一次排序后最大的数会落到最底层,然后对于n-1个数继续重复上述过程

void Bubble_Sort(ElementType A[],int N)
{
	for ( R=N-1; P>=0; P--){
		flag = 0;
		for(i=0; i<P; i++){
			if(A[i]>A[i+1]){
				Swap(A[i],A[i+1]);
				flag = 1;
			}
		}
		if ( flag == 0 ) break;
	}
}
  • 最好情况O(N)
  • 最坏情况O(N^2)
  • 稳定

插入排序

void Insertion_Sort(ElementType A[],int N)
{
	for(p=1;p<N;p++){
		Tmp=A[p];
		for(i=p;i>0 && A[i-1]>Tmp;i--)
			A[i] = A[i-1];
		A[i] = Tmp;
		}
}
  • 最好情况O(n)
  • 最坏情况O(N^2)
  • 稳定性

时间复杂度下界

  • 逆序对
  • 交换两个相邻元素正好消去一个逆序对
  • 插入排序 T(N,I)=O(N+I) I表示逆序对;如果序列基本有序,则插入排序简单且高效
  • 定理:任意N个不同元素组成的序列平均有N(N-1)/4个逆序对
  • 定理:任何以交换相邻两元素来排序的算法,其平均时间复杂度为Ω(N^2)
  • 这意味着想要提高效率,必须每次消去不止一个逆序对

希尔排序

思想

  • 5-间隔排序
  • 然后在5-间隔排序的基础上进行3-间隔排序
  • 最后做插入排序
  • 定义一个增量序列,对每个增量进行增量-间隔排序
  • 三间隔有序序列还保持了五间隔的性质

希尔增量序列

不停的除二,向下取整

void Shell_sort(ElementType A[], int N)
{
	for ( D-N/2; D>0; D/=2){  //希尔增量序列
		for(P=D; P<N; P++{  //插入排序
			Tmp = A[P];
			for(i=p;i>=D && A[i-D]>Tmp;i-=D)
				A[i]=A[i-D];
			A[i] = Tmp;
		}
	}
}

seita(N^2)
由于增量元素不互质,则小增量可能根本不起任何作用

更多增量序列

  • Hibbard增量序列 最坏情况seita(N^3/2)
  • Sedgewick增量序列

堆排序

选择排序

扫描数组,将最小元换到最后的位置
最坏情况下换n-1次,但是扫描需要的时间很久,时间复杂度为seita(N^2)
接下来的问题就在于如何找到最小元

算法1

实际上堆排序就是对选择排序的一个改进,在如何找到最小元这个位置改变

void Heap_Sort(ElementType A[],int N)
{
	BuildHeap(A);
	for ( i=0;i<N;i++ )
		TmpA[i] = DeleteMin(A);
	for ( i=0;i<N;i++)
		A[i] = TmpA[i];
}

时间复杂度为NlogN,但是需要额外的N的空间

算法2

建立一个最大堆,然后把根节点换到当前最后的位置,最后位置往前移动1,循环上述过程
平均比较次数 2NlogN-O(NloglogN)
实际上其实不如Sedgewick增量序列的希尔序列

归并排序

有序子列归并

时间复杂度为O(N)

递归算法

  • 分而治之 O(NlogN)
  • 稳定算法

非递归算法

在外排序非常有用


转载:https://blog.csdn.net/five_zzxxdd/article/details/105917055
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场