第九章 内部排序

插入排序 (Insert Sorting)

本章涉及的待排记录的数据类型定义为:
#define  MAXSIZE    20
Typedef int KeyType
Typedef struct
     {KeyType  key;              //关键字项
       InfoType  otherinfo;   //其它数据项
      }RcdType;
Typedef  struct
      {RcdType r[MAXSIZE+1]   //r[0]闲置或用作哨兵
       int  length;
      }Sqlist;

1.直接插入排序 (Insert Sort)
直接插入排序的基本思想是:当插入第i (i  1) 个对象时,前面的V[1], …, v[i-1]已经排好序。这时,用v[i]的关键字与v[i-1], v[i-2], …的关键字顺序进行比较,找到插入位置即将v[i]插入,原来位置上之后的所有对象依次向后顺移。

void InsertSort(SqList &L)
//生成按关键字非递减有序序列
   {  for (int i=2;i<=L.length;++i)
	if (LT(L.r[i].key,L.r[i-1].key))
           { L.r[0]=L.r[i];  // L.r[0]为监视哨
	 for (int j=i-1; LT(L.r[0].key,L.r[j].key); --j)
		L.r[j+1]=L.r[j]; 						    L.r[j+1]=L.r[0];
	 }
    }

2. 折半插入排序 (Binary Insertsort)
折半插入排序基本思想是:设在顺序表中有一 个对象序列 V[1], …, v[n-1]。其中,V[1], …, v[i-1] 是已经排好序的对象。在插入 v[i] 时,利用折半搜索法寻找 v[i] 的插入位置。

void BInsertSort(SqList &L)
   { int low,high,mid;
     for (int i=2;i<=L.length;++i)
       {  L.r[0]=L.r[i];
	 low = 1; high=i-1;
	 while (low <= high)
              {  mid = (low+high)/2;
	       if (LT(L.r[0].key,L.r[mid].key))   high=mid-1;
           	else low=mid+1; }
 	for (int j=i-1; j>=high+1;--j) L.r[j+1]=L.r[j];
            	L.r[high+1]=L.r[0];
	}
}说明:low 或者 high+1为插入点         稳定排序

交换排序 ( Exchange Sort )

1.起泡排序 (Bubble Sort)
起泡排序的基本方法是:设待排序对象序列中的对象个数为 n。最多作 n-1 趟排序。在第 i 趟中顺次两两比较r[j-1].Key和r[j].Key,j = i, i+1, , n-i-1。如果发生逆序,则交换r[j-1]和r[j]。

void BubbleSort(SqList &L)
{for (int i=L.length, change=TRUE;i>1 && change; --i)
      {	change = FALSE;
	for (int j=1; j<i; ++j)
	   if (LT(L.r[j+1].key,L.r[j].key))
                 { ElemType temp=L.r[j];
		L.r[j]=L.r[j+1];
		L.r[j+1]=temp;
		change = TRUE;
		}
     }
}

2. 快速排序 (Quick Sort)
快速排序方法的基本思想是任取待排序对象序列中的某个对象 (例如取第一个对象) 作为枢轴(pivot),按照该对象的关键字大小,将整个对象序列划分为左右两个子序列:
左侧子序列中所有对象的关键字都小于或等于枢轴对象的关键字
右侧子序列中所有对象的关键字都大于枢轴对象的关键字
枢轴对象则排在这两个子序列中间(这也是该对象最终应安放的位置)。

QuickSort ( List ) {
     if ( List的长度大于1) {
	将序列List划分为两个子序列
                LeftList 和 Right List;
         QuickSort ( LeftList );
	QuickSort ( RightList );	
         将两个子序列 LeftList 和 RightList
   	       合并为一个序列List;
    }
}
void QSort(SqList &L, int low, int high){
	if (low < high)
               {
		int pivotloc = Partition(L,low,high);
		QSort(L,low, pivotloc-1);
		QSort(L,pivotloc+1, high);
	      }
}
void QuickSort(SqList &L){
	QSort(L,1,L.length);
}
int Partition(SqList &L, int low, int high)
 { L.r[0] = L.r[low];
   int pivotkey = L.r[low].key;
   while (low < high)
      {	while (low<high && L.r[high].key >= pivotkey) --high;		L.r[low] = L.r[high];
	while (low<high && L.r[low].key <= pivotkey) ++low;		L.r[high] = L.r[low];
       }
	L.r[low]=L.r[0];
	return low;
}

选择排序(Selection Sort)

选择排序的基本思想是:每一趟 (例如第 i 趟,i = 1, …, n-1) 在后面的 n-i+1 个待排序对象中选出关键字最小的对象, 作为有序对象序列的第 i 个对象。待到第 n-1 趟作完,待排序对象只剩下1个,就不用再选了。
1. 简单选择排序 (Simple Selection Sort)
基本步骤为:i从1开始,直到n-1,进行n-1趟排序,第i 趟的排序过程为: 在一组对象r[j]~r[n] (j=i+1,…,n)中选择具有最小关键字的对象;并和第 i 个对象进行交换;

void SelectSort(SqList &L)
 { for (int i=1; i<L.length;++i)
      { int k=i;  
	  for (int j=i+1;j<=L.length;++j)
	         if (L.r[k].key > L.r[j].key)   k=j;
	  if (i!=k){ ElemType temp=L.r[i];
		          L.r[i]=L.r[k];
		          L.r[k]=temp; 	
                        }
	}
}

归并排序 (Merge Sort)

归并,是将两个或两个以上的有序表合并成一个新的有序表。
对象序列 initList 中有两个有序表V[l] …V[m]和V[m+1] …V[n]。它们可归并成一个有序表,存于另一对象序列 mergedList 的V[l] …V[n]中。
这种归并方法称为2-路归并 (2-way merging)。
其基本思想是:设两个有序表A和B的对象个数(表长)分别为 al 和 bl,变量 i 和 j 分别是表A和表B的当前检测指针。设表C是归并后的新有序表,变量 k 是它的当前存放指针。
当 i 和 j 都在两个表的表长内变化时,根据A[i]与B[j]的关键字的大小,依次把关键字小的对象排放到新表C[k]中;
当 i 与 j 中有一个已经超出表长时,将另一 个表中的剩余部分照抄到新表C[k]中。
在这里插入图片描述

void Merge(ElemType SR[],ElemType TR[],int i, int m,int n)
//将有序表的SR[i..m]和SR[m+1..n]归并成有序表
{
    for (int j=m+1,k=i;i<=m && j<=n; ++k)
    {  
         if (LQ(SR[i].key ,SR[j].key)) 
	    TR[k] = SR[i++];
         else TR[k] = SR[j++];
     }
    if (i<=m) 
    for (int n1=k,n2=i;n1<=n &&n2<=m;n1++,n2++) 
	TR[n1]=SR[n2];
    if (j<=n) 
    for (int n1=k,n2=j;n1<=n && n2<=n;n1++,n2++) 
	TR[n1]=SR[n2];
}

基数排序 (Radix Sort)

基数排序是采用“分配”与“收集”的办法,用对多关键字进行排序的思想实现对单关键字进行排序的方法。
最低位优先法首先依据最低位关键字Kd对所有对象进行一趟排序,再依据次低位关键字Kd-1对上一趟排序的结果再排序,依次重复,直到依据关键字K^1最后一趟排序完成,就可以得到一个有序的序列。使用这种排序方法对每一个关键字进行排序时,不需要再分组,而是整个对象组都参加排序。
最高位优先法通常是一个递归的过程:
先根据最高位关键字K1排序,得到若干对象组,对象组中每个对象都有相同关键字K1。 再分别对每组中对象根据关键字K2进行排序,按K2值的不同,再分成若干个更小的子组,每个子组中的对象具有相同的K1和K2值。
依此重复,直到对关键字K^d完成排序为止。
最后,把所有子组中的对象依次连接起来,就得到一个有序的对象序列。
不稳定排序有希尔排序、简单选择排序、快速排序、堆排序;
稳定排序有直接插入排序、折半插入排序、冒泡排序、归并排序、基数排序。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cai-4

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值