码迷,mamicode.com
首页 > 编程语言 > 详细

排序算法

时间:2015-08-08 13:27:25      阅读:182      评论:0      收藏:0      [点我收藏+]

标签:

插入排序:直接插入排序

排序思想

将待排序的记录Ri,插入到已排好序的记录表R1, R2 ,…., Ri-1中,得到一个新的、记录数增加1的有序表。 直到所有的记录都插入完为止。

设待排序的记录顺序存放在数组R[1…n]中,在排序的某一时刻,将记录序列分成两部分:

◆ R[1…i-1]:已排好序的有序部分;

◆ R[i…n]:未排好序的无序部分。

       显然,在刚开始排序时,R[1]是已经排好序的。

   例:设有关键字序列为:7, 4, -2, 19, 13, 6,直接插入排序的过程如下图10-1所示:

技术分享

C语言实现

 1 void straight_insert_sort(Sqlist *L)
 2 {   int i, j ;
 3 for (i=2; i<=L->length; i++)
 4 {  L->R[0]=L->R[i]; j=i-1;     /*   设置哨兵   */
 5 while( LT(L->R[0].key, L->R[j].key) )
 6     {   L->R[j+1]=L->R[j];
 7          j--;
 8      }          /*   查找插入位置   */
 9 L->R[j+1]=L->R[0];      /*   插入到相应位置   */
10 }
11 }

 

 

希尔排序(分组插入排序法)

排序思想:

①   先取一个正整数d1(d1<n)作为第一个增量,将全部n个记录分成d1组,把所有相隔d1的记录放在一组中,即对于每个k(k=1, 2,  … d1),R[k], R[d1+k], R[2d1+k] , …分在同一组中,在各组内进行直接插入排序。这样一次分组和排序过程称为一趟希尔排序;

②   取新的增量d2<d1,重复①的分组和排序操作;直至所取的增量di=1为止,即所有记录放进一个组中排序为止。

过程图:

技术分享

 

C语言实现:

先给出一趟希尔排序的算法,类似直接插入排序

 1 void shell_pass(Sqlist *L, int d)
 2    /*  对顺序表L进行一趟希尔排序, 增量为d  */
 3 {  int j, k ;
 4 for (j=d+1; j<=L->length; j++)
 5 {  L->R[0]=L->R[j] ;        /*  设置监视哨兵  */
 6 k=j-d ;
 7 while (k>0&&LT(L->R[0].key, L->R[k].key) )
 8     {   L->R[k+d]=L->R[k] ; k=k-d ;   }
 9 L->R[k+j]=L->R[0] ;
10 }
11 }

然后在根据增量数组dk进行希尔排序

1 void shell_sort(Sqlist *L, int dk[], int t)
2      /*    按增量序列dk[0 … t-1],对顺序表L进行希尔排序   */
3 {  int m ;
4 for (m=0; m<=t; m++)
5 shll_pass(L, dk[m]) ;
6 }

说明:

希尔排序的分析比较复杂,涉及一些数学上的问题,其时间是所取的“增量”序列的函数。

希尔排序特点

       子序列的构成不是简单的“逐段分割”,而是将相隔某个增量的记录组成一个子序列。

 

 

快速排序:冒泡

排序思想:

        依次比较相邻的两个记录的关键字,若两个记录是反序的(即前一个记录的关键字大于后前一个记录的关键字),则进行交换,直到没有反序的记录为止。

① 首先将L->R[1]与L->R[2]的关键字进行比较,若为反序(L->R[1]的关键字大于L->R[2]的关键字),则交换两个记录;然后比较L->R[2]与L->R[3]的关键字,依此类推,直到L->R[n-1]与L->R[n]的关键字比较后为止,称为一趟冒泡排序,L->R[n]为关键字最大的记录。

②  然后进行第二趟冒泡排序,对前n-1个记录进行同样的操作。

排序过程图:

关键字分别为23, 38, 22, 45, 23, 67, 31, 15, 41

技术分享

C语言实现

 1 #define FALSE 0
 2 #define TRUE 1
 3 void Bubble_Sort(Sqlist *L)
 4 {  int j ,k , flag ;
 5 for (j=0; j<L->length; j++)       /*   共有n-1趟排序   */
 6 {  flag=TRUE ;
 7 for (k=1; k<=L->length-j; k++)   /*   一趟排序   */
 8     if (LT(L->R[k+1].key, L->R[k].key ) )
 9         {   flag=FALSE ; L->R[0]=L->R[k] ; 
10             L->R[k]=L->R[k+1] ; 
11             L->R[k+1]=L->R[0] ;  
12          }
13     if  (flag==TRUE)  break ;
14 }
15 }

 

快速排序:

排序思想:

通过一趟排序,将待排序记录分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,再分别对这两部分记录进行下一趟排序,以达到整个序列有序。

 

一趟快排:

后续待补充。。。

排序算法

标签:

原文地址:http://www.cnblogs.com/fysola/p/4712887.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!