Chinaunix首页 | 论坛 | 博客
  • 博客访问: 255563
  • 博文数量: 52
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 1538
  • 用 户 组: 普通用户
  • 注册时间: 2013-04-24 07:45
个人简介

生活就像海洋,只有意志坚强的人,才能到达彼岸。

文章存档

2013年(52)

分类: C/C++

2013-08-22 12:20:19

一、排序的概念及分类

1>排序的一般定义

    排序是计算机内京城进行的一种操作,其目的是将一组“无序”的数据元素调整为“有序”的数据元素。

2>排序的数学定义

    假设含n个数据元素的序列为{R1,R2,R3,...,Rn},其相应的关键字序列为{K1,K2,...,Kn}这

些关键字相互之间可以进行比较,即在他们之间存在着这样一个关系:

        Kp1<=Kp2<=...<=Kpn

按此固有关系将上式记录序列重新排列为{Rp1,Rp2,...,Rpn}的操作称作排序。

3>排序的稳定性

    如果在序列中有两个数据元素r[i]和r[j],它们的关键字k[i]==k[j],且在排序之前,对象r[i]排

在r[j]前面。如果排序之后,对象r[i]仍在对象r[j]的前面,则称这个排序方法是稳定的,否则称这

个排序方法是不稳定的。

4>多关键字排序

    排序时需要比较的关键字多余一个,排序结果首先按关键字1进行排序,当关键字1相同时按关键

字2进行排序,......当关键字n-1相同时则按关键字n进行排序,以此类推。

5>排序中的关键操作

    比较:任意两个数据元素通过比较操作确定先后次序。
    
    交换:数据元素之间需要交换才能得到预期结果。

6>内排序和外排序

    内排序:整个排序过程中不需要访问外存便能完成

    外排序:待排序的数据元素数量很大,整个序列的排序过程不可能在内存中完成。

7>排序的审判

时间性能
    关键性能差异体现在比较和交换的数量

辅助存储空间
    为完成排序操作需要的额外的存储空间,必要时可以“空间换时间”。

算法的实现复杂性
    过于发杂的排序会影响代码的可读性和可维护性,也可能影响排序的性能。

二、选择排序:

1>基本思想:
    每一趟(例如第i趟,i = 0,1,...,n - 2)在后面n - i个待排的数据元素中选出关键字最小的

元素,作为有序元素序列的第 i 个元素。

2>代码实现:


点击(此处)折叠或打开

  1. /**********************SelectionSort.c*********************************/
  2. #include <stdio.h>
  3. #include <stdlib.h>

  4. /* run this program using the console pauser or add your own getch, system("pause") or input loop */

  5. void println(int array[], int len)
  6. {
  7.     int i = 0;
  8.     for(i=0; i<len;i++)
  9.     {
  10.         printf("%d ", array[i]);
  11.     }
  12.     printf("\n");
  13. }

  14. void swap(int array[], int i, int j)
  15. {
  16.     int temp = array[i];
  17.     array[i] = array[j];
  18.     array[j] = temp;
  19. }

  20. void SelectionSort(int array[], int len) //O(n*n)
  21. {
  22.     int i = 0;
  23.     int j = 0;
  24.     int k = -1;
  25.     for(i=0;i<len;i++)
  26.     {
  27.         k = i;
  28.         for(j=i;j<len;j++)
  29.         {
  30.             if( array[j] < array[k] )
  31.             {
  32.                 k = j;
  33.             }
  34.         }
  35.         swap(array, i ,k);
  36.     }
  37. }

  38. int main(int argc, char *argv[])
  39. {
  40.     int array[] = {21,25,49,25,16,8};
  41.     int len = sizeof(array) / sizeof(*array);
  42.     println(array,len);
  43.     SelectionSort(array,len);
  44.     println(array,len);
  45.     return 0;
  46. }



三、插入排序

1>基本思想:
    当插入第i(i >= 1)个数据元素时,前面的v[0],v[1],...,v[i-1]已经排好序。这时,用v[i]

的关键字与v[i-1],v[i-2],...的关键字进行比较,找到插入位置即将v[i]插入,原来位置上的对象

向后顺移

2>代码实现:


点击(此处)折叠或打开

  1. /**********************InsertionSort.c*********************************/
  2. #include <stdio.h>
  3. #include <stdlib.h>

  4. /* run this program using the console pauser or add your own getch, system("pause") or input loop */

  5. void println(int array[], int len)
  6. {
  7.     int i = 0;
  8.     for(i=0; i<len;i++)
  9.     {
  10.         printf("%d ", array[i]);
  11.     }
  12.     printf("\n");
  13. }

  14. void swap(int array[], int i, int j)
  15. {
  16.     int temp = array[i];
  17.     array[i] = array[j];
  18.     array[j] = temp;
  19. }

  20. void InsertionSort(int array[], int len) //O(n*n)
  21. {
  22.     int i = 0;
  23.     int j = 0;
  24.     int k = -1;
  25.     int temp = -1;
  26.     for(i=0;i<len;i++)
  27.     {
  28.         k = i;
  29.         temp = array[k];
  30.         for(j=i-1; (j>=0) && (array[j]>temp); j--)
  31.         {
  32.             array[j+1] = array[j];
  33.             k = j;
  34.         }
  35.         array[k] = temp;
  36.     }
  37. }

  38. int main(int argc, char *argv[])
  39. {
  40.     int array[] = {21,25,49,25,16,8};
  41.     int len = sizeof(array) / sizeof(*array);
  42.     println(array,len);
  43.     InsertionSort(array,len);
  44.     println(array,len);
  45.     return 0;
  46. }



四、冒泡排序:
    
1>基本思想:
    设待排数据元素序列中的元素个数为n。最多作n-1趟,i=1,2,...,n-1在第i趟中从后向前,

j=n-1,n-2,...,i,两两比较v[j-1]和v[j]的关键字。如果发生逆序,则交换v[j-1]和v[j].

2>代码实现:


点击(此处)折叠或打开

  1. /*********************BuubleSort.c****************************************/
  2. #include <stdio.h>
  3. #include <stdlib.h>

  4. /* run this program using the console pauser or add your own getch, system("pause") or input loop */

  5. void println(int array[], int len)
  6. {
  7.     int i = 0;
  8.     for(i=0; i<len;i++)
  9.     {
  10.     printf("%d ", array[i]);
  11.     }
  12.     printf("\n");
  13. }

  14. void swap(int array[], int i, int j)
  15. {
  16.     int temp = array[i];
  17.     array[i] = array[j];
  18.     array[j] = temp;
  19. }

  20. void BubbleSort(int array[], int len) //O(n*n)
  21. {
  22.     int i = 0;
  23.     int j = 0;
  24.     int exchange = 1;
  25.     for(i=0; (i<len) && exchange; i++)
  26.     {
  27.         exchange = 0;
  28.         for(j=len-1; j>i; j--)
  29.         {
  30.             if( array[j] < array[j-1] )
  31.             {
  32.                 swap(array,j, j-1);
  33.                 exchange = 1;
  34.             }
  35.         }
  36.     }
  37. }

  38. int main(int argc, char *argv[])
  39. {
  40.     int array[] = {21,25,49,25,16,8};
  41.     int len = sizeof(array) / sizeof(*array);
  42.     println(array,len);
  43.     BubbleSort(array,len);
  44.     println(array,len);
  45.     return 0;
  46. }


五、希尔排序(不稳定)

1>基本思想:
    将排序序列划分为若干组,在每一组内进行插入排序,以使整个序列基本有序,然后再对整个序

列进行插入排序。

2>代码实现:


点击(此处)折叠或打开

  1. /********************ShellSort.c*****************************/

  2. #include <stdio.h>
  3. #include <stdlib.h>

  4. /* run this program using the console pauser or add your own getch, system("pause") or input loop */

  5. void println(int array[], int len)
  6. {
  7.     int i = 0;
  8.     for(i=0; i<len;i++)
  9.     {
  10.     printf("%d ", array[i]);
  11.     }
  12.     printf("\n");
  13. }

  14. void swap(int array[], int i, int j)
  15. {
  16.     int temp = array[i];
  17.     array[i] = array[j];
  18.     array[j] = temp;
  19. }

  20. void ShellSort(int array[], int len) //O(n*n)
  21. {
  22.     int i = 0;
  23.     int j = 0;
  24.     int k = -1;
  25.     int temp = -1;
  26.     int gap = len;
  27.     do
  28.     {
  29.         gap = gap / 3 + 1; /*gap的值必须最后收敛于1*/
  30.         for(i= gap; i<len; i+=gap)
  31.         {
  32.             k = i;
  33.             temp = array[k];
  34.             for(j=i-gap; (j>=0) && (array[j]>temp); j-=gap)
  35.             {
  36.                 array[j+gap] = array[j]    ;
  37.                 k = j;
  38.             }
  39.             array[k] = temp;
  40.         }
  41.     }while(gap > 1);
  42. }

  43. int main(int argc, char *argv[])
  44. {
  45.     int array[] = {21,25,49,25,16,8};
  46.     int len = sizeof(array) / sizeof(*array);
  47.     println(array,len);
  48.     ShellSort(array,len);
  49.     println(array,len);
  50.     return 0;
  51. }



六、快速排序(不稳定)

1>基本思想:
    1)任取待排序序列中的某个数据元素(例如:第一个元素)作为基准,按照该元素的关键字大

小将整个序列划分为左右两个序列:

    *左侧子序列中所有的元素都小于或等于基准元素
    *右侧子序列元素中所有元素都大于基准元素
    *基准元素排在这两个子序列中间

    2)分别对这两个自序列重复施行上述方法,知道所有的对象都排在相应位置上为止。

    3)首先对无序的记录序列进行一次划分,之后分别对分割所得两个子序列递归进行快速排序。


2>实现代码:


点击(此处)折叠或打开

  1. /*********************QuickSort.c*******************************/

  2. #include <stdio.h>
  3. #include <stdlib.h>

  4. /* run this program using the console pauser or add your own getch, system("pause") or input loop */

  5. void println(int array[], int len)
  6. {
  7.     int i = 0;
  8.     for(i=0; i<len;i++)
  9.     {
  10.     printf("%d ", array[i]);
  11.     }
  12.     printf("\n");
  13. }

  14. void swap(int array[], int i, int j)
  15. {
  16.     int temp = array[i];
  17.     array[i] = array[j];
  18.     array[j] = temp;
  19. }

  20. int partition(int array[], int low, int high)//
  21. {
  22.     int pv = array[low];
  23.     while( low < high )
  24.     {
  25.         while( (low < high ) && (array[high] >= pv))
  26.         {
  27.             high--;
  28.         }
  29.         swap(array,low,high);
  30.         while( (low < high) && (array[low] <= pv) )
  31.         {
  32.             low++;
  33.         }
  34.         swap(array,low,high);
  35.     }
  36.     return low;
  37. }

  38. void QSort(int array[], int low, int high)
  39. {
  40.     if(low < high)
  41.     {
  42.         int pivot = partition(array,low,high);
  43.         QSort(array,low,pivot-1);
  44.         QSort(array,pivot+1,high);
  45.     }
  46. }

  47. void QuickSort(int array[], int len) //O(n*logn)
  48. {
  49.     QSort(array,0,len-1);
  50. }

  51. int main(int argc, char *argv[])
  52. {
  53.     int array[] = {21,25,49,25,16,8};
  54.     int len = sizeof(array) / sizeof(*array);
  55.     println(array,len);
  56.     QuickSort(array,len);
  57.     println(array,len);
  58.     return 0;
  59. }





七、归并排序(稳定的)

1>基本思想:
    将两个或两个以上的有序序列合并成一个新的有序序列:

有序序列v[1],v[2]...v[m]和v[m+1],...v[n] ====> v[1]...v[n] 这种归并方法称为2路归并。将多个有序序列归并为一个新的有序序列,称为多路归并。

检测两个有序序列A和B,C为归并后的新的有序序列:

  =>当i和j都在两个序列内变化时,根据关键码的大小将较小的数据元素排放到新序列k所指位置中

  =>当i与j中有一个已经超出序列时,将另一个序列中的剩余部分照抄到新序列中

2>代码实现:


点击(此处)折叠或打开

  1. /*******************MergeSort.c*****************************/

  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <malloc.h>

  5. /* run this program using the console pauser or add your own getch, system("pause") or input loop */

  6. void println(int array[], int len)
  7. {
  8.     int i = 0;
  9.     for(i=0; i<len;i++)
  10.     {
  11.         printf("%d ", array[i]);
  12.     }
  13.     printf("\n");
  14. }

  15. void swap(int array[], int i, int j)
  16. {
  17.     int temp = array[i];
  18.     array[i] = array[j];
  19.     array[j] = temp;
  20. }

  21. void Merge(int src[], int des[],int low,int mid, int high)
  22. {
  23.     int i = low;
  24.     int j = mid + 1;
  25.     int k = low;
  26.     while( (i <= mid) && ( j <= high) )
  27.     {
  28.         if(src[i] < src[j])
  29.         {
  30.             des[k++] = src[i++];
  31.         }
  32.         else
  33.         {
  34.             des[k++] = src[j++];
  35.         }
  36.     }
  37.     while( i<= mid )
  38.     {
  39.         des[k++] = src[i++];
  40.     }
  41.     while( j<= high)
  42.     {
  43.         des[k++] = src[j++];
  44.     }
  45. }

  46. void MSort(int src[], int des[], int low, int high,int max)
  47. {
  48.     if( low == high)
  49.     {
  50.     des[low] = src[low];
  51.     }
  52.     else
  53.     {
  54.         int mid = (low + high) / 2;
  55.         int* space = (int*)malloc(sizeof(int*)*max);
  56.         if( space != NULL )
  57.         {
  58.             MSort(src,space,low,mid,max);
  59.             MSort(src,space,mid+1,high,max);
  60.             Merge(space,des,low,mid,high);
  61.         }
  62.         free(space);
  63.     }
  64. }

  65. void MergeSort(int array[], int len) //O(n*logn)
  66. {
  67.     MSort(array,array,0,len-1,len);
  68. }

  69. int main(int argc, char *argv[])
  70. {
  71.     int array[] = {21,25,49,25,16,8};
  72.     int len = sizeof(array) / sizeof(*array);
  73.     println(array,len);
  74.     MergeSort(array,len);
  75.     println(array,len);
  76.     return 0;
  77. }





希尔排序,快速排序和归并排序将排序算法的时间复杂度提高到了O(n*logn),希尔排序和快速排序是不稳定的,归并排序的排序结果是稳定的。

    

阅读(1906) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~