插入排序,选择排序,归并排序等等源码及简要分析

【说明】这些代码部分参考严蔚敏老师的《数据结构》一书

【源代码】

//数据结构
#define MAX_LEN 40
typedef int KeyType;
typedef struct SQLIST{
 KeyType key[MAX_LEN+1];  //关键字
 int Length;     //表实际长度
}SqList;

void PrintList(char * strKind,SqList list)
{
 printf("%s",strKind);
 for(int i=1; i<=list.Length; i++){
  printf("%d ",list.key[i]);
 }
 printf("/n");
}
void MakeList(SqList &list)
{
 printf("please input the length :");
 scanf("%d",&list.Length);
 while(list.Length > MAX_LEN){
  printf("What you Input length is over Max %d/n",MAX_LEN);
  printf("please input again : ");
  scanf("%d",&list.Length);
 }
 printf("please input numbers :");
 for(int i=1; i<=list.Length; i++){
  scanf("%d",&list.key[i]);
 }
}
//快速排序
//测试数据:5 2 6 9 7 1 3 4 0 8
//      11 55 68 2 35 78 9 87 -1 -58
//1,BubSort,升序排列
void BubSort(SqList &list)
{
 KeyType temp;
 for(int i=list.Length; i>=1; i--){
  for (int j=2; j<=i; j++)
   if(list.key[j-1] > list.key[j]){
    temp    = list.key[j-1];
    list.key[j-1] = list.key[j];
    list.key[j]   = temp;
   }
 }
}
//2,Quick Sort,BubSort的升级,同样是升序排列
int Partition(SqList &list,int low,int high) //寻找划分处(剑影)
{
 list.key[0] = list.key[low];
 int pivotkey = list.key[low];
 while(low < high){
  while(low < high && list.key[high] >= pivotkey)
   high--;
  list.key[low] = list.key[high];
  while(low <high && list.key[low] <= pivotkey)
   low++;
  list.key[high] = list.key[low];
 }
 list.key[low] = list.key[0];
 return low;
}
void QuickSort(SqList &list,int low,int high)
{
 if (low < high)
 {
  int pivotloc = Partition(list,low,high);
  QuickSort(list,low,pivotloc-1);
  QuickSort(list,pivotloc+1,high);
 }
}

//选择排序 升序
//测试数据:5 2 6 9 7 1 3 4 0 8
//      11 55 68 2 35 78 9 87 -1 -58
//   0 256 0 25 86 9 -456 7 -56 100
//1,简单选择排序
int SelectMinKey(SqList list,int flag)
{
 list.key[0] = list.key[flag];
 int iMin = flag;
 for(int i=flag; i<=list.Length; i++)
  if (list.key[0] > list.key[i])
  {
   list.key[0] = list.key[i];
   iMin = i;
  }
 return iMin;
}
void SelectSort(SqList &list)
{
 KeyType temp;
 for(int i=1; i<=list.Length; i++){
  int j = SelectMinKey(list,i);
  if(i != j){
   temp  = list.key[j];
   list.key[j] = list.key[i];
   list.key[i] = temp;
  }
 }
}
//2,堆排序:适合处理记录较大的数据
//堆定义:1,大根堆,K(i)>=K(2i)&&K(i)>=K(2i+1)
//    2,小根堆,K(i)<=K(2i)&&K(i)<=K(2i+1)
void HeapAdjust(SqList &list,int s,int m)
{
 //前提条件:list中除list.key[s]之外均满足堆的定义
 //目的   :重新调整list,使其满足大根堆的条件
 KeyType rc = list.key[s];
 for(int j=2*s; j<=m; j*=2){
  if(j<m && list.key[j]<list.key[j+1])
   j++;
  if(rc > list.key[j]) 
   break;
  list.key[s] = list.key[j];
  s = j;
 }
 list.key[s] = rc;
}
void HeapSort(SqList &list)
{
 KeyType temp;
 for(int i = list.Length/2; i>0; i--)  //将list建成大根堆,从表后往前调整
  HeapAdjust(list,i,list.Length);
 for(i = list.Length; i>1; --i){       //每次将大根堆的第一个元素(即值最大)
  temp = list.key[1];      //取出来放在末尾位置上(撇开已经排好的序列) 
  list.key[1] = list.key[i];
  list.key[i] = temp;
  HeapAdjust(list,1,i-1);     //重新调整list为大根堆
 }
}

//归并排序:升序
//测试数据:5 2 6 9 7 1 3 4 0 8
//      11 55 68 2 35 78 9 87 -1 -58
//   0 256 0 25 86 9 -456 7 -56 100
void Merge(SqList &SR,SqList &TR,int i,int m,int n)
{
 for (int j=m+1,k=i; i<=m && j<=n; k++){
  if(SR.key[i] < SR.key[j])
   TR.key[k] = SR.key[i++];
  else
   TR.key[k] = SR.key[j++];
 }
 for( ; i<=m && k<=n; i++){
  TR.key[k] = SR.key[i];
  k++;
 }
 for( ; j<=n && k<=n; j++){
  TR.key[k] = SR.key[j];
  k++;
 }
}
void MSort(SqList SR,SqList &TR1,int s,int t)
{
 if(s ==t)
  TR1.key[s] = SR.key[s];
 else{
  SqList TR2;
  int m = (s+t)/2;
  MSort(SR,TR2,s,m);
  MSort(SR,TR2,m+1,t);
  Merge(TR2,TR1,s,m,t);
 }
}
void MergeSort(SqList &list)
{
 MSort(list,list,1,list.Length);
}

//插入排序
//1,直接插入排序
void InsertSort(SqList &list)
{
 for(int i=2; i<=list.Length; i++)
  if(list.key[i] < list.key[i-1]){
   list.key[0] = list.key[i];
   list.key[i] = list.key[i-1];
   for(int j=i-2; list.key[0]<list.key[j]; j--)
    list.key[j+1] = list.key[j];
   list.key[j+1] = list.key[0];
  }
}
//2,希尔排序:对直接插入排序的一种优化(升级)
//又称:缩小增量排序
//排序描述:
//希尔排序的时间是增量序列的函数
void ShellInsert(SqList &list,int dk)
{
 for (int i = dk+1; i<=list.Length; i++)
  if(list.key[i] < list.key[i-dk]){
   list.key[0] = list.key[i];
   for (int j=i-dk; j>0 && list.key[0]<list.key[j]; j-=dk)
    list.key[j+dk] = list.key[j];
   list.key[j+dk] = list.key[0];
  }
}
void ShellSort(SqList &list,int dlta[],int t)
{
 //增量要求:
 //在参考了河南大学,南京大学的张连堂教授和张博教授的《希尔排序最佳增量序列研究》后
 //得出结论:当dlta[k] = 2`k-1;,即增量序列为...,2`k-1,...,15,7,3,1时排序较为理想
 //严蔚敏老师的书上介绍了另外一个人的说法:dlta[k] = 2`(t-k+1)-1时排序的时间复杂度为O(n`(3/2))
 for (int k=0; k<t; k++)
  ShellInsert(list,dlta[k]);
}

【测试程序】

#include <stdio.h>
#include "AllKindofSort.h"

int main(int, char **, char **)
{
 SqList lt;
 MakeList(lt);
 BubSort(lt);
 PrintList("BubSort : ",lt);
//
 SqList lt1;
 MakeList(lt1);
 QuickSort(lt1,0,lt1.Length);
 PrintList("Quick Sort : ",lt1);
//
 SqList lt2;
 MakeList(lt2);
 SelectSort(lt2);
 PrintList("Simple Select Sort : ",lt2);
//
 SqList lt3;
 MakeList(lt3);
 HeapSort(lt3);
 PrintList("Heap Sort : ",lt3);
//
 SqList lt4;
 MakeList(lt4);
 MergeSort(lt4);
 PrintList("Merge Sort : ",lt4);

//
 SqList lt5;
 MakeList(lt5);
 InsertSort(lt5);
 PrintList("Direct Insert Sort : ",lt5);
//
 SqList lt6;
 int dt[3] = {7,3,1};
 MakeList(lt6);
 ShellSort(lt6,dt,3);
 PrintList("Shell Sort : ",lt6);

 return 0;
}

【测试结果】

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值