数据结构中几种算法排序
#include<stdlib.h>
#include<time.h>
#include<conio.h>
#include<string.h>
#define MAX_NUM 6000 //*待排序记录表的最大长度
#define MAX_STR_LEN 10
typedef int KeyType;//*关键字为int类型
typedef struct {
KeyType key;//*关键字(忽略数据元素的其他数据项)
}RecordType;//记录类型
typedef struct{
RecordType R[ MAX_NUM+1];//R[0]闲置或用作哨兵单元
int length;//表长度
}OrderList;//待排序表类型
long compCount;//比较次数
long moveCount;//移动次数
//随机产生n个1~m之间的整数,保存在数组a中a.R[1]~a.R[m]
//OrderList CreateDataRandom(int n,int m,OrderList a)
OrderList CreateDataRandom(OrderList a)
{
int n,m,i;
printf("排序数据为自动生成的1~m之间的n个数,请输入n,m:");
scanf("%d,%d",&n,&m);
srand((unsigned)time(NULL));//srand()提供一个种子,是0到32767之间的整数,因为time()函数,所以每次种子不同*/
for(i=1;i<=n;i++){
a.R[i].key=rand()%m+1;//rand函数对m求余数,再+1,得到1~m之间的一个整数。m为10000,即得到1~10000之间的n个整数
}
a.length=n;//不要遗漏
return a;
}
OrderList CopyList(OrderList a)
{
//复制顺序表
OrderList b;
int i;
b.length=a.length;
for(i=1;i<=a.length;i++)
{
b.R[i]=a.R[i];
}
return b;
}
void InvertedList(OrderList *a)
{
//逆序表
int i;
RecordType temp;
for(i=1;i<=a->length/2;i++)
{
temp=a->R[i];
a->R[i]=a->R[a->length-i+1];
a->R[a->length-i+1]=temp;
}
}
int Less(int x,int y)//逆序返回0,正序返回1
{
compCount++;
return x<y;//x<y返回1,否则返回0;
}
int LessOrEqual(int x,int y)//逆序返回0,正序返回1
{
compCount++;
return x<=y;//x<=y返回1,否则返回0;
}
void Swap(OrderList *L,int i,int j)//交换R[i],R[j]
{
RecordType temp;
temp=L->R[i];
L->R[i]=L->R[j];
L->R[j]=temp;
moveCount+=3;
}
void OutputData(OrderList a)//输出
{
int i;
for(i=1;i<=a.length;i++)
{
printf("%d ",a.R[i].key);
if((i%10)==0 )printf("\n");
}
}
OrderList InsertSort(OrderList L)//直接插入排序
{
int i,j;
for(i=2;i<=L.length;i++)//依次输入R[2].....R[L.lengrh]
{
L.R[0]=L.R[i];//L.R[0]为哨兵
j=i-1;
while(Less(L.R[0].key,L.R[j].key))
{
L.R[j+1]=L.R[j];//记录后移
moveCount++;
j--;
}
L.R[j+1]=L.R[0];
}
return L;
}
OrderList ShellSort(OrderList L)//希尔排序
{
int i,j,d;
RecordType temp;
for(d=L.length/2;d>0;d/=2)
{
for(i=d+i;i<=L.length;i++)//数据存储从R[i]起,R[0]闲置
{
temp=L.R[i];
j=i-d;
while(j>=1&&Less(temp.key,L.R[j].key))
{
L.R[j+d]=L.R[j];//记录后移d个位置
moveCount++;
j=j-d;
}
L.R[j+d]=temp;//插入记录
}
}
return L;
}
OrderList BubbleSort(OrderList L)
{
//冒泡排序
int i,j;
int flag;//交换标志
for(j=1;j<=L.length-1;i++)//最多做n-1趟排序
{
flag=0;//本趟排序前,交换标志为0
for(i=1;i<=L.length-j;i++)//对当前无序区扫描
if(Less(L.R[i+1].key,L.R[i].key))
{//交换记录
Swap(&L,i+1,i);
flag=1;//发生交换
}
if(flag==0)
break;
}
return L;
}
//一趟快速排序
int Partition(OrderList *L,int i,int j)
{
int pivotkey;
L->R[0]=L->R[i];//以子表的首记录作为枢纽记录,放入R[0]单元
pivotkey=L->R[i].key;
while(i<j)//从表的两端交替地向中间扫描
{
while(i<j&&LessOrEqual(pivotkey,L->R[j].key)) --j;
{
L->R[i]=L->R[j];//将比枢纽小的记录交换到低端
moveCount++;
}
while(i<j&&LessOrEqual(L->R[i].key,pivotkey)) ++i;
{
L->R[j]=L->R[i];//将比枢纽大的记录交换到高端
moveCount++;
}
}
L->R[i]=L->R[0];//枢纽记录到位
return i;//返回枢纽记录所在位置
}
//快速排序
void QuickSort(OrderList *L,int i,int j)
{
int pivot;
if(i<j)//长度>1
{
pivot=Partition(L,i,j);//一趟快排,将R[]一分为二
QuickSort(L,i,pivot-1);//在左子区间进行递归快排,直到长度为1;
QuickSort(L,pivot+1,j);//在右子区间进行递归快排,直到长度为1;
}
}
OrderList SelectSort(OrderList L)//简单选择排序
{
int i,j,min;
for(i=1;i<L.length;i++)//对n个记录进行n-1趟的简单选择排序
{
min=i;//初始化第i趟简单排序的最小记录指针
for(j=i+1;j<=L.length;j++)//搜索关键字最小的记录位置
if(Less(L.R[j].key,L.R[min].key))
min=j;
if(min!=i)
Swap(&L,i,min);
}
return L;
}
OrderList HeapAdjust(OrderList H,int s,int m)//堆排序筛选算法
{
//已知H.R[s..m]中记录的关键字除H.R[s].key之外均满足堆定义
//本函数调整H.R[s],使H.R[s..m]成为一个小跟堆
RecordType rc;
int j;
rc=H.R[s];
for(j=2*s;j<=m;j*=2)//沿key较小的关键字向下筛选
{
if((j<m)&&LessOrEqual(H.R[j+1].key,H.R[j].key))
j++;//j为较小的记录下标
if(LessOrEqual(rc.key,H.R[j].key))
break;//rc应在位置s上
H.R[s]=H.R[j];
moveCount++;
s=j;
}
H.R[s]=rc;//调整到位
return H;
}
OrderList HeapSort(OrderList H)
{
int i;
for(i=H.length/2;i>0;--i)//把H.R[1...H.length]建成小跟堆
H=HeapAdjust(H,i,H.length);//从i=H。length/2往前依次调整
for(i=H.length;i>1;i--)//输出堆顶,然后重建堆
{
Swap(&H,1,i);//堆顶与堆底交换
H=HeapAdjust(H,1,i-1);//将R.R[1...i-1]重建堆
}
return H;
}
void sort(OrderList a,OrderList b,int op)
{
int i;
char *str[3];
for(i=0;i<3;i++)
str[i]=(char*)malloc(MAX_STR_LEN*sizeof(char));
strcpy(str[0],"随机序列");
strcpy(str[1],"正序");
strcpy(str[2],"逆序");
a=CopyList(b);
for(i=0;i<3;i++)
{
compCount=0;moveCount=0;
if((i==2&&op!=7)||(i==1&&op==7))
{
InvertedList(&a);
}
switch(op)
{
case 2:a=InsertSort(a);break;
case 3:a=ShellSort(a);break;
case 4:a=BubbleSort(a);break;
case 5:QuickSort(&a,1,a.length);break;
case 6:a=SelectSort(a);break;
case 7:a=HeapSort(a);break;
}
if(i==0) OutputData(a);
printf("\n初态是%s:比较次数=%d 移动次数=%d\n",str[i],compCount,moveCount);
getch();
}
}
int main()
{
OrderList a,b;//待排序数据
int choose;
while(1)
{
system("cls");
printf(" 内部算法比较 \n");
printf(" 1.初始化待排序数据 \n ");
printf(" 2.直接插入排序 3.希尔排序 \n ");
printf(" 4.简单选择 5.快速排序\n");
printf(" 6.简单选择 7.堆排序 \n");
printf(" 0.退出 ");
printf(" \n");
printf(" 输入选项(0~7)\n");
scanf("%d",&choose);
if(choose==1)
{
a=CreateDataRandom(a);
printf("初始数据是: \n");
b=CopyList(a);
OutputData(a);
getch();
}
else
{
if(choose==0)
{
printf("\n按任意键退出系统\n");
getch();
exit(0);
}
else
sort(a,b,choose);
}
}
return 0;
}