排序

排序算法

排序的基本概念:
排序:给定一组记录的集合{r1, r2, ……, rn},其相应的关键码分别为{k1, k2, ……, kn},排序是将这些记录排列成顺序为{rs1, rs2, ……, rsn}的一个序列,使得相应的关键码满足ks1≤ks2≤……≤ksn(称为升序)或ks1≥ks2≥……≥ksn(称为降序)。
正序:待排序序列中的记录已按关键码排好序。
逆序(反序):待排序序列中记录的排列顺序与排好序的顺序正好相反。
趟:在排序过程中,将待排序的记录序列扫描一遍称为一趟。通常,一次排序过程需要进行多趟扫描才能完成

排序算法的稳定性:
假定在待排序的记录集中,存在多个具有相同键值的记录,若经过排序,这些记录的相对次序仍然保持不变,即在原序列中,ki=kj且ri在rj之前,而在排序后的序列中,ri仍在rj之前,则称这种排序算法是稳定的;否则称为不稳定的。

对于不稳定的排序算法,只要举出一个实例,即可说明它的不稳定性;而对于稳定的排序算法,必须对算法进行分析从而证明稳定的特性。

排序算法是否为稳定的是由具体算法决定的:
不稳定的算法在某种条件下可以变为稳定的算法,
而稳定的算法在某种条件下也可以变为不稳定的算法。

稳定性比较:
所有排序方法可分为两类,
(1)一类是稳定的,包括直接插入排序、起泡排序、和归并排序,基数桶式排序;
(2)另一类是不稳定的,包括直接选择排序、希尔排序、快速排序和堆排序。

排序的分类:
排序的分类——根据排序数据在内存中还是在外存中:
1.内排序:在排序的整个过程中,待排序的所有记录全部被放置在内存中
2. 外排序:由于待排序的记录个数太多,不能同时放置在内存,而需要将一部分记录放置在内存,另一部分记录放置在外存上,整个排序过程需要在内外存之间多次交换数据才能得到排序的结果。

排序的分类——根据排序过程中所进行的基本操作分类:

  1. 基于比较:基本操作——关键码的比较和记录的移动,其最差时间下限已经被证明为O(nlog2n)。
  2. 不基于比较:根据关键码的分布特征。比如,桶式排序,基数排序(多关键字排序)
    基于比较的内排序:
  3. 插入排序
  4. 交换排序
  5. 选择排序
  6. 归并排序
    不基于比较的内排序:
  7. 分配排序
    2.桶式排序
    3.基数排序

算法简单性比较:
从算法简单性看,
(1)一类是简单算法,包括直接插入排序、直接选择排序和起泡排序,
(2)另一类是改进后的算法,包括希尔排序、堆排序、快速排序、归并排序和基数排序,这些算法相对比较复杂。

直接插入排序

void  insertSort (int  r[ ], int n){	
   for (i=2; i<=n; i++)   { 
       r[0]=r[i]; j=i-1;
       while (r[0]<r[j])       {  
           r[j+1]=r[j];	
	 j=j-1;	
        }
       r[j+1]=r[0];	
    }
}

希尔排序

void Shellsort(int r[],int n){
  for (d=n/2; d>=1; d=d/2){
     for (i=d+1; i<=n; i++) {
	     r[0]=r[i];           
	     j=i-d;                
	     while (j>0 && r[0]<r[j])
	     { 
          		r[j+d]=r[j]; 
	          j=j-d;          
	      }
	      r[j+d]=r[0]; 
	}
  }
}

起泡排序

void BubbleSort(int r[ ], int n)
{	
    exchange=n; 	
    while (exchange) 
    {
        bound=exchange; 
        exchange=0;  
        for (j=1; j<bound; j++)
            if (r[j]>r[j+1]) {
                r[j]←→r[j+1];
	      exchange=j; 
            }
     }
 }

void BubbleSort(int r[ ], int n)
{	
    change=true; bound=n;
    while (change) 
    {
        change=false;
          
        for (j=1; j<bound; j++)
            if (r[j]>r[j+1]) {
                r[j]←→r[j+1];
	      bound=j;
	      change=true
            }
     }
 }

快速排序

int Partition(int r[ ], int first, int end)
{	
    i=first; j=end;         //初始化
    r[0]=r[i];
     while (i<j)	
    {  
      while (i<j && r[0]<= r[j]) j--;  //右侧扫描
       if (i<j) { 
          r[i]=r[j];   i++;  //将较小记录交换到前面
       }
       while (i<j && r[i]<= r[0]) i++;  //左侧扫描
       if (i<j) {
          r[j]=r[i];   j--;  //将较大记录交换到后面
       }
    }
    r[i]=r[0];
    retutn i;    //i为轴值记录的最终位置
}

选择排序

void  selectSort ( int  r[ ], int n)
{   
    for ( i=1; i<n; i++) 
    {  
        index=i; 		
        for (j=i+1; j<=n; j++) 
           if  (r[j]<r[index])  index=j;
        if (index!=i)   r[i]<==>r[index]; 	 
    }
} 

堆调整

void sift ( int r[ ], int k, int m )
{//要筛选结点的编号为k,堆中最后一个结点的编号为m 
    i=k;  j=2*i;  temp=r[i];  //将筛选记录暂存
    while (j<=m )           //筛选还没有进行到叶子
    {
        if (j<m && r[j]<r[j+1]) j++;  //左右孩子中取较大者
        if (temp>r[j]) break; 
        else {
             r[i]=r[j];   i=j;   j=2*i;
        }
     }
     r[i]=temp;   //将筛选记录移到正确位置
}

堆排序

void  HeapSort ( int  r[], int n)
{
    for (i=n/2; i>=1; i--)      //初建堆
       sift(r, i, n) ;     
    for (i=1; i<n; i++ )
    {
       r[1]←→r[n-i+1];        //移走堆顶
       sift(r, 1, n-i);               //重建堆
    }
}

在这里插入图片描述
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值