#include<iostream> #include<string.h> #include<math.h> using namespace std; int EQ(int a,int b) { return a==b?1:0;} int LT(int a,int b) { return a<b ?1:0;} int LQ(int a,int b) { return a<=b?1:0;} #define MAXSIZE 50 typedef struct { int key; //关键字项 int other;//其他数据项 }RedType; typedef struct { RedType r[MAXSIZE+1];//r[0]闲置或者作为哨兵单元 int length; }SqList; //顺序表类型 //顺序表的建立 void CreateSqList(SqList &L) { cout<<"请输入顺序表的长度:"; cin>>L.length; int i; cout<<"请输入"<<L.length<<"个元素:"; for(i=1;i<=L.length;i++) cin>>L.r[i].key; } //简单选择排序 int SelectMinKey(SqList &L,int i) { int j,t,min=L.r[i].key; t=i; for(j=i;j<=L.length;j++) if(LT(L.r[j].key,min)) { min=L.r[j].key; t=j; } return t; } void SelectSort(SqList &L) { int i,j,t; for(i=1;i<L.length;i++) { j=SelectMinKey(L,i);//在L.r[i...L.length]中选择key的最小记录 if(i!=j)//与第i个记录交换 {t=L.r[i].key ; L.r[i].key=L.r[j].key; L.r[j].key=t;} } } //直接插入排序 void InsertSort(SqList &L) { int i,j; for(i=2;i<=L.length;i++) if( LT(L.r[i].key,L.r[i-1].key) )//需要将L.r[i]插入有序子表 { L.r[0]=L.r[i]; //复制为哨兵 L.r[i]=L.r[i-1]; for(j=i-2; LT(L.r[0].key,L.r[j].key ); j--) L.r[j+1]=L.r[j]; //记录后移 L.r[j+1]=L.r[0]; //插入 } } //冒泡排序 void BubbleSort(SqList &L) { int i,j,temp; for(i=1;i<L.length;i++) for(j=1;j<=L.length-i;j++) if(LT(L.r[j+1].key,L.r[j].key)) {temp=L.r[j].key; L.r[j].key=L.r[j+1].key; L.r[j+1].key=temp; } } //输出顺序表 void print(SqList L) { int i; cout<<"排序输出为:"; for(i=1;i<=L.length;i++) cout<<L.r[i].key<<" "; cout<<endl; } //希尔排序 void ShellInsert(SqList &L,int dk) // 对顺序表L做一趟希尔排序。r[0]只是暂存单元,不是哨兵。当j<=0时,插入位置已找到 { int i,j; for(i=dk+1;i<=L.length;i++) if(LT(L.r[i].key,L.r[i-dk].key))//将L.r[i]插入有序增量子表 { L.r[0]=L.r[i]; //暂时存在r[0] for(j=i-dk; j>0&<(L.r[0].key,L.r[j].key); j-=dk) L.r[j+dk]=L.r[j]; //记录后移,直接插入位置 L.r[j+dk]=L.r[0]; //插入 } } void ShellSort(SqList &L) { int k,i,t; t=(int)log((double)(L.length-1)); int dlta[MAXSIZE]; for(k=0;k<t;k++) { dlta[k]=1; for(i=1;i<=t-k;i++) dlta[k]=2*dlta[k]; dlta[k]+=1; } dlta[k]=1; for(k=0;k<=t;k++) ShellInsert(L,dlta[k]); } //快速排序 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; } void QSort(SqList &L,int low,int high) { if(low<high) //长度大于1 { 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); } //堆排 void HeapAdjust (SqList &H,int s,int m) { RedType rc=H.r[s]; int j; for(j=2*s;j<=m;j*=2) { if(j<m && LT(H.r[j].key,H.r[j+1].key)) j++; if(!LT(rc.key,H.r[j].key)) break; H.r[s]=H.r[j]; s=j; } H.r[s]=rc; } void HeapSort(SqList &H) { int i;RedType temp; for(i=H.length/2;i>0;i--) HeapAdjust(H,i,H.length); for(i=H.length;i>1;i--) { {temp=H.r[1]; H.r[1]=H.r[i]; H.r[i]=temp; } HeapAdjust(H,1,i-1); } } //链式操作---------------------- int ListLength; typedef struct node { int key; struct node *next; }node,*LinkList; LinkList CreatNode() { LinkList p; p=(LinkList)malloc(sizeof(node)); p->next=NULL; return p; } //数据的输入 void CreatList(LinkList &head) { int i,key; cout<<"输入链表的长度:"; cin>>ListLength; cout<<"请输入"<<ListLength<<"个元素:"; LinkList p,q; p=head; for(i=0;i<ListLength;i++) { cin>>key; q=CreatNode(); q->key=key; p->next=q; p=p->next; } } //链式输出 void printt(LinkList &head) { LinkList p; p=head->next; while(p) { cout<<p->key<<" "; p=p->next; } cout<<endl; } //简单的选择排序 int SMinKey(LinkList &head,int i) { int count,j,min; LinkList p; p=head->next; for(j=1;j<i;j++) p=p->next; count=i; min=p->key; while(p) { if(LT(p->key,min)) {min=p->key; count=i;} p=p->next; i++; } return count; } LinkList DeList(LinkList &head,int j) { int k; LinkList t,q; t=head; for(k=1;k<j;k++) t=t->next; q=t->next; t->next=t->next->next; return q; } void SelectSort2(LinkList &head) { int i,j; LinkList p; LinkList q; p=head; for(i=1;i<ListLength;i++) { j=SMinKey(head,i); if(i!=j) { q=DeList(head,j); q->next=p->next; p->next=q; } p=p->next; } } //链式直接插入排序 void Insert(LinkList &head,LinkList &q) { LinkList p; p=head; while(p->next && LT( p->next->key,q->key )) p=p->next; if(!p->next) { p->next=q; q->next=NULL; } else { q->next=p->next; p->next=q; } } LinkList DelList(LinkList &head,int i) { int k; LinkList t,q; t=head; for(k=1;k<i;k++) t=t->next; q=t->next; t->next=t->next->next; return q; } void InsertSort2(LinkList &head) { int i; LinkList p; LinkList q; p=head; for(i=1;i<ListLength;i++) { q=DeList(head,i); Insert(head,q); p=p->next; } } // int main() { LinkList Head; Head=CreatNode(); int c1; cout<<"----------------欢迎进入排序界面--------------------"<<endl; cout<<"--------------------"<<endl; cout<<"|顺序表操作 选0 |"<<endl; cout<<"|链表操作 选1 |"<<endl; cout<<"|退出 选-1 |"<<endl; cout<<"--------------------"<<endl; while(cin>>c1) { if(c1==-1) break; else if(c1==0) { SqList L; int c2; cout<<"----------------------"<<endl; cout<<"|顺序表建立 选0 |"<<endl; cout<<"|顺序表简单排序 选1 |"<<endl; cout<<"|顺序表直插排序 选2 |"<<endl; cout<<"|顺序表冒泡排序 选3 |"<<endl; cout<<"|顺序表希尔排序 选4 |"<<endl; cout<<"|顺序表快速排序 选5 |"<<endl; cout<<"|顺序表堆排 选6 |"<<endl; cout<<"|顺序表输出 选7 |"<<endl; cout<<"|退出 选-1 |"<<endl; cout<<"----------------------"<<endl; while(cin>>c2) { if(c2==-1) break; else if(c2==0) { CreateSqList(L); cout<<"顺序表建立操作完毕"<<endl; } else if(c2==1) { SelectSort(L); cout<<"顺序表简单排序操作完毕"<<endl; } else if(c2==2) { InsertSort(L);cout<<"顺序表直插排序操作完毕"<<endl; } else if(c2==3) { BubbleSort(L);cout<<"顺序表冒泡排序操作完毕"<<endl; } else if(c2==4) { ShellSort(L);cout<<"顺序表希尔排序操作完毕"<<endl; } else if(c2==5) { QSort(L,1,L.length);cout<<"顺序表快速排序操作完毕"<<endl; } else if(c2==6) { HeapSort(L);cout<<"顺序表堆排操作完毕"<<endl; } else if(c2==7) { print(L);cout<<"顺序表输出操作完毕"<<endl; } cout<<"----------------------"<<endl; cout<<"|顺序表建立 选0 |"<<endl; cout<<"|顺序表简单排序 选1 |"<<endl; cout<<"|顺序表直插排序 选2 |"<<endl; cout<<"|顺序表冒泡排序 选3 |"<<endl; cout<<"|顺序表希尔排序 选4 |"<<endl; cout<<"|顺序表快速排序 选5 |"<<endl; cout<<"|顺序表堆排 选6 |"<<endl; cout<<"|顺序表输出 选7 |"<<endl; cout<<"|退出 选-1 |"<<endl; cout<<"----------------------"<<endl; } } else if(c1==1) { cout<<"--------------------"<<endl; cout<<"|链表建立 选1 |"<<endl; cout<<"|链表简单排序 选2 |"<<endl; cout<<"|链式直插排序 选3 |"<<endl; cout<<"|链式输出 选4 |"<<endl; cout<<"|退出 选-1 |"<<endl; cout<<"--------------------"<<endl; int c3; while(cin>>c3) { if(c3==-1)break; switch(c3) { case 1:CreatList(Head);cout<<"链表建立操作完毕"<<endl;break; case 2:SelectSort2(Head);cout<<"链表简单排序操作完毕"<<endl;break; case 3:InsertSort2(Head);cout<<"链式直插排序操作完毕"<<endl;break; case 4:printt(Head);cout<<"链式输出操作完毕"<<endl;break; } cout<<"--------------------"<<endl; cout<<"|链表建立 选1 |"<<endl; cout<<"|链表简单排序 选2 |"<<endl; cout<<"|链式直插排序 选3 |"<<endl; cout<<"|链式输出 选4 |"<<endl; cout<<"|退出 选-1 |"<<endl; cout<<"--------------------"<<endl; } } cout<<"--------------------"<<endl; cout<<"|顺序表操作 选0 |"<<endl; cout<<"|链表操作 选1 |"<<endl; cout<<"|退出 选-1 |"<<endl; cout<<"--------------------"<<endl; } cout<<"结束"<<endl; return 0; } // 9 5 6 8 0 1 7 2 3 4
输入一组关键字序列分别实现下列排序:
(1)实现简单选择排序、直接插入排序和冒泡排序。
(2)实现希尔排序算法。
(3)实现快速排序算法。
(4)实现堆排序算法。
(5)采用链式存储实现简单选择排序、直接插入排序和冒泡排序。
(6)在主函数中设计一个简单的菜单,分别测试上述算法。
综合训练:采用几组不同数据测试各个排序算法的性能(比较次数和移动次数)。