#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)在主函数中设计一个简单的菜单,分别测试上述算法。
综合训练:采用几组不同数据测试各个排序算法的性能(比较次数和移动次数)。