排序

来源:互联网 发布:苏州网络培训 编辑:程序博客网 时间:2024/05/26 20:24

#include <stdio.h>

#define KEYTYPE    int

#define MAXSIZE    100

int createList(RECNODE  *r)

{ int j, k;

 printf("\n\n输入待排序数据(整数,以空格隔开,0 结束) :"); k = 0; scanf("%d",&j);

  while(j != 0) { k++; r[k].key = j;scanf("%d",&j); }

  return k;

}

 

frontdisplayList(RECNODE *r, int n)

{int i;

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

 for (i= 0; i < n; i++)   printf("  %d",r[i+1].key);

 printf("\n\n");

}

 

reardisplayList(RECNODE *r, int n)

{int i;

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

 for (i= 0; i < n; i++)   printf("  %d",r[i+1].key);

 printf("\n\n");

}

 

void insertsort(RECNODE *r, int n)

{/*直接插入排序*/

     inti,j;

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

       {  r[0]= r[i];  

j = i - 1;             /*r[0]是监视哨,j表示当前已排好序列的长度*/

         while(r[0].key < r[j].key)    /*确定插入位置*/

            {r[j + 1] = r[j];   j--;}

         r[j + 1] = r[0];              /*元素插入*/

       }

}

 

void bublesort(RECNODE *r, int n)

{/*简单交换排序:冒泡排序*/

     inti, j;

     RECNODEtemp;

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

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

         if(r[j+ 1].key < r[j].key)

           {temp = r[j + 1];  r[j + 1] = r[j];  r[j] = temp;}

}

 

int partition(RECNODE *r, int *low, int*high)

{/*一趟快速排序,返回i,产生了两个独立的待排子序列*/

     inti, j;

     RECNODE  temp;

     i =*low;  j = *high;

     temp= r[i];           /*枢轴记录保存在temp变量中*/

     do

{while((r[j].key >= temp.key) && (i < j)) 

j--;   /*j指针记录和枢轴记录比较*/

          if(i< j)    { r[i] = r[j];   i++;}

        while((r[i].key <= temp.key) &&(i < j))  

i++;   /*i指针记录和枢轴记录比较*/

        if(i < j)     { r[j] = r[i];   j--;}

      }while(i != j);

     r[i]= temp;            /*枢轴记录的排序位置确定在i*/

     returni;

}

 

void quicksort(RECNODE *r, int start, intend)

{/*快速排序*/

     inti;

     if(start< end)

        { i = partition(r, &start, &end);

  /*一趟快速排序,返回i,产生了两个独立的待排子序列*/

          quicksort(r, start, i - 1);     

/*对两个独立的待排子序列分别递归调用快速排序算法*/

          quicksort(r, i + 1,end);}

}

 

void selesort(RECNODE *r, int n)

{/*简单选择排序*/

     inti,j,k;

     RECNODEtemp;

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

       { k = i;                       /*k:最小关键字的初始位置*/

         for(j = i + 1; j <= n; j++)

           if(r[j].key < r[k].key)

              k =j;          /*k:跟踪记录当前最小关键字的位置*/

         if(k != i)            /*最小关键字元素和待排序列的第一个元素交换*/

           {temp = r[i];   r[i] = r[k];   r[k] = temp;}

       }

}

 

void sift(RECNODE *r, int i, int m)

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

     intj;

     RECNODEtemp;

     temp= r[i];

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

     while(j<= m)

       {if(j < m && (r[j].key < r[j +1].key))

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

        if(temp.key < r[j].key)       /*按堆定义调整,并向下一层筛选调整 */

          { r[i] = r[j];   i = j;  j = 2 * i;}

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

       }

     r[i]= temp;

}

 

void heapsort(RECNODE *r, int n)

{/*堆排序: n为r表中记录数,从r[1]开始放起*/

     inti;

     RECNODEtemp;

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

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

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

       {temp = r[1];              /*堆顶及堆尾元素交换*/

        r[1] = r[i];

        r[i] = temp;

        sift(r,1,i - 1); 

 /*交换后,从第一个元素开始调整为大堆,每次记录个数少一个*/

       }        

}

 

void merge(RECNODE *r, int low, int m, inthigh)

{  /*两相邻的有序表(一个从low到m;另一个从m+1到high)*/

/*合并为一个有序表(从low到high)*/

     RECNODE r1[MAXSIZE];             /*合并时用的缓冲向量*/

     inti, j, k;

     i =low;

     j =m + 1;

     k =0;

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

       if(r[i].key <= r[j].key)

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

       else

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

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

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

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

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

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

        r[i] = r1[k];

 

}

 

void merge_one(RECNODE *r, int lenth, int n)

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

     inti = 0;

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

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

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

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

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

}

 

void mergesort(RECNODE *r, int n)

{/*二路归并排序算法*/

     intlenth = 1;                 /*有序子序列长度初始值 = 1*/

     while(lenth< n)

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

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

}

 

void main() {

     RECNODE  a[MAXSIZE];

     intlen, b, j, k;

     intloop = 1;

     while(loop) {

     printf("\n\n排序综合练习\n\n");

     printf("  0 -- 退出\n");

     printf("  1 -- 直接插入排序\n");

     printf("  2 -- 简单交换(冒泡)排序\n");

     printf("  3 -- 快速排序\n");

     printf("  4 -- 简单选择排序\n");

     printf("  5 -- 堆排序\n");

     printf("  6 -- 二路归并排序\n");

     printf("\n\n  请选择项号 :");

     scanf("%d",&b);

     printf("\n\n");

     if(b>= 0 && b <= 6)

         switch(b){

              case0: loop = 0;

                     break;

              case1: len = createList(a);

                   frontdisplayList(a,len);

                   insertsort(a,len);

                   reardisplayList(a,len);

                   break;

              case2: len = createList(a);

                   frontdisplayList(a,len);

                   bublesort(a,len);

                   reardisplayList(a,len);

                   break;

              case3: len = createList(a);

                   frontdisplayList(a,len);

                   quicksort(a,1, len);

                   reardisplayList(a,len);

                   break;

              case4: len = createList(a);

                   frontdisplayList(a,len);

                   selesort(a,len);

                   reardisplayList(a,len);

                   break;

              case5: len = createList(a);

                   frontdisplayList(a,len);

                   heapsort(a,len);

                   reardisplayList(a,len);

                   break;

              case6: 

printf("\n\n输入待排序数据(整数,以空格隔开,0 结束) :"); k = 0; scanf("%d",&j);

                  while(j != 0) { k++; a[k-1].key = j; scanf("%d",&j);}

                  len = k;

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

                  for (j = 0; j < len; j++)   printf("  %d",a[j].key);

                  printf("\n\n");

                  mergesort(a, len);

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

                 for (j = 0; j < len; j++)   printf("  %d",a[j].key);

                  printf("\n\n");

                   break;

         }

     printf("\n\n结束此练习吗? (0 -- 结束 1 -- 继续): ");

     scanf("%d",&loop);

     printf("\n\n");

     }

}