zoukankan      html  css  js  c++  java
  • 两种多关键字排序代码

    #include<iostream>
    #include<iomanip>
    #include<ctime>
    #include<fstream>
    #include<string>
    
    #define radix 10
    
    using namespace std;
    
    clock_t start,stop;
    
    //学生的结构体
    typedef struct SNode{
        string name;
        int ID;             //学号
        int key[4]={0};     //成绩
        struct SNode *next;    //指针域
    }SNode,*Student;
    
    void StudentGrade(int n);     //生成学生成绩信息文件new.txt,n为文件读取数据的组数
    
    Student CreatStudent_old(Student &L,int num);   //读取old.txt,尾插法建立学生成绩单链表L,num为总人数
    
    Student CreatStudent_new(Student &L,int num);   //读取new.txt,尾插法建立学生成绩单链表L,num为总人数
    
    Student BubbleSort(Student &L,int order[]);  //MSD冒泡排序,L为学生成绩链表,order[]为用户输入的次关键字顺序
    
    Student RadixSort(Student &L,int order[]);   //LSD基数排序,L为学生成绩链表,order[]为次关键字顺序
    
    void Print(Student &L);     //在屏幕上显示
    
    void choose(Student &L);    //选择功能
    
    void Menu();    //菜单
    
    int main(){
        ofstream fout;
        fout.open("C:\Out.txt",ios::app);
        if(!fout){
            cout<<"无法打开文件!!!"<<endl;
        }
        int a;
        do{
          Menu();   //调用菜单
          cout<<"   输入0结束,输入其他则可重新生成成绩再进行排序";
          cin>>a;
          fout<<"   输入0结束,输入其他则可重新生成成绩再进行排序"<<a;
        }while(a!=0) ;  //a等于0停止循环
    
        return 0;
    }
    
    //菜单
    void Menu(){
        ofstream fout;
        fout.open("C:\Out.txt",ios::app);
        if(!fout){
            cout<<"无法打开文件!!!"<<endl;
        }
        cout<<endl;
        cout<<endl;
        cout<<"   --------------------------------------------------"<<endl;
        cout<<"   |------------------学生成绩排序------------------|"<<endl;
        cout<<"   |                                                |"<<endl;
        cout<<"   |   本程序可以按关键字的优先关系排序对成绩排序。 |"<<endl;
        cout<<"   |                                                |"<<endl;
        cout<<"   |   学生成绩有两种方式产生                       |"<<endl;
        cout<<"   |   输入1:从old.txt文件中读取                   |"<<endl;
        cout<<"   |   输入2:随机产生数据并导入new.txt文件中       |"<<endl;
        cout<<"   --------------------------------------------------"<<endl;
        cout<<endl;
    
        //输出到文件
        fout<<endl;
        fout<<endl;
        fout<<"   --------------------------------------------------"<<endl;
        fout<<"   ------------------学生成绩排序------------------"<<endl;
        fout<<"                                                   "<<endl;
        fout<<"      本程序可以按关键字的优先关系排序对成绩排序。  "<<endl;
        fout<<"                                                   "<<endl;
        fout<<"      学生成绩有两种方式产生                          "<<endl;
        fout<<"      输入1:从old.txt文件中读取                   "<<endl;
        fout<<"      输入2:随机产生数据并导入new.txt文件中       "<<endl;
        fout<<"   --------------------------------------------------"<<endl;
        fout<<endl;
    
        Student L;
        int a;
        cout<<"   选择产生成绩的方式:";
        cin>>a;
        cout<<endl;
        fout<<"   选择产生成绩的方式:"<<a<<endl;
        switch (a) {
        case 1:
            int n;
            cout<<"   从old.txt文件中读取多少组数据:";
            cin>>n;
            fout<<"   从old.txt文件中读取多少组数据:"<<n<<endl;
            CreatStudent_old(L,n);    //调用函数创建学生成绩单链表
            break;
        case 2:
            int m;
            cout<<"   需要随机产生多少组数据:";
            cin>>m;
            fout<<"   需要随机产生多少组数据:"<<m<<endl;
            StudentGrade(m);
            CreatStudent_new(L,m);    //调用函数创建学生成绩单链表
            break;
        }
    
        Print(L);               //调用打印函数将生成的学生成绩信息打印在屏幕上
    
        int b;
        do{
            cout<<"   --------------------------------------------------"<<endl;
            cout<<"   |   请选择:                                     |"<<endl;
            cout<<"   |   1.MSD策略对数据进行冒泡法排序                |"<<endl;
            cout<<"   |   2.LSD策略对数据进行基数排序                  |"<<endl;
            cout<<"   --------------------------------------------------"<<endl;
    
            fout<<"   --------------------------------------------------"<<endl;
            fout<<"      请选择:                                     "<<endl;
            fout<<"      1.MSD策略对数据进行冒泡法排序                       "<<endl;
            fout<<"      2.LSD策略对数据进行基数排序                         "<<endl;
            fout<<"   --------------------------------------------------"<<endl;
            choose(L);      //调用选择函数,选择排序方式和排序次序
            cout<<"   输入0结束,输入其他数则继续进行此成绩的排序";
            cin>>b;
            cout<<endl;
            fout<<"   输入0结束,输入其他数则继续进行此成绩的排序"<<b<<endl;
        }while(b!=0);
    }
    
    //生成学生成绩信息文件new.txt,n为需要随机生成的数据组数
    void StudentGrade(int n){
        ofstream fout;
        fout.open("C:\new.txt",ios::out);
        if(!fout){
            cout<<"无法打开文件!!!"<<endl;
        }
        string name;    //姓名
        int id;         //学号
        int score[4];   //分数
        //随机产生数据并写入new中
        string studentname[10]={"a","b","c","d","e","f","g","h","i","j"};
        srand(time(0));
        for(int a=1;a<=n;a++){
            name=studentname[rand()%10] + studentname[rand()%10] + studentname[rand()%10];//对字进行随机组合生成姓名
            fout<<name<<" ";
            id=a;
            fout<<id<<" ";
            for(int c=0;c<=3;c++){  //初始化成绩
                score[c]=0;
            }
            for(int b=0;b<3;b++){
                score[b]=rand()%101;    //随机产生成绩
                fout<<score[b]<<" ";
                score[3]=score[3]+score[b]; //总分
            }
            fout<<score[3]<<endl;
        }
        fout.close();
    }
    
    //读取old.txt,尾插法建立学生成绩单链表L,num为人数
    Student CreatStudent_old(Student &L,int num){
        ifstream fin;
        fin.open("C:\old.txt",ios::in);
        if(!fin){
            cout<<"无法打开文件!!!"<<endl;
        }
        Student p,r;
        L=new SNode;
        L->next=NULL;   //创建带头结点的链表L
        r=L;            //尾指针指向头结点
        for(int i=1;i<=num;i++){
            p=new SNode;    //生成新结点
            fin>>p->name;   //读取姓名
            fin>>p->ID;     //读取学号
            for(int j=0;j<=3;j++){
                fin>>p->key[j];
            }
            p->next=NULL;
            r->next=p;   //将新结点p插入尾结点r之后
            r=p;        //r指向新的尾结点p
        }
        return L;
    }
    
    //读取new.txt里的数据,尾插法建立学生成绩单链表L,num为人数
    Student CreatStudent_new(Student &L,int num){
        ifstream fin;
        fin.open("C:\new.txt",ios::in);
        if(!fin){
            cout<<"无法打开文件!!!"<<endl;
        }
        Student p,r;
        L=new SNode;
        L->next=NULL;   //创建带头结点的链表L
        r=L;            //尾指针指向头结点
        for(int i=1;i<=num;i++){
            p=new SNode;    //生成新结点
            fin>>p->name;   //读取姓名
            fin>>p->ID;     //读取学号
            for(int j=0;j<=3;j++){
                fin>>p->key[j];
            }
            p->next=NULL;
            r->next=p;   //将新结点p插入尾结点r之后
            r=p;        //r指向新的尾结点p
        }
        return L;
    }
    
    //选择功能
    void choose(Student &L){
        ofstream fout;
        fout.open("C:\Out.txt",ios::app);
        if(!fout){
            cout<<"无法打开文件!!!"<<endl;
        }
        double time;    //排序时间
        cout<<"   ";
        fout<<"   ";
        int order[4];
        int a;
        cin>>a;
        fout<<a<<endl;
        cout<<"   --------------------------------------------------"<<endl;
        fout<<"   --------------------------------------------------"<<endl;
        switch (a) {
        case 1:
            cout<<"   输入次关键字比较顺序,0为语文,1为数学,2为英语,3为总分,总分默认第一个"<<endl;
            cout<<endl;
            fout<<"   输入次关键字比较顺序,0为语文,1为数学,2为英语,3为总分,总分默认第一个"<<endl;
            fout<<endl;
            for(int i=0;i<=3;i++){
                cout<<""<<i+1<<"个次序";
                cin>>order[i];
                cout<<endl;
                fout<<""<<i+1<<"个次序";
                fout<<order[i]<<endl;
            }
            start=clock();
            BubbleSort(L,order);      //调用冒泡排序
            stop=clock();
            time=(double)(stop-start)/CLK_TCK;
            Print(L);        //打印结果
            cout<<"   排序所用时间:"<<time<<endl;;
            fout<<"   排序所用时间:"<<time<<endl;
            break;
        case 2:
            cout<<"   输入次关键字比较顺序,0为语文,1为数学,2为英语,3为总分,总分默认第一个"<<endl;
            cout<<endl;
            fout<<"   输入次关键字比较顺序,0为语文,1为数学,2为英语,3为总分,总分默认第一个"<<endl;
            fout<<endl;
            for(int i=0;i<=3;i++){
                cout<<""<<i+1<<"个次序";
                cin>>order[i];
                cout<<endl;
                fout<<""<<i+1<<"个次序";
                fout<<order[i]<<endl;
            }
            start=clock();
            RadixSort(L,order);      //调用基数排序
            stop=clock();
            time=(double)(stop-start)/CLK_TCK;
            Print(L);
            cout<<"   排序所用时间:"<<time<<endl;
            fout<<"   排序所用时间:"<<time<<endl;
            break;
        default:
            cout<<"   选择不存在,请输入1或者2"<<endl;
            fout<<"   选择不存在,请输入1或者2"<<endl;
            break;
        }
    }
    
    //MSD冒泡排序,L为学生成绩链表,order[]为用户输入的次关键字顺序
    Student BubbleSort(Student &L,int order[]){
        int flag=1;         //标记,判断该趟排序是否发生交换
        Student p,q,t;
        while(flag==1){
            t=L;
            p=L->next;
            q=p->next;
            flag=0;
            while(q){
                int k1=order[0];
                if(p->key[k1]<q->key[k1]){     //交换数据域,指针域不变
                    flag=1;         //发生交换,flag变成1
                    p->next=q->next;
                    t->next=q;
                    q->next=p;
                    q=p->next;
                }
                else if(p->key[k1]==q->key[k1]){       //总分相等,比较第二次序
                    int k2=order[1];
                    if(p->key[k2]<q->key[k2]){
                        flag=1;
                        p->next=q->next;
                        t->next=q;
                        q->next=p;
                        q=p->next;
                    }
                    else if(p->key[k2]==q->key[k2]){     //第二次序相等,比较第三次序
                        int k3=order[2];
                        if(p->key[k3]<q->key[k3]){
                            flag=1;
                            p->next=q->next;
                            t->next=q;
                            q->next=p;
                            q=p->next;
                        }
                        if(p->key[k3]==q->key[k3]){     //第三次序相等,比较第四次序
                            int k4=order[3];
                            if(p->key[k4]<q->key[k4]){
                                flag=1;
                                p->next=q->next;
                                t->next=q;
                                q->next=p;
                                q=p->next;
                             }
                            else {
                                p=p->next;
                                q=q->next;
                            }
                         }//if(k2)
                        else {
                            p=p->next;
                            q=q->next;
                        }
                    }//if(k1)
                    else {
                        p=p->next;
                        q=q->next;
                    }
                }//if(3)
                else {
                    p=p->next;
                    q=q->next;
                }
                t=t->next;
            }//while
        }//while
        return L;
    }
    
    //LSD基数排序,L为学生成绩链表,order[]为次关键字顺序
    Student RadixSort(Student &L,int order[]){
        Student front[radix],end[radix],p,t;
        int m,k;
        for(int n=3;n>=0;n--){
            k=order[n];
            for(int d=1;d<=3;d++){      //位数
                for(int i=0;i<radix;i++){    //初始化各链队首尾指针
                    front[i]=end[i]=NULL;
                }
                p=L->next;
                while(p){
                    if(d==1){
                        m=p->key[k]%10; //第一趟取个位分配
                    }
                    else if(d==2){
                        m=(p->key[k]%100)/10;   //第二趟分配取十位
                    }
                    else{
                        m=p->key[k]/100;    //第三趟取百位分配
                    }
                    if(front[m]==NULL){     //采用尾插法建立单链表
                        front[m]=p;
                        end[m]=p;
                    }
                    else{
                        end[m]->next=p;
                        end[m]=p;
                    }
                    p=p->next;
                }//while
                L->next=NULL;
                for(int j=radix-1;j>=0;j--){    //对每一个链队从大到小进行收集
                    if(front[j]){
                        if(L->next==NULL){
                            L->next=front[j];   //L指向链队头
                            t=end[j];         //t指向队尾
                        }
                        else{
                            t->next=front[j];  //t->next指向下一个链队头
                            t=end[j];
                        }
                    }
                    t->next=NULL;          //最后一个结点指向空
                }//for
            }
        }
        return L;
    }
    
    //在屏幕上显示
    void Print(Student &L){
        ofstream fout;
        fout.open("C:\Out.txt",ios::app);
        if(!fout){
            cout<<"无法打开文件!!!"<<endl;
        }
        cout<<"   --------------------------------------------------"<<endl;
        cout<<setw(8)<<"姓名"<<setw(8)<<"学号"<<setw(8)<<"语文"<<setw(8)<<"数学"<<setw(8)<<"英语"<<setw(8)<<"总分"<<endl;
        fout<<"   --------------------------------------------------"<<endl;
        fout<<setw(8)<<"姓名"<<setw(8)<<"学号"<<setw(8)<<"语文"<<setw(8)<<"数学"<<setw(8)<<"英语"<<setw(8)<<"总分"<<endl;
        Student p;
        p=L->next;
        while(p){
            cout<<setw(8)<<p->name;
            cout<<setw(8)<<p->ID;
            fout<<setw(8)<<p->name;
            fout<<setw(8)<<p->ID;
            for(int i=0;i<4;i++){  //依次输出4个数据
                cout<<setw(8)<<p->key[i];
                fout<<setw(8)<<p->key[i];
            }
            cout<<endl;
            fout<<endl;
            p=p->next;
        }
        cout<<endl;
        fout<<endl;
    }
  • 相关阅读:
    决策树算法系列之一 ID3
    线性递归数列算法题
    Python爬虫快速上手教程
    gensim快速上手教程
    GCN和GCN在文本分类中应用
    命名实体如何进行概念消歧?
    浅谈神经网络中的激活函数
    nginx安装配置和基本使用
    netty学习总结(三)
    netty学习总结(二)
  • 原文地址:https://www.cnblogs.com/ZhangStudy/p/12492485.html
Copyright © 2011-2022 走看看