内部排序性能分析演示程序

(1)问题描述
分别采用直接插入排序、希尔排序、简单选择排序、堆排序、冒泡排序、快速排序、归并排序算法进行排序,并对比较次数与移动次数进行比较。
(2)功能与界面要求
对随机序列、正序和逆序的进行上述各种排序算法的比较测试和分析。
待排序的记录不从键盘输入。随机序列应该是随机生成的 1—N 之间的 n 个整数。
要求设置菜单,在菜单提示下,输入 1-7 之间的整数,选择某一种排序方法进行排序,
输入 8,进行统计分析(比较上述 7 种内部排序算法的关键字比较次数和移动次数,以
取得直观感受),输入 0,则退出。
归并排序算法要求用递归的分治算法实现。
当选择功能 1-7 时:
输入:待排序元素个数 n,输入 m(关键字取值范围为 1-m)。
输出:输出自动生成的 n 个整数的初始序列。
输出排序后的序列。
输出初态分别是随机序列、正序和逆序时的比较次数、移动次数。
当选择功能 8 时:
输入:无。
n 不需要输入,在 1000-3000 之间随机产生,m 也不需要输入,表中关键字在 100-300 之
间随机产生。
至少用 5 组不同数据作比较。
比较指标有:关键字参加比较次数和关键字的移动次数。
(关键字交换记为 3 次移动)。
输出:显示比较结果。
代码如下

#include<bits/stdc++.h>
using namespace std;

#define Maxsize 10000+1
typedef int KeyType;

int mov;      //移动次数
int com;      //比较次数
int Light = 1; //控制输入

typedef struct{
    KeyType key;//关键字
}RedType;
typedef struct{
    RedType r[Maxsize];//r[0]是暂存单元,不是哨兵;
    int Length;//顺序表长度
}SqList;

//菜单
void manu();
void manu1();

// 插入排序
void InserSort(int a[],int N);

// 选择排序
void SelectSort(int a[],int N);

// 冒泡排序
void bubble_sort(int* arr, int len);

// 快速排序
void QSort(int low,int high,KeyType arr[]);

// 归并排序
void Merge(KeyType R[],KeyType T[],int low,int mid,int high);
void MSort(KeyType R[],KeyType T[],int low,int high);
void MergeSort(KeyType arr[],int n);

// 堆排序
void HeapAdjust(SqList &L,int s,int m);//调整堆,假设r[s+1..m]已经是堆,则将r[s..m]调整r[s]为根的堆
void BuildHeap(SqList &L); //建立堆
void HeapSort(SqList &L); //堆排序
void Paixu(SqList &L);

// 希尔排序
void ShellInsert(SqList &L,int dk);
void ShellSort(SqList &L,int dt[],int t);

//初始化数组,产生随机序列
void InitArr(int arr[],int n,int m);
void CreatSq(SqList &L,int n,int m);
void CreatSq(SqList &L,int n);


// 逆置函数
void NiZhi(KeyType arr[],int n);
void Nizhi(SqList &L);

// 清空数组
void ClearList(SqList &L);

int main(){
    int choose,flag = 1;
    int arr[Maxsize];
    int n,m;
    while(flag){
        if(Light){
            system("cls");
            manu();
        }
        cout<<"请选择排序方法:";
        cin>>choose;
        if(choose == 8)
            Light = 0;
        switch(choose){
            case 1:{
                mov = 0,com = 0;
                if(Light){
                    cout<<"请分别输入数据个数和范围:";
                    cin>>n>>m;
                }
                InitArr(arr,n,m);
                cout<<"排序前序列:"<<endl;
                for(int i = 1;i <= n;i++)
                    cout<<arr[i]<<" ";
                cout<<endl;
                cout<<"排序后序列:"<<endl;
                InserSort(arr,n);
                for(int i = 1;i <= n;i++)
                    cout<<arr[i]<<" ";
                cout<<endl;
                cout<<"---------------------------------"<<endl;
                cout<<"初态为随机序列"<<endl;
                cout<<"比较次数:"<<com<<endl;
                cout<<"移动次数:"<<mov<<endl;
                cout<<"---------------------------------"<<endl;
                mov = 0,com = 0;
                InserSort(arr,n);
                cout<<"初态为正序"<<endl;
                cout<<"比较次数:"<<com<<endl;
                cout<<"移动次数:"<<mov<<endl;
                cout<<"---------------------------------"<<endl;
                mov = 0,com = 0;
                NiZhi(arr,n);
                InserSort(arr,n);
                cout<<"初态为逆序"<<endl;
                cout<<"比较次数:"<<com<<endl;
                cout<<"移动次数:"<<mov<<endl;
                system("pause");
                Light = 1;

                break;
            }
            case 2:{
                mov = 0,com = 0;
                if(Light){
                    cout<<"请分别输入数据个数和范围:";
                    cin>>n>>m;
                }
                InitArr(arr,n,m);
                cout<<"排序前序列:"<<endl;
                for(int i = 1;i <= n;i++)
                    cout<<arr[i]<<" ";
                cout<<endl;
                cout<<"排序后序列:"<<endl;
                SelectSort(arr,n);
                for(int i = 1;i <= n;i++)
                    cout<<arr[i]<<" ";
                cout<<endl;
                cout<<"---------------------------------"<<endl;
                cout<<"初态为随机序列"<<endl;
                cout<<"比较次数:"<<com<<endl;
                cout<<"移动次数:"<<mov<<endl;
                cout<<"---------------------------------"<<endl;
                mov = 0,com = 0;
                SelectSort(arr,n);
                cout<<"初态为正序"<<endl;
                cout<<"比较次数:"<<com<<endl;
                cout<<"移动次数:"<<mov<<endl;
                cout<<"---------------------------------"<<endl;
                mov = 0,com = 0;
                NiZhi(arr,n);
                SelectSort(arr,n);
                cout<<"初态为逆序"<<endl;
                cout<<"比较次数:"<<com<<endl;
                cout<<"移动次数:"<<mov<<endl;

                Light = 1;
                system("pause");
                break;
            }
            case 3:{
                mov = 0,com = 0;
                if(Light){
                    cout<<"请分别输入数据个数和范围:";
                    cin>>n>>m;
                }
                InitArr(arr,n,m);
                cout<<"排序前序列:"<<endl;
                for(int i = 1;i <= n;i++)
                    cout<<arr[i]<<" ";
                cout<<endl;
                cout<<"排序后序列:"<<endl;
                bubble_sort(arr,n);
                for(int i = 1;i <= n;i++)
                    cout<<arr[i]<<" ";
                cout<<endl;
                cout<<"---------------------------------"<<endl;
                cout<<"初态为随机序列"<<endl;
                cout<<"比较次数:"<<com<<endl;
                cout<<"移动次数:"<<mov<<endl;
                cout<<"---------------------------------"<<endl;
                mov = 0,com = 0;
                bubble_sort(arr,n);
                cout<<"初态为正序"<<endl;
                cout<<"比较次数:"<<com<<endl;
                cout<<"移动次数:"<<mov<<endl;
                cout<<"---------------------------------"<<endl;
                mov = 0,com = 0;
                NiZhi(arr,n);
                bubble_sort(arr,n);
                cout<<"初态为逆序"<<endl;
                cout<<"比较次数:"<<com<<endl;
                cout<<"移动次数:"<<mov<<endl;

                Light = 1;
                system("pause");
                break;
            }
            case 4: {
                mov = 0,com = 0;
                if(Light){
                    cout<<"请分别输入数据个数和范围:";
                    cin>>n>>m;
                }
                InitArr(arr,n,m);
                cout<<"排序前序列:"<<endl;
                for(int i = 1;i <= n;i++)
                    cout<<arr[i]<<" ";
                cout<<endl;
                cout<<"排序后序列:"<<endl;
                QSort(1,n,arr);
                for(int i = 1;i <= n;i++)
                    cout<<arr[i]<<" ";
                cout<<endl;
                cout<<"---------------------------------"<<endl;
                cout<<"初态为随机序列"<<endl;
                cout<<"比较次数:"<<com<<endl;
                cout<<"移动次数:"<<mov<<endl;
                cout<<"---------------------------------"<<endl;
                mov = 0,com = 0;
                QSort(1,n,arr);
                cout<<"初态为正序"<<endl;
                cout<<"比较次数:"<<com<<endl;
                cout<<"移动次数:"<<mov<<endl;
                cout<<"---------------------------------"<<endl;
                mov = 0,com = 0;
                NiZhi(arr,n);
                QSort(1,n,arr);
                cout<<"初态为逆序"<<endl;
                cout<<"比较次数:"<<com<<endl;
                cout<<"移动次数:"<<mov<<endl;

                Light = 1;
                system("pause");
                break;
            }
            case 5: {
                mov = 0,com = 0;
                if(Light){
                    cout<<"请分别输入数据个数和范围:";
                    cin>>n>>m;
                }
                InitArr(arr,n,m);
                cout<<"排序前序列:"<<endl;
                for(int i = 1;i <= n;i++)
                    cout<<arr[i]<<" ";
                cout<<endl;
                cout<<"排序后序列:"<<endl;
                MergeSort(arr,n);
                for(int i = 1;i <= n;i++)
                    cout<<arr[i]<<" ";
                cout<<endl;
                cout<<"---------------------------------"<<endl;
                cout<<"初态为随机序列"<<endl;
                cout<<"比较次数:"<<com<<endl;
                cout<<"移动次数:"<<mov<<endl;
                cout<<"---------------------------------"<<endl;
                mov = 0,com = 0;
                MergeSort(arr,n);
                cout<<"初态为正序"<<endl;
                cout<<"比较次数:"<<com<<endl;
                cout<<"移动次数:"<<mov<<endl;
                cout<<"---------------------------------"<<endl;
                mov = 0,com = 0;
                NiZhi(arr,n);
                MergeSort(arr,n);
                cout<<"初态为逆序"<<endl;
                cout<<"比较次数:"<<com<<endl;
                cout<<"移动次数:"<<mov<<endl;

                Light = 1;
                system("pause");
                break;
            }
            case 6: {
                if(Light){
                    cout<<"请分别输入数据个数和范围:";
                    cin>>n>>m;
                }
                SqList L;
                com=0;
                mov=0;
                CreatSq(L,n,m);
                HeapSort(L);//堆排序
                cout<<"排序后的顺序"<<endl;
                for(int i=1;i<=n;i++)//输出堆排序后的顺序
                    cout<<L.r[i].key<<" ";
                cout<<endl;
                cout<<"---------------------------------"<<endl;
                cout<<"初态为随机序列"<<endl;
                cout<<"比较次数:"<<com<<endl;
                cout<<"移动次数:"<<mov<<endl;
                cout<<"---------------------------------"<<endl;
                com=0;
                mov=0;
                Paixu(L);
                HeapSort(L);//推排序
                cout<<"初态为正序"<<endl;
                cout<<"比较次数:"<<com<<endl;
                cout<<"移动次数:"<<mov<<endl;
                cout<<"---------------------------------"<<endl;
                com=0;
                mov=0;
                Nizhi(L);
                HeapSort(L);//堆排序
                cout<<"初态为逆序"<<endl;
                cout<<"比较次数:"<<com<<endl;
                cout<<"移动次数:"<<mov<<endl;

                ClearList(L);

                Light = 1;
                system("pause");
                break;
            }
            case 7: {
                SqList L;
                com=0;
                mov=0;
                int t,dt[t],a;
                if(Light){
                    cout<<"请分别输入数据个数和范围:";
                    cin>>n>>m;
                }
                cout<<"输入t,增量序列的每个增量a:"<<endl;
                cin>>t;
                for(int i=0;i<t;i++){
                    cin>>a;
                    dt[i]=a;
                }
                CreatSq(L,n,m);
                ShellSort(L,dt,t);
                cout<<"排序后序列:"<<endl;
                for(int i=1;i<=n;i++)
                    cout<<L.r[i].key<<" ";
                cout<<endl;
                cout<<"---------------------------------"<<endl;
                cout<<"初态为随机序列"<<endl;
                cout<<"比较次数:"<<com<<endl;
                cout<<"移动次数:"<<mov<<endl;
                cout<<"---------------------------------"<<endl;
                mov=0;
                com=0;
                ShellSort(L,dt,t);
                cout<<"初态为正序"<<endl;
                cout<<"比较次数:"<<com<<endl;
                cout<<"移动次数:"<<mov<<endl;
                cout<<"---------------------------------"<<endl;
                mov=0;
                com=0;
                Nizhi(L);
                ShellSort(L,dt,t);
                cout<<"初态为逆序"<<endl;
                cout<<"比较次数:"<<com<<endl;
                cout<<"移动次数:"<<mov<<endl;
                Light = 1;
                system("pause");
                break;
            }
            case 8:{
                mov = 0,com = 0;
                n = rand()%2000 + 1000;
                m = 201;
                system("cls");
                manu1();
                Light = 0;
                break;
            }
            default:
                cout<<"请重新输入!"<<endl;
                system("pause");
                break;
        }
    }
}

void manu(){
    cout<<"*************************************************"<<endl;
    cout<<"*                1. 插入排序                    *"<<endl;
    cout<<"*                2. 选择排序                    *"<<endl;
    cout<<"*                3. 冒泡排序                    *"<<endl;
    cout<<"*                4. 快速排序                    *"<<endl;
    cout<<"*                5. 归并排序                    *"<<endl;
    cout<<"*                6. 堆排序                      *"<<endl;
    cout<<"*                7. 希尔排序                    *"<<endl;
    cout<<"*                8. 无输入                      *"<<endl;
    cout<<"*************************************************"<<endl;
}

void manu1(){
    cout<<"*************************************************"<<endl;
    cout<<"*                1. 插入排序                    *"<<endl;
    cout<<"*                2. 选择排序                    *"<<endl;
    cout<<"*                3. 冒泡排序                    *"<<endl;
    cout<<"*                4. 快速排序                    *"<<endl;
    cout<<"*                5. 归并排序                    *"<<endl;
    cout<<"*                6. 堆排序                      *"<<endl;
    cout<<"*                7. 希尔排序                    *"<<endl;
    cout<<"*************************************************"<<endl;
}


// -------------------------------------------------------------------------------------------------------
// 插入排序

void InserSort(int a[],int N){
	int j;
	for(int i=2;i<=N;i++){
		int t=a[i];
		for(j=i-1;j>=1&&t<a[j];j--){
			a[j+1]=a[j];
            com++;
            mov++;
        }
        com++;
		a[j+1]=t;
	}
}

// -------------------------------------------------------------------------------------------------------
// 选择排序

void SelectSort(int a[],int N){
    int i,j,temp;
    for(i=1;i<=N-1;i++){
        for(j=i+1;j<=N;j++){
            if(a[i]>a[j]){
                temp=a[i];
                a[i]=a[j];
                a[j]=temp;
                mov += 3;
            }
            com++;
        }
    }
}

// -------------------------------------------------------------------------------------------------------
// 冒泡排序

void bubble_sort(int* arr, int len)
{
	for (int i = len - 1; i >= 1; i--){
		for (int j = 1; j <= i; j++){
            if (arr[j] > arr[j + 1]){
				int t = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = t;
        		mov += 3;
			}
        com++;
		}
	}
}

// -------------------------------------------------------------------------------------------------------
// 快速排序

void QSort(int low,int high,KeyType arr[]){
    if(low >= high)
        return;
    int i,j,base,temp;
    i = low,j = high;
    base = arr[low];
    while(i < j){
        while(arr[j] >= base && i < j){
            com++;
            j--;
        }
        while(arr[i] <= base && i < j){
            com++;
            i++;
        }
        if(i < j){
            temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
            mov += 3;
        }
        com++;
    }
    //基准数归位
    arr[low] = arr[i];
    arr[i] = base;
    mov += 2;
    QSort(low,i-1,arr); //递归左边
    QSort(i+1,high,arr);  //递归右边
}

// -------------------------------------------------------------------------------------------------------
// 归并排序

void Merge(KeyType R[],KeyType T[],int low,int mid,int high){
    int i = low;
    int j = mid + 1;
    int k = low;
    while(i <= mid && j <= high){
        if(R[i] <= R[j])
            T[k++]=R[i++];
        else
            T[k++] = R[j++];
        mov++;
        com++;
    }   
    while(i<=mid){
        T[k++]=R[i++];
        mov++;
    }
    while(j<=high){
        T[k++]=R[j++];
        mov++;
    }
}

void MSort(KeyType R[],KeyType T[],int low,int high){
    int mid;
    int S[Maxsize];
    if(low == high)
        T[low] = R[low];
    else{
        mid = (low+high)/2;
        MSort(R,S,low,mid);
        MSort(R,S,mid+1,high);
        Merge(S,T,low,mid,high);
    }
}

void MergeSort(KeyType arr[],int n){
    MSort(arr,arr,1,n);
}

// -------------------------------------------------------------------------------------------------------
// 堆排序

void HeapAdjust(SqList &L,int s,int m)
{
    RedType rc;
    rc=L.r[s];
    mov++;
    for(int j=2*s;j<=m;j*=2)//沿着key较大的孩子结点向下筛选
    {
        com+=2;
        if(j<m&&L.r[j].key<L.r[j+1].key) ++j;//j 为 key 较大的记录下标
        if(rc.key>=L.r[j].key) break; //rc应插在位置s上
        L.r[s]=L.r[j];
        mov++;
        s=j;
    }
    mov++;
    L.r[s]=rc;//交换
}

void BuildHeap(SqList &L)
{
    int n;
    n=L.Length;
    for(int i=n/2;i>0;i--)
    {
        HeapAdjust(L,i,n);
    }
}

void HeapSort(SqList &L)
{
    RedType x;
    BuildHeap(L);
    for(int i=L.Length;i>1;--i)
    {
        x=L.r[1];//将堆顶记录和当前未经排序的子序列L.[1...i]中最后一个记录交换
        L.r[1]=L.r[i];
        L.r[i]=x;
        mov+=3;
        HeapAdjust(L,1,i-1);//将L.r[1...i-1]重新调整为大根堆
    }
}

void Paixu(SqList &L){
    int m=L.Length-1;
    int flag=1;
    while((m>0)&&(flag==1)){
        flag=0;
        for(int j=0;j<=m;j++){
            if(L.r[j].key>L.r[j+1].key){
                RedType t;
                flag=1;
                t=L.r[j];
                L.r[j]=L.r[j+1];
                L.r[j+1]=t;
            }
        }
    }
}

// -------------------------------------------------------------------------------------------------------
// 希尔排序

void ShellInsert(SqList &L,int dk){
    for(int i=dk+1;i<=L.Length;++i){
        if(L.r[i].key<L.r[i-dk].key){
            L.r[0]=L.r[i];
            int j;
            for(j=i-dk;j>0&&L.r[0].key<L.r[j].key;j-=dk){
                L.r[j+dk]=L.r[j];
                mov++;
            }

            L.r[j+dk]=L.r[0];
        }
        com++;
    }
    com++;
}

void ShellSort(SqList &L,int dt[],int t)
{//按增量序列·dt[0..t-1]对顺序表L作t趟希尔排序
    for(int k=0;k<t;++k)
        ShellInsert(L,dt[k]);

}

// -------------------------------------------------------------------------------------------------------
// 其他函数

void InitArr(int arr[],int n,int m){
    if(Light)
        for(int i = 1;i <= n;i++)
            arr[i] = rand()%m + 1;
    else
        for(int i = 1;i <= n;i++)
            arr[i] = rand()%200 + 100;
}

void CreatSq(SqList &L,int n,int m){
    L.Length=n;
    srand((int)time(NULL));
    for(int i=1;i<=n;i++){
        L.r[i].key=rand()%m+1;
        for(int j=1;j<i;j++){
            if(Light)
                L.r[i].key=rand()%m+1;
            else
                L.r[i].key=rand()%m+100;
        }
    }
    cout<<"排序前序列: "<<endl;
    for(int i=1;i<=n;i++)
        cout<<L.r[i].key<<" ";
    cout<<endl;
}

void CreatSq(SqList &L,int n){
    L.Length=n;
    cout<<"请输入推排序,关键字取值范围\n1:100\n2:1000\n3:10000"<<endl;
    srand((int)time(NULL));
    int i,t;
    cin>>t;
    for(i=1;i<=n;i++){
        if(t==1)
            L.r[i].key=rand()%100;
        if(t==2)
            L.r[i].key=rand()%1000;
        if(t==3)
            L.r[i].key=rand()%10000;
    }
    cout<<"输出随机顺序"<<endl;
    for(i=1;i<=n;i++)
        cout<<L.r[i].key<<" ";
    cout<<endl;
}

void NiZhi(KeyType arr[],int n){
    int l = n/2;
    int t;
    for(int i = 1;i<=l;i++){
        t = arr[i];
        arr[i] = arr[n-i+1];
        arr[n-i+1] = t;
    }
}

void Nizhi(SqList &L){
    RedType t;
    int q=L.Length/2;
    for(int i=1;i<=q;i++){
        t=L.r[i];
        L.r[i]=L.r[L.Length-i+1];
        L.r[L.Length-i+1]=t;
    }
}

void ClearList(SqList &L){
    L.Length=0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值