数据结构复习小结4(排序)

插入排序

基本思想:每次将一个待排序的记录,按其关键字大小插入到前面已经排好序的子序列中,直到插入完成。

----直接插入排序

在有序子列里找到第i个的位置k,将L[k.....i-1]中元素向后移动一个位置

void InsertSort(ElemType A[],int n){

     int i,j;
     for(i=2;i<=n;i++){

        if(A[i].key<A[i-1].key){
            A[0]=A[i];
            for(j=i-1;A[0].key<A[j].key;--j){
                A[j+1]=A[j];
            }
            A[j+1]=A[0];
        }
     }

}

空间复杂度O(1);时间复杂度O(n^2);适合于顺序存储和链式存储的线性表。

------折半插入排序

   先折半查找出元素的待插入位置,再统一移动插入

顺序存储的线性表的有序子表可以用折半查找来实现;比较次数与元素个数有关,时间复杂度O(n^2)

------希尔排序

 将待排序表分成若干个子表,分别进行直接插入排序,再对全表进行一次直接插入排序。

void ShellSort(ElemType A[],int n){
    for(dk=n/2;dk>=1;dk=dk/2)
        for(i=dk+1;i<=n;++i){

            if(A[i].key<A[i-dk].key){
                A[0]=A[i];
                for(j=i-dk;j>0&&A[0]<A[j];k-=dk){
                    A[j+dk]=A[j];
                }
                A[j+dk]=A[0];
            }
        }
}

时间复杂度O(n^2),不稳定;适用于顺序存储

交换排序

-----冒泡排序

基本思想:待排序表长n,从后往前两两比较相邻元素的值,若为逆序,交换。

void BubbleSort(ElemType A[],int n){
    for(i=0;i<n-1;i++){
        flag=false;
        for(j=n-1;j>i;j--){
            if(A[j-1].A[j]){
                swap(A[j-1],A[j]);
                flag=true;
            }
        }
        if(flag==false)
            return;
    }    
}

时间复杂:最好O(n),最坏O(n^2)

------快速排序

 基本思想:基于分治法,任取一个元素作为基准pivot,通过一趟排序划分两边部分,一边小于pivot,一遍大于等于pivot。pivot放在最终位置,然后分别递归的对俩子表重复上述排序。

int partion(int data[],int low,int high)
{  
   int t=data[low];
   while(low<high)
   {
    while(low<high&&data[high]>=t)
    {
      high--;
    }
    data[low]=data[high];
    while(low<high&&data[low]<=t)
    {
      low++;
    }
    data[high]=data[low];
   }
   data[low]=t;
   return low;
}
 
 
void quicksort(int data[],int low,int high)
{
   int part;
  if(low<high)
  {
	 
	  part=partion(data,low,high);
	 // printf("%d\n",part);
	  quicksort(data,low,part-1);
	  quicksort(data,part+1,high);
  }
}

--------------------- 
作者:xulu_258 
来源:CSDN 
原文:https://blog.csdn.net/xulu_258/article/details/51319047 
版权声明:本文为博主原创文章,转载请附上博文链接!

空间复杂度:最坏情况O(n^2)

不稳定算法

选择排序

基本思想:每一趟i在后面n-i+1个待排序元素中选取关键字最小的元素,作为有序子序的第i个元素,直到第n-1趟完成。

------简单选择排序

时间效率:n(n-1)/2次,O(n^2);不稳定

比较次数与初始状态无关

------堆排序

树形选择排序,特点:将L[n] 看成是一颗完全二叉树的顺序存储结构,利用完全二叉树中双亲结点和孩子结点之间的内在关系,在当前无序区选择最大(小)关键字;

小根堆:L(i)<=L(2i) 且L(i)<=L(2i+1)

大根堆:L(i)>=L(2i+1) (1<=i<=n/2);最大元素存放在根结点中

建堆时间:O(n)   时间复杂度:O(nlog2 n)  不稳定

归并排序和基数排序

--------归并排序

基本思想:归并的含义将两个或两个以上的有序表组合成一个新的有序表;调用n/2h次算法 ;整个归并需进行log2 n趟

空间复杂度:O(n)  时间复杂度O(nlog2 n);稳定排序;排序次数与初始状态无关

--------基数排序

基本思想:基于关键字各位的大小进行排序

性能:空间O(r) r个队列;  时间O(d(n+r)) 与初始状态无关;稳定

内部排序算法得比较及应用

------时空复杂度

平均情况下时间复杂度O(n^2):简单选择排序,直接插入排序,冒泡排序

空间复杂度:简单选择排序,插入排序冒泡排序,希尔排序,堆排序借助常数个辅助空间

        快速排序使用小的辅助栈O(log2 n);二路归并O(n)

稳定:插入排序,冒泡排序,归并排序,基数排序

小结:

  1. 若n较小,可以采用直接插入或简单选择排序;直接插入排序的移动操作较多,记录信息本身量大时,用简单排序
  2. 若文件的初始状态已按关键字基本有序,选择直接插入或冒泡排序
  3. 若n较大,采用时间复杂度O(nlog2 n)快速排序,堆排序,递归排序;快速排序被认为目前内部排序中最好的方法;堆排序所需的辅助空间少于快速排序,这俩是不稳定排序;
  4. 若n很大,并记录的关键字位数较少且可分解采用基数排序
  5. 记录本身信息量较大,避免耗费大量时间移动记录,可用链表作为存储结构

外部排序

归并排序

归并趟数S=logm r(向上取整) 

归并路数m个元素中关键字最小比较m-1次,每趟归并n个元素需要(n-1)*(m-1)

S趟归并比较总数:S(n-1)*(m-1)

----置换-选择算法

初始待排文件F1,初始归并段文件FO,内存工作区为WA,内存工作区可容纳W个记录;

步骤:

  1. 从待排文件F1输入W个记录到工作区WA
  2. 从内存工作区WA中选出关键字最小的记录MIN
  3. 将MIN记录输出到FO中
  4. 若F1未读完,则从F1输入下一个记录到WA
  5. 从WA中所有关键字比MIN大的记录中选出最小的,作为新的MIN
  6. 重复3-5

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值