数据结构实验课_实验八 排序

一.实验内容
1.编写程序实现下列排序算法:
(1)插入排序;
(2)希尔排序;
(3)冒泡排序;
(4)快速排序;
(5)选择排序;
(6)堆排序;
(7)归并排序。
2.在主函数中设计一个简单的菜单,用随机函数生成一组数,分别测试上述算法。

代码实现:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<time.h>
#include<Windows.h>
typedef int keytype;
typedef struct {
    
    
    keytype key;/*关键字码*/
}RecType;

int s[50][2];/*辅助栈s*/
void PrintArray(RecType R[],int n)
{
    
    
    int i;
    for(i=0;i<n;i++)
        printf("%6d",R[i].key);
    printf("\n");
}
void InsertSort(RecType R[],int n)/*用直接插入排序法对R[n]进行排序*/
{
    
    
    int i,j;
    RecType temp;
    for(i=0;i<=n-2;i++)
    {
    
    
        temp=R[i+1];
        j=i;
        while (temp.key<=R[j].key  && j>-1)
        {
    
    
            R[j+1]=R[j];
            j--;
        }
        R[j+1]=temp;
    }
}
void ShellInsert(RecType *r,int dk,int n)
{
    
    
    int i,j;
    keytype temp;
    for(i=dk; i<n; ++i )
        if(r[i].key <r[i-dk].key ) //将r[i]插入有序子表
        {
    
    
            temp=r[i].key;
            r[i].key=r[i-dk].key;
            for(j=i-2*dk;j>-1 && temp<r[j].key; j-=dk )
                r[j+dk].key=r[j].key; // 记录后移
            r[j+dk].key = temp; // 插入到正确位置
        }
}
void ShellSort(RecType *L,int dlta[],int t,int n)/*希尔排序*/
{
    
    
// 按增量序列 dlta[t-1] 对顺序表L作希尔排序
    int k;
    for(k=0;k<t;k++)
        ShellInsert(L,dlta[k],n); //一趟增量为 dlta[k] 的插入排序
} // ShellSort
void CreatArray(RecType R[],int n)
{
    
    
    int i;
    Sleep(1000);
    srand( (unsigned)time( NULL ) );
    for(i=0;i<n;i++)
        R[i].key=rand()%1000;
}
void BubbleSort(RecType R[],int n) /*冒泡排序*/
{
    
    
    int i,j,flag;
    keytype temp;
    for(i=0;i<n-1;i++)
    {
    
    
        flag=0;
        for(j=0;j<n-i-1;j++)
        {
    
    
            if(R[j].key>R[j+1].key)
            {
    
    
                temp=R[j].key;
                R[j].key=R[j+1].key;
                R[j+1].key=temp;
                flag=1;
            }
        }
        if(flag==0)break;
    }
}
int Hoare(RecType r[],int l,int h)/*快速排序分区处理*/
{
    
    
    int i,j;
    RecType x;
    i=l;j=h;x=r[i];
    do{
    
    
        while(i<j && r[j].key>=x.key)j--;
        if(i<j)
        {
    
    
            r[i]=r[j];
            i++;
        }
        while(i<j && r[i].key<=x.key)i++;
        if (i<j)
        {
    
    
            r[j]=r[i];
            j--;
        }
    }while(i<j);
    r[i]=x;
    return(i);
} /*Hoare*/
void QuickSort1(RecType r[],int n) /*快速排序非递归*/
{
    
    
    int l=0,h=n-1,tag=1,top=0,i;
    do{
    
    
        while (l<h)
        {
    
    
            i=Hoare(r,l,h);
            top++;
            s[top][0]=i+1;
            s[top][1]=h;
            h=i-1;
        }/*tag=0表示栈空*/
        if (top==0)tag=0;
        else
        {
    
    
            l=s[top][0];h=s[top][1];top--;
        }
    }while (tag==1); /*栈不空继续循环*/
} /*QuickSort1*/
void SelectSort(RecType R[],int n)/*直接选择排序*/
{
    
    
    int i,j,k; RecType temp;
    for(i=0;i<n-1;i++)
    {
    
    
        k=i;/*设第i个记录关键字最小*/
        for(j=i+1;j<n;j++)/*查找关键字最小的记录*/
            if(R[j].key<R[k].key)
                k=j;/*记住最小记录的位置*/
        if (k!=i) /*当最小记录的位置不为i时进行交换*/
        {
    
    
            temp=R[k];
            R[k]=R[i];
            R[i]=temp;
        }
    }
}
void HeapAdjust(RecType R[],int l,int m)/*堆排序筛选*/
{
    
    /*l表示开始筛选的结点,m表示待排序的记录个数。*/
    int i,j;
    RecType temp;
    i=l;
    j=2*i+1;   /*计算R[i]的左孩子位置*/
    temp=R[i]; /*将R[i]保存在临时单元中*/
    while(j<=m-1)
    {
    
    
        if(j<m-1 && R[j].key<R[j+1].key)
            j++; /*选择左右孩子中最大者,即右孩子*/
        if(temp.key<R[j].key)/*当前结点小于左右孩子的最小者*/
        {
    
    
            R[i]=R[j];i=j;j=2*i+1;
        }
        else  /*当前结点不小于左右孩子*/
            break;
    }
    R[i]=temp;
}
void HeapSort(RecType R[],int n)/*堆排序*/
{
    
    
    int j;
    RecType temp;
    for(j=n/2-1;j>=0;j--) /*构建初始堆*/
        HeapAdjust(R,j,n);/*调用筛选算法*/
    for(j=n;j>1;j--)   /*将堆顶记录与堆中最后一个记录交换*/
    {
    
    
        temp=R[0];
        R[0]=R[j-1];
        R[j-1]=temp;
        HeapAdjust(R,0,j-1);/*将R[0..j-1]调整为堆*/
    }
}
void Merge(RecType aa[],RecType bb[],int l,int m,int n)
{
    
    /*将两个有序子序列aa[1…m]和aa[m+1,…n]合并为一个有序序列bb[1…n]*/
    int i,j,k;
    k=l;i=l;j=m+1;/*将i,j,k分别指向aa[1…m]、aa[m+1,…n]、bb[1…n]首记录*/
    while (i<=m && j<=n)    /*将aa中记录由小到大放入bb中*/
        if(aa[i].key<=aa[j].key)
            bb[k++]=aa[i++];
        else
            bb[k++]=aa[j++];
    while (j<=n)     /*将剩余的aa[j…n]复制到bb中*/
        bb[k++]=aa[j++];
    while (i<=m)     /*将剩余的aa[i…m]复制到bb中*/
        bb[k++]=aa[i++];
}
void MergeOne(RecType aa[],RecType bb[],int len,int n)
{
    
    /*从aa[1…n]]归并到bb[1…n],其中len是本趟归并中有序表的长度*/
    int i;
    for(i=0;i+2*len-1<=n;i=i+2*len)
        Merge(aa,bb,i,i+len-1,i+2*len-1);/*对两个长度为len的有序表合并*/
    if(i+len-1<n)  /*当剩下的元素个数大于一个子序列长度len时*/
        Merge(aa,bb,i,i+len-1,n);
    else           /*当剩下的元素个数小于或等于一个子序列长度len时*/
        Merge(aa,bb,i,n,n);  /*复制剩下的元素到bb中*/
}
void MergeSort(RecType aa[],RecType bb[],int n)//归并排序 
{
    
    
    int len=1;    /*len是排序序列表的长度 */
    while (len<n)
    {
    
    
        MergeOne(aa,bb,len,n-1);
        MergeOne(bb,aa,2*len,n-1);
        len=4*len;
    }
}
int main()
{
    
    
    int n,data[3]={
    
    4,2,1},cord;
    RecType *r,*bb;
    printf("Please input number:");
    scanf("%d",&n);
    r=(RecType *)malloc(sizeof(RecType)*n);
    bb=(RecType *)malloc(sizeof(RecType)*n);
    memset(bb,0,sizeof(RecType)*n);
    do
    {
    
    
        printf("\n 主菜单  \n");
        printf("1----插入排序\n");
        printf("2----希尔排序\n");
        printf("3----冒泡排序\n");
        printf("4----快速排序\n");
        printf("5----选择排序\n");
        printf("6----堆排序\n");
        printf("7----归并排序\n");
        printf("8----退出\n");
        scanf("%d",&cord);
        switch(cord)
        {
    
    
            case 1:
                memset(r,0,sizeof(RecType)*n);
				CreatArray(r,n);
    			PrintArray(r,n);
    			InsertSort(r,n);
    			PrintArray(r,n);
                break;
            case 2:
                memset(r,0,sizeof(RecType)*n);
				CreatArray(r,n);
    			PrintArray(r,n);
    			ShellSort(r,data,3,n);
    			PrintArray(r,n);
                break;
            case 3:
                memset(r,0,sizeof(RecType)*n);
				CreatArray(r,n);
    			PrintArray(r,n);
    			BubbleSort(r,n);
    			PrintArray(r,n);
                break;
            case 4:
                memset(r,0,sizeof(RecType)*n);
				CreatArray(r,n);
    			PrintArray(r,n);
    			QuickSort1(r,n);
    			PrintArray(r,n);
                break;
            case 5:
                memset(r,0,sizeof(RecType)*n);
				CreatArray(r,n);
    			PrintArray(r,n);
    			SelectSort(r,n);
    			PrintArray(r,n);
                break;
            case 6:
            	memset(r,0,sizeof(RecType)*n);
				CreatArray(r,n);
    			PrintArray(r,n);
    			HeapSort(r,n);
    			PrintArray(r,n);
                break;
            case 7:
            	memset(r,0,sizeof(RecType)*n);
				CreatArray(r,n);
    			PrintArray(r,n);
    			MergeSort(r,bb,n);
    			PrintArray(r,n);
                break;
        	case 8:
        		exit(0);
        	default:
        		cord=0;
        }
    }while(cord<=8);
    return 0;
}

程序演示:
Please input number:6

主菜单
1----插入排序
2----希尔排序
3----冒泡排序
4----快速排序
5----选择排序
6----堆排序
7----归并排序
8----退出
1
885 785 888 182 437 260
182 260 437 785 885 888

主菜单
1----插入排序
2----希尔排序
3----冒泡排序
4----快速排序
5----选择排序
6----堆排序
7----归并排序
8----退出
2
917 965 690 439 279 759
279 439 690 759 917 965

主菜单
1----插入排序
2----希尔排序
3----冒泡排序
4----快速排序
5----选择排序
6----堆排序
7----归并排序
8----退出
3
927 442 746 325 454 771
325 442 454 746 771 927

主菜单
1----插入排序
2----希尔排序
3----冒泡排序
4----快速排序
5----选择排序
6----堆排序
7----归并排序
8----退出
4
933 939 706 684 84 625
84 625 684 706 933 939

主菜单
1----插入排序
2----希尔排序
3----冒泡排序
4----快速排序
5----选择排序
6----堆排序
7----归并排序
8----退出
5
940 668 667 274 945 478
274 478 667 668 940 945

主菜单
1----插入排序
2----希尔排序
3----冒泡排序
4----快速排序
5----选择排序
6----堆排序
7----归并排序
8----退出
6
947 397 627 633 806 332
332 397 627 633 806 947

主菜单
1----插入排序
2----希尔排序
3----冒泡排序
4----快速排序
5----选择排序
6----堆排序
7----归并排序
8----退出
7
953 894 587 224 435 417
224 417 435 587 894 953

主菜单
1----插入排序
2----希尔排序
3----冒泡排序
4----快速排序
5----选择排序
6----堆排序
7----归并排序
8----退出

猜你喜欢

转载自blog.csdn.net/zavay/article/details/112358884