数据结构课程设计之排序综合

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_39360985/article/details/78967258

题目:

实现功能:
利用随机函数产生N个随机整数(20000以上),对这些数进行多种方法进行排序。
要求:
1) 至少采用三种方法实现上述问题求解(提示,可采用的方法有插入排序、希尔排序、起泡排序、快速排序、选择排序、堆排序、归并排序)。并把排序后的结果保存在不同的文件中。
2) 统计每一种排序方法的性能(以上机运行程序所花费的时间为准进行对比),找出其中两种较快的方法。
3) 如果采用4种或4种以上的方法者,可适当加分。

利用随机函数产生30000个随机数,并将这些数存入txt文件中的代码如下:

#define N 30000
void write()     //随机产生30000个数,并将这些数存放在data.txt文件中
{
    FILE* fp=fopen("data0.txt","w");
    for(int i=1;i<=N;i++)
    {
        fprintf(fp,"%d ",rand());
        if(i%10==0)
            fprintf(fp,"\n");
    }
    fclose(fp);
}

从文件中读取数据,并且输出的代码如下:

//从文件中读入数据存入数组a
int readData(int a[], int n,char *f )  //函数返回成功读入放入数据个数
{
    FILE *fp;
    int i;
    fp=fopen(f,"r");
    if (fp==NULL){
        fclose(fp);
        return 0;
    }
    else
    {
        for (i=0; i<n && !feof(fp); i++)
            fscanf(fp,"%d",&a[i]);
        fclose(fp);
        return i;
    }
}

void output(int a[],int n) //输出数组的内容
{
    int i;
    printf("原数组的内容是:");
    for (i=0; i<n; i++)
    {
        if (i%10==0)
            printf("\n");
        printf("%7d",a[i]);
    }
    printf("\n");
}

各种排序算法可以看下我之前发表的博客;

计算各算法的时间消耗的代码,以选择排序算法为例,如下:

#include <time.h>
 double time1;
 clock_t start,finish;
 start=clock();
 SelectSort(a,N);
 finish=clock();
 time1=(double)(finish-start)/CLOCKS_PER_SEC;
 cout<<"选择排序的耗时:"<<time1<<"秒"<<endl;

将各种排序算法的结果存入txt文件中的代码,以选择排序为例,如下:

SelectSort(a,N);
FILE* fp1;
fp1=fopen("data1.txt","w");
for(int i=0;i<N;i++)
{
    fprintf(fp1,"%d \t",a[i]);
}
fclose(fp1);

整体代码如下:(水平低,仅供参考)

无堆排序的原因是堆排序读取的数组第一个数据无作用,为了课设结果的整体性所以去掉,堆排序可以参考之前我发表的博客;

#include <iostream>
#include <stdio.h>
#include <fstream>
#include <stdlib.h>
#include <string.h>
#include <time.h>
using namespace std;

#define N 30000

void write()     //随机产生30000个数,并将这些数存放在data.txt文件中
{
    FILE* fp=fopen("data0.txt","w");
    for(int i=1;i<=N;i++)
    {
        fprintf(fp,"%d ",rand());
        if(i%10==0)
            fprintf(fp,"\n");
    }
    fclose(fp);
}

//从文件中读入数据存入数组a
int readData(int a[], int n,char *f )  //函数返回成功读入放入数据个数
{
    FILE *fp;
    int i;
    fp=fopen(f,"r");
    if (fp==NULL){
        fclose(fp);
        return 0;
    }
    else
    {
        for (i=0; i<n && !feof(fp); i++)
            fscanf(fp,"%d",&a[i]);
        fclose(fp);
        return i;
    }
}

void output(int a[],int n) //输出数组的内容
{
    int i;
    printf("原数组的内容是:");
    for (i=0; i<n; i++)
    {
        if (i%10==0)
            printf("\n");
        printf("%7d",a[i]);
    }
    printf("\n");
}

void SelectSort(int a[],int n) //选择排序
{
    int mix,temp;
    for(int i=0;i<n-1;i++) //每次循环数组,找出最小的元素,放在前面,前面的即为排序好的
    {
        mix=i; //假设最小元素的下标
        for(int j=i+1;j<n;j++) //将上面假设的最小元素与数组比较,交换出最小的元素的下标
            if(a[j]<a[mix])
                mix=j;
        //若数组中真的有比假设的元素还小,就交换
        if(i!=mix)
        {
            temp=a[i];
            a[i]=a[mix];
            a[mix]=temp;
        }
    }
}

void bubleSort(int a[],int n)//冒泡排序
{
    int temp;
    //运用两个for循环,每次取出一个元素跟数组的其它元素比较,将最大的元素排到最后
    for(int i=0;i<n-1;i++)
    {
        //外循环一次,就排好一个数,并放在后面,所以比较前面n-i-1个元素即可
        for(int j=0;j<n-i-1;j++)
        {
            if(a[j]>a[j+1])
            {
                temp=a[j];
                a[j]=a[j+1];
                a[j+1]=temp;
            }
        }
    }
}

void bInsertSort(int a[],int n) //插入排序
{
    int low,high,mid;
    int temp;
    for(int i=1;i<n;i++)
    {
        low=0;
        //把a[i]元素插入到它的前面a[0--(n-1)]中
        temp=a[i];
        high=i-1;
        while(low<=high) //该while是折半优化算法,缩小a[i]的范围
        {
            mid=(low+high)/2;
            if(a[mid]>temp)
                high=mid-1;
            else
                low=mid+1;
        }
        int j=i;
        while((j>low)&&(a[j-1]>temp)) //让a与已经排好的数组的各元素比较,小的放前面
        {
            a[j]=a[j-1];
            --j;
        }
        a[low]=temp;
    }
}

int findPos(int a[],int low,int high)
{
    //将小于t的元素赶到t的左边,大于t的元素赶到t的右边
    int t=a[low];
    while(low<high)
    {
        while(low<high && a[high]>=t)
            high--;
        a[low]=a[high];
        while(low<high && a[low]<=t)
            low++;
        a[high]=a[low];
    }
    a[low]=t;
    //返回此时t在数组中的位置
    return low;
}

//在数组中找一个元素,对于大于该元素和小于该元素的两个数组进行再排序,
//再对两个数组分为4个数组,再排序,直到最后每组只剩下一个元素为止
void quickSort(int a[],int low,int high) //快速排序
{
    if(low>high)
        return ;
    int pos=findPos(a, low, high);
    quickSort(a, low, pos-1);
    quickSort(a, pos+1, high);
}

void shellSort(int *a,int n) //希尔排序
{
    int key,j;
    for(int step=n/2;step>0;step/=2) //将数组按照step分组,不断二分到每组只剩下一个元素
    {
        for(int i=step;i<n;i++) //将每组中的元素排序,小的在前面
        {
            key=a[i];
            for(j=i-step;j>=0 && key<a[j];j-=step)
            {
                a[j+step]=a[j];
            }
            a[j+step]=key; //和上面的for循环一起,将组中小的元素换到数组的前面
        }
    }
}


void merge(int a[],int low,int mid,int high)
{
    int i,k;
    //定义一个临时数组存放传进来的无序数组排好序之后的数组
    int *temp=(int *)malloc((high-low+1)*sizeof(int));
    //将无序数组分成两个序列
    int left_low=low;
    int left_high=mid;
    int right_low=mid+1;
    int right_high=high;
    //将两个序列比较排序,小的排前
    for(k=0;left_low<=left_high && right_low<=right_high;k++)
    {
        if(a[left_low]<=a[right_low])
            temp[k]=a[left_low++];
        else
            temp[k]=a[right_low++];
    }
    //左序列如果有剩下元素未排序,加到临时数组的末尾
    if(left_low<=left_high)
    {
        for(i=left_low;i<=left_high;i++)
            temp[k++]=a[i];
    }
    //右序列如果有剩下元素未排序,加到临时数组的末尾
    if(right_low<=right_high)
    {
        for(i=right_low;i<=right_high;i++)
            temp[k++]=a[i];
    }
    //将排好序的小分组转移到原数组中
    for(i=0;i<high-low+1;i++)
    {
        a[low+i]=temp[i];
    }
    free(temp);
}

void mergeSort(int a[],int first,int last)//归并排序
{
    int mid=0;
    //将数组不停的二分分组再组合,直到每组只剩下一个元素
    if(first<last)
    {
        mid=(first+last)/2;
        mergeSort(a, first, mid);
        mergeSort(a, mid+1, last);
        merge(a,first,mid,last);
    }
}

//该函数的作用是找出num的pos位数的数字(比如:23的个位数数字是3)
int getNumPos(int num,int pos)
{
    int i;
    int temp=1;
    for(i=0;i<pos-1;i++)
        temp*=10;
    return (num/temp)%10;
}

void radixSort(int a[],int n) //基数排序
{
    int i,j,k,pos,num,index;
    //这几句话是创建一个从0-9(行)× (n+1)(列)的网格,第一列从上往下是0-9,第二列是该行包含的元素个数,默认为0个
    int *radixArrays[10];
    for(i=0;i<10;i++)
    {
        radixArrays[i]=(int *)malloc(sizeof(int)*(n+1));
        radixArrays[i][0]=0;
    }
    //pos最大为31为数,计算机能承受的最大范围了
    for(pos=1;pos<=31;pos++)
    {
        //该for循环是将数组的元素按照位数(pos)的值放进网格内
        for(i=0;i<n;i++)
        {
            num=getNumPos(a[i], pos);
            index=++radixArrays[num][0];
            radixArrays[num][index]=a[i];
        }
        //该for循环是将上面的for循环已经按照某个位数(pos)排列好的元素存入数组
        for(i=0,j=0;i<10;i++)
        {
            for(k=1;k<=radixArrays[i][0];k++)
                a[j++]=radixArrays[i][k];
            //清空网格,以便给下个位数排列
            radixArrays[i][0]=0;
        }
    }
}


int main()
{
    write();
    int n,a[N];
    n=readData(a,N,"data0.txt");
    output(a,n);

    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;
    cout<<"请输入你的选择:"<<endl;

    double time1,time2,time3,time4,time5,time6,time7;
    clock_t start,finish;

    char c=getchar();
    switch(c)
    {
        case '1':
            cout<<"选择排序:"<<endl;
            start=clock();
            SelectSort(a,N);
            finish=clock();
            time1=(double)(finish-start)/CLOCKS_PER_SEC;
            for(int i=0;i<N;i++)
                cout<<a[i]<<" "<<"\t";
            cout<<endl;
            cout<<"选择排序的耗时:"<<time1<<"秒"<<endl;
            FILE* fp1;
            fp1=fopen("data1.txt","w");
            for(int i=0;i<N;i++)
            {
                fprintf(fp1,"%d \t",a[i]);
            }
            fclose(fp1);
            break;
        case '2':
            cout<<"冒泡排序:"<<endl;
            start=clock();
            bubleSort(a,N);
            finish=clock();
            time2=(double)(finish-start)/CLOCKS_PER_SEC;
            for(int i=0;i<N;i++)
                cout<<a[i]<<" "<<"\t";
            cout<<endl;
            cout<<"冒泡排序的耗时:"<<time2<<"秒"<<endl;
            FILE* fp2;
            fp2=fopen("data2.txt","w");
            for(int i=0;i<N;i++)
            {
                fprintf(fp2,"%d \t",a[i]);
            }
            fclose(fp2);
            break;
        case '3':
            cout<<"插入排序:"<<endl;
            start=clock();
            bInsertSort(a,N);
            finish=clock();
            time3=(double)(finish-start)/CLOCKS_PER_SEC;
            for(int i=0;i<N;i++)
                cout<<a[i]<<" "<<"\t";
            cout<<endl;
            cout<<"插入排序的耗时:"<<time3<<"秒"<<endl;
            FILE* fp3;
            fp3=fopen("data3.txt","w");
            for(int i=0;i<N;i++)
            {
                fprintf(fp3,"%d \t",a[i]);
            }
            fclose(fp3);
            break;
        case '4':
            cout<<"快速排序:"<<endl;
            start=clock();
            quickSort(a, 0, N-1);
            finish=clock();
            time4=(double)(finish-start)/CLOCKS_PER_SEC;
            for(int i=0;i<N;i++)
                cout<<a[i]<<" "<<"\t";
            cout<<endl;
            cout<<"快速排序的耗时:"<<time4<<"秒"<<endl;
            FILE* fp4;
            fp4=fopen("data4.txt","w");
            for(int i=0;i<N;i++)
            {
                fprintf(fp4,"%d \t",a[i]);
            }
            fclose(fp4);
            break;
        case '5':
            cout<<"希尔排序:"<<endl;
            start=clock();
            shellSort(a, N);
            finish=clock();
            time5=(double)(finish-start)/CLOCKS_PER_SEC;
            for(int i=0;i<N;i++)
                cout<<a[i]<<" "<<"\t";
            cout<<endl;
            cout<<"希尔排序的耗时:"<<time5<<"秒"<<endl;
            FILE* fp5;
            fp5=fopen("data5.txt","w");
            for(int i=0;i<N;i++)
            {
                fprintf(fp5,"%d \t",a[i]);
            }
            fclose(fp5);
            break;
        case '6':
            cout<<"归并排序:"<<endl;
            start=clock();
            mergeSort(a, 0, N-1);
            finish=clock();
            time6=(double)(finish-start)/CLOCKS_PER_SEC;
            for(int i=0;i<N;i++)
                cout<<a[i]<<" "<<"\t";
            cout<<endl;
            cout<<"归并排序的耗时:"<<time6<<"秒"<<endl;
            FILE* fp6;
            fp6=fopen("data6.txt","w");
            for(int i=0;i<N;i++)
            {
                fprintf(fp6,"%d \t",a[i]);
            }
            fclose(fp6);
            break;
        case '7':
            cout<<"基数排序:"<<endl;
            start=clock();
            radixSort(a, N);
            finish=clock();
            time7=(double)(finish-start)/CLOCKS_PER_SEC;
            for(int i=0;i<N;i++)
                cout<<a[i]<<" "<<"\t";
            cout<<endl;
            cout<<"基数排序的耗时:"<<time7<<"秒"<<endl;
            FILE* fp7;
            fp7=fopen("data7.txt","w");
            for(int i=0;i<N;i++)
            {
                fprintf(fp7,"%d \t",a[i]);
            }
            fclose(fp7);
            break;
        default:
            cout<<"输入错误!请重新输入!";
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_39360985/article/details/78967258
今日推荐