数据结构--排序算法汇总

 

#include

#include

#include

#include

#include

#include

#include

 

#define MAX 200                                                    // 数组元素的最大个数

 

typedef int datatype;                         

typedef struct                                                //定义记录为结构体类型

{

         int Date;                                                 //关键字域

         datatype other;                                             //其他域

}Key;

Key *s1,S[MAX];

 

class paixu                         //声明一个排序类

{

 public:

          paixu(){}                      //构造函数为空

          ~paixu(){}                     //析构函数为空

  void createA(int n);              //键盘输入数据

  void createB(int n);              //随机产生数据

  void createrandnum(int a[],int n);

  void frontdisplayList(Key L[], int n);//输出未排数据

  void reardisplayList(Key L[], int n); //输出已排数据

  void face1();                      //欢迎界面

  char choose();                     //选择数据产生方式

  void meun();                       //选择排序算法

  void face2();                      //欢迎推出界面

  void SelectSort(Key L[],int n);          //选择排序 

  void InsertSort(Key L[],int n);          //插入排序  

  void BubbleSort(Key L[],int n);          //冒泡排序

  void merge(Key L[], int low, int m, int high);//归并排序

  void merge_one(Key L[], int lenth, int n);          

  void mergesort(Key L[], int n);

  void ShellSort(Key L[],int n);          //希尔排序

  int partition(Key L[],int s,int t);     //一轮快速排序

  void QuickSort(Key L[], int first, int last); //快速排序

  void sift(Key L[], int i, int m);

  void HeapSort(Key L[], int n);           //堆排序

 };

 

void paixu::SelectSort(Key L[],int n)

{//选择排序算法

 //其思路是把待排数组视为两部分L[0..i]为已排部分L[i..n-1]为未排部分

  int i,j,k;                        

  int temp;

  for(i=0;i

  {

         k=i;

         for(j=i+1;j

         if(L[k].Date>L[j].Date)        //找最小元L[k]

          k=j;

         if(k!=i)

         {

                   temp=L[i].Date;            //放入已排部分

                   L[i].Date=L[k].Date;

                   L[k].Date=temp;

                                     

 }

 return;

}

 

void paixu::InsertSort(Key L[],int n)

{//插入排序---将无序部分的任一元插入到有序部分的正确位置上

   int i,j;                                                  

   Key temp;

   for(i=0;i                                  //依次插入记录L[0]...L[n-1]

         {

           temp=L[i];                                   //temp是监视哨      

           j=i-1;                                                  

           while(temp.Date   //查找适合L[i]的插入位置              

                   L[j+1]=L[j--];                           //将记录关键字大于L[i].Date的纪录后移

           L[j+1]=temp;                                        //将记录L[i]插入到有序表的合适位置上

         }

         return ;

}

 

void paixu::BubbleSort(Key L[],int n)

{//冒泡排序算法

 int i,j,temp;

 for(i=0;i                 //外循环

 {

  for(j=i;j                //内循环

  {

   if(L[i].Date>L[j].Date)        //从第一个数据开始依次与其后面的数相比,若大则交换

          {

      temp=L[i].Date;

           L[i].Date=L[j].Date;

           L[j].Date=temp;

          }

  }

 }

 return;

}

 

void paixu::merge(Key L[], int low, int m, int high)

{//两相邻的有序表(一个从lowm;另一个从m+1high)合并为一个有序表(lowhigh)

   Key  r[MAX];                            //合并时用的缓冲向量

   int i, j, k;

   i = low;

   j = m + 1;

   k = 0;

   while(i <= m && j <= high)              //两相邻的有序表合并

   if(L[i].Date <= L[j].Date)

        {r[k] = L[i];  i++;  k++;}

      else

        {r[k] = L[j];  j++;  k++;}

   while(i <= m)                           //有序表剩余部分处理

       {r[k] = L[i];  i++;  k++;}

   while(j <= high)                        //有序表剩余部分处理

       {r[k] = L[j];  j++;  k++;}

   for(i = low, k = 0; i <= high; i++, k++)//缓冲向量r复制到原来的r

       L[i] = r[k];

 

}

 

void paixu::merge_one(Key L[], int lenth, int n)

{//二路归并中的"一趟归并"算法

   int i = 0;

 

   while(i + 2 * lenth - 1 < n)

     {merge(L, i, i + lenth - 1, i + 2 * lenth - 1);//两子序列长度相等的

       i = i + 2 * lenth;}                           //情况下调用merge

   if(i + lenth - 1 < n - 1)

     merge(L, i, i + lenth - 1, n - 1);            //序列中的余留部分处理

}

 

void paixu::mergesort(Key L[], int n)

{//二路归并排序算法

   int lenth = 1;                  //有序子序列长度初始值 = 1

   while(lenth < n)

     {

            merge_one(L, lenth, n);     //调用"一趟归并"的算法

       lenth = 2 * lenth;          //有序子序列长度加倍

         

}

 

void paixu::ShellSort(Key L[],int n)

{//希尔排序---取增量d(i+1)=d(i)/2的希尔排序算法

   int i,h,p,temp,m;                         //p为交换标志,h为增量步长                

   h=n;                                          

   while(h>0)

         {

           h=h/2;                                      //取步长为d(i+1)=d(i)/2

           do{

                     p=0;                                          //设置交换标志,p=0表示未交换

                     for(i=0;i

                            {

                              m=i+h;                          //取本趟的增量

                              if(L[i].Date>L[m].Date) //记录交换

                                     {

                                       temp=L[m].Date;

                                       L[m].Date=L[i].Date;

                                       L[i].Date=temp;

                                       p=1;                       //p=1表示有交换

                                     }

                            }

                   }while(p==1);                          //p=0,终止本趟排序

                                                                      //当增量h=1p=0时终止算法

}

 

int paixu::partition(Key L[],int s,int t)

{//快速排序---快速排序算法中的一趟划分函数

 //对无序区间L[s]L[t]进行划分

 int i,j;

 Key temp;

 i=s;j=t;temp=L[i];                               //初始化,temp为基准记录

 do{

         while((L[j].Date>=temp.Date)&&(i            

                   j--;                                          //从右往左扫描查找第一个关键字小于temp的纪录

         if(i

                   L[i++]=L[j];                           //交换r[i]r[j]

         while((L[i].Date<=temp.Date)&&(i

                   i++;                                        //从左往右扫描查找第一个关键字大于temp的纪录

         if(i

                   L[j--]=L[i];

         }while(i!=j);                                   //i=j,则一次划分结束,基准记录到达最终位置

 L[i]=temp;                                                     //最后将基准记录temp定位

 return (i);

}

 

void paixu::QuickSort(Key L[], int first, int last)         

{//快速排序

   int i;

   if(first < last)

    {

           i = partition(L, first, last);    //一趟快速排序,返回i,产生了两个独立的待排子序列

      QuickSort(L, first, i - 1);       //对两个独立的待排子序列分别递归调用快速排序算法

      QuickSort(L, i + 1,last);

         }

    return;

}

 

void paixu::sift(Key L[], int i, int m)

{//i是根结点编号,m是以i结点为根的子树中最后一个结点的编号

    int j;

    Key temp;

    temp = L[i];

    j = 2 * i;                                //ji根结点的左孩子

    while(j <= m)

      {if(j < m && (L[j].Date

        j++;                                  //i结点有左右孩子时,j取关键字大的孩子结点编号

       if(temp.Date < L[j].Date)

         { L[i] = L[j];   i = j;   j = 2 * i;}//按堆定义调整,并向下一层筛选调整

       else   break;                          //筛选调整完成,跳出循环

      }

    L[i] = temp;

}

 

void paixu::HeapSort(Key L[], int n)                 

{//堆排序: nL表中记录数,L[1]开始放起

    int i;

    Key temp;

    for(i = n/2; i >= 0; i--)

      sift(L, i, n);                     //将无序序列建成大堆

    for(i = n-1; i >= 1; i--)

      {temp = L[0];                      //堆顶及堆尾元素交换

       L[0] = L[i];

       L[i] = temp;

       sift(L,0,i - 1);                  //交换后,从第一个元素开始调整为大堆,每次记录个数少一个

            

}

 

//其他需要的函数

void paixu::createA(int n)

{

  int j, k;

 

  cout<<"输入待排序数据(整数,以空格隔开,0 结束 : "<<endl;

  k=0;

  cin>>j;

 while(j != 0)         //将整数存放到数组S

  {

    S[k].Date=j;

         k++;

    cin>>j;

  }

  s1=S;                      

}

 

void paixu::createrandnum(int a[],int n)

{//产生随机整数

 int i;

 srand((int)time(0));       //产生随机数的种子

 for(i=0;i

         a[i]=rand()$0;       //产生的是240以下的随机数

 cout<<"   排序前原始随机数据"<<endl;

 for(i=0;i

 {

         cout<<"   "<<a[i];

         if(i==0)

         cout<<endl;

 }

 cout<<endl;

}

 

void paixu::createB(int n)

{//产生n个随机整数,并保存到记录数组S

 int b[MAX]; 

 int i;     

 createrandnum(b,n);

 for(i=0;i

         S[i].Date=b[i];                              //将随机整数存放到数组S

 s1=S;

}

 

void paixu::frontdisplayList(Key L[], int n)

{//显示未排数据

  int i;

  printf("\n排序前 : ");

  for (i = 0; i < n; i++)

           printf("  %d",L[i].Date);

  printf("\n\n");

}

 

void paixu::reardisplayList(Key L[], int n)

{//显示已排数据

  int i;

  printf("排序后 : ");

  for (i = 0; i < n; i++) 

           printf("  %d",L[i].Date);

  printf("\n\n");

}

 

void paixu::face1()

{//欢迎界面

  cout<<endl<<endl;

  cout<<"\t\t       欢迎进入本系统!"<<endl;

  cout<<"\t\t    本系统为排序算法比较!"<<endl<<endl<<endl<<endl;

  cout<<"\t\t    请按任意键继续。。。。。。。。。。"<<endl;

  getch();

  system("cls");

}

 

char paixu::choose()

{//选择数据产生方式

       char i;

         cout<<endl<<endl<<"请选择产生数组方式(数据最大个数为200):"<<endl;

    cout<<"    A:选择键盘输入产生数组"<<endl;

    cout<<"    B:选择随机产生数组"<<endl<<endl;

         cout<<"    请输入你的选择: ";

    cin>>i;

    return i;

}

 

void paixu::meun()

{//选择排序算法

   char * string[]={"",

                        "\t                                                   ",

                        "\t      操作方法:(请输入以下数字进行!)               ",

                                        "\t                                                   ",

                                   "\t   --------排序算法的比较----------                ",

                                        "\t           1----选择排序                           ",

                                        "\t           2----插入排序                           ",

                                        "\t           3----冒泡排序                           ",

                                        "\t           4----二路归并排序                       ",

                                        "\t           5----希尔排序                           ",

                                   "\t           6----快速排序                           ",

                                        "\t           7----堆排序                             ",

                                        "\t           8----请屏                               ",        

                                        "\t           0----退出                               "};

  for(int i=14;i>0;i--)

  {  

   system("cls");

   for(int j=i;j<14;j++)

           cout<<string[j]<<endl;

  }

}

 

void paixu::face2()

{//欢迎推出界面

         char * string[]={

                              "\t                   谢谢你的使用                             ",

                                   "\t                   欢迎下次登陆                            

                                      

         };

         for(int i=0;i<2;i++)

         {

                   cout<<string[i]<<endl;

         }

         cout<<endl<<endl;

}

 

void main()

{

         int  k,n;

         char c;

         paixu a;

    a.face1();

         for(;;)

         {

           c=a.choose();

       if(c=='A'||c=='a')

            {

                    cout<<"输入个数:"<<endl;

                    cin>>n;

                    a.createA(n);break;

            }

              if(c=='B'||c=='b')

                    {

                      cout<<"产生多少个数:"<<endl;

                      cin>>n;

                      a.createB(n);break;

                    }

       else

                   {

                     cout<<"选择错误"<<endl;

                     continue;

                   }

         }

          a.meun();

          a.frontdisplayList(s1,n);

         for(;;)

         {

                 cout<<"\t请按数字(0-8)键选择功能"<<endl;

                   cin>>k;

                   switch(k)

                   {

                  

                   case 1:

                            {

                              cout<<"选择排序排序"<<endl;

                              a.SelectSort(s1,n);

                              a.reardisplayList(s1,n);break;

                            }

                   case 2:

                            {

                          cout<<"插入排序"<<endl;

                          a.InsertSort(s1,n);

                               a.reardisplayList(s1,n);break;

                            }

                   case 3:

                            {

                              cout<<"冒泡排序"<<endl;

                              a.BubbleSort(s1,n);

                              a.reardisplayList(s1,n);break;

                            }

                   case 4:

                            {

                              cout<<"二路归并排序"<<endl;

                              a.mergesort(s1,n);

                              a.reardisplayList(s1,n);break;

                            }

                   case 5:

                            {

                              cout<<"希尔排序"<<endl;

                              a.ShellSort(s1,n);

                              a.reardisplayList(s1,n);break;

                            }

                   case 6:

                            {

                              cout<<"快速排序"<<endl;

                              a.QuickSort(s1,0,n-1);

                              a.reardisplayList(s1,n);break;

                            }

                   case 7:

                            {

                              cout<<"堆排序"<<endl;  

                         a.HeapSort(s1,n);

                              a.reardisplayList(s1,n);break;

                            }

                   case 8:{ system("cls");a.meun();break;      }

                   case 0: {system("cls");a.face2();exit(0);}

                   default:

                                     cout<<"\t输入错误"<<endl;

                                 

         }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值