C++各种排序算法

#include<stdio.h>
#include<string.h>
#include<malloc.h>
#define MAXSIZE 20//一个用作示例的小顺序表的最大长度
#define OK 1
#define TRUE 1
#define ERROR 0
#define FALSE 0
#define OVERLOW -2
#define EQ(a,b) ((a)==(b))
#define LT(a,b) ((a)< (b))
#define LQ(a,b) ((a)<=(b))

typedef int Status;
typedef int KeyType;
typedef struct
{//记录类型(学生学号及姓名)
 KeyType key;
 char name[10];
}RedType;
typedef struct
{//顺序表存储结构
 RedType *elem;//elem[0]闲置或用作哨兵单元
 int length;//顺序表示实际长度
}SqList;

Status InitSqList(SqList &L)
{//初始化顺序表
 L.elem=(RedType *)malloc((MAXSIZE+1)*sizeof(RedType));
 L.length=0;
 return OK;
}

Status CreateSqList(SqList &L,int n)
{//构建顺序表
 int i;
 printf("请输入各条记录的内容(学号、姓名):/n");
 for(i=1;i<=n;i++)
  scanf("%d%s",&L.elem[i].key,L.elem[i].name);
 L.length=n;
 return OK;
}

void Print(SqList L)
{//依次输出顺序表中各记录
 int i;
 for(i=1;i<=L.length;i++)
  printf("%d%s/n",L.elem[i].key,L.elem[i].name);
}

void InsertSort(SqList &L)
{//对顺序表直接插入排序
 int i,j;
 for(i=2;i<=L.length;i++)
  if(LT(L.elem[i].key,L.elem[i-1].key))
  {
   L.elem[0]=L.elem[i];
   for(j=i-1;LT(L.elem[0].key,L.elem[j].key);j--)
    L.elem[j+1]=L.elem[j];
   L.elem[j+1]=L.elem[0];
  }
}
void BInsertSort(SqList &L)
{//折半插入排序
 int i,j,low,high,mid;
 for(i=2;i<=L.length;i++)
 {//执行n-1次直接插入排序
  L.elem[0]=L.elem[i];
  low=1;high=i-1;
  while(low<=high)//查找插入位置(high的后面)
  {
   mid=(low+high)/2;
   if(LT(L.elem[0].key,L.elem[mid].key))
    high=mid-1;
   else
    low=mid+1;
  }
  for(j=i-1;j>=high+1;j--)
   L.elem[j+1]=L.elem[j];
  L.elem[high+1]=L.elem[0];
 }
}

void ShellInsert(SqList &L,int dk)
{//一趟希尔插入排序(等价于步长为dk的直接插入排序)
 int i,j;
 for(i=1+dk;i<=L.length;i++)
  if(LT(L.elem[i].key,L.elem[i-1].key))
  {
   L.elem[0]=L.elem[i];
   for(j=i-dk;LT(L.elem[0].key,L.elem[j].key);j-=dk)
    L.elem[j+dk]=L.elem[j];
   L.elem[j+dk]=L.elem[0];
  }
}

void ShellSort(SqList &L)
{//希尔排序
 int t=3,dlta[3]={5,3,1},k;
 for(k=0;k<t;k++)
  ShellInsert(L,dlta[k]);
}

int Partition(SqList &L,int low,int high)
{//求顺序表L.elem[low...high]的枢轴记录在表中的位置
 int pivotkey;
 pivotkey=L.elem[low].key;
 L.elem[0]=L.elem[low];
 while(low<high)
 {//四种情况
  while((low<high)&&LQ(pivotkey,L.elem[high].key)) high--;
  L.elem[low]=L.elem[high];
  while((low<high)&&LQ(L.elem[low].key,pivotkey)) low++;
  L.elem[high]=L.elem[low];
 }
 L.elem[low]=L.elem[0];
 return low;
}
void QSort(SqList &L,int low,int high)
{//对顺序表L中的子序列L.elem[low...high]做快速排序
 int pivotloc;//枢轴记录在顺序表中的位置
 if(low<high)
 {
  pivotloc=Partition(L,low,high);
  QSort(L,low,pivotloc-1);
  QSort(L,pivotloc+1,high);
 }
}
void QuickSort(SqList &L)
{
 QSort(L,1,L.length);
}

void Merge(RedType SR[],RedType TR[],int i,int m,int n)
{
 int j,k,l;
 for(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(l=0;l<=m-i;l++)
    TR[k+1]=SR[i+1];
   if(j<=n)
    for(l=0;l<=n-j;l++)
     TR[k+1]=SR[j+1];
}
void MSort(RedType SR[],RedType TR1[],int s,int t)
{//将SR[]归并排序为TR1[]
 int m;
 RedType TR2[MAXSIZE+1];
 if(s==t)
  TR1[s]=SR[s];
 else
 {
  m=(s+t)/2;
  MSort(SR,TR2,s,m);
  MSort(SR,TR2,m+1,t);
  Merge(TR2,TR1,s,m,t);
 }
}
void MergeSort(SqList &L)
{
 MSort(L.elem,L.elem,1,L.length);
}

int Choice()
{//选择排序方法
 int num;
 printf("1.直接插入排序/n2.折半插入排序/n3.希尔排序/n4.快速排序/n5.归并排序/n请输入您选择的排序编号:");
 scanf("%d",&num);
 return num;
}

int main()
{
 SqList L;
 int n;
 InitSqList(L);
 printf("请输入要排序的顺序表的长度:");scanf("%d",&n);
 CreateSqList(L,n);
 printf("***您输入的记录序列是***/n");Print(L);
 switch(Choice())
 {
 case 1:InsertSort(L);printf("**经过直接插入排序后生成的记录序列是**/n");Print(L);break;
 case 2:BInsertSort(L);printf("**经过折半插入排序后生成的记录序列是**/n");Print(L);break;
 case 3:ShellSort(L);printf("**经过希尔排序后生成的记录序列是**/n");Print(L);break;
 case 4:QuickSort(L);printf("**经过快速排序后生成的记录序列是**/n");Print(L);break;
 case 5:MergeSort(L);printf("**经过归并排序后生成的记录序列是**/n");Print(L);break;
 default:break;
 }
 return 0;
}
 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值