快速排序【记录一下代码】

简介: 本文仅用作学习记录,大神勿喷O(∩_∩)O~代码一、百度百科C++语言版本代码,参考数据结构p274(清华大学出版社,严蔚敏) 1 void Qsort1(int a[], int low, int high)//百度百科C++语言版本代码 2 {/*参考数据结构p274(清华大学出版社...

本文仅用作学习记录,大神勿喷O(∩_∩)O~

代码一、百度百科C++语言版本代码,参考数据结构p274(清华大学出版社,严蔚敏)

 1 void Qsort1(int a[], int low, int high)//百度百科C++语言版本代码 
 2 {/*参考数据结构p274(清华大学出版社,严蔚敏)*/
 3     if(low >= high) return;
 4     int first = low;
 5     int last = high;
 6     int key = a[first];/*用字表的第一个记录作为枢轴*/
 7  
 8     while(first < last)
 9     {
10         while(first < last && a[last] >= key)
11         {
12             --last;
13         }
14         a[first] = a[last];/*将比第一个小的移到低端*/
15         while(first < last && a[first] <= key)
16         {
17             ++first;
18         }
19         a[last] = a[first];    
20         /*将比第一个大的移到高端*/
21     }
22     a[first] = key;/*枢轴记录到位*/
23     Qsort1(a, low, first-1);
24     Qsort1(a, first+1, high);
25 }
View Code

代码二、百度百科C语言版本代码

 1 void Qsort2(int *a, int left, int right)//百度百科C语言版本代码 
 2 {
 3     if(left >= right)/*如果左边索引大于或者等于右边的索引就代表已经整理完成一个组了*/
 4     {
 5         return ;
 6     }
 7     int i = left;
 8     int j = right;
 9     int key = a[left];
10      
11     while(i < j)                               /*控制在当组内寻找一遍*/
12     {
13         while(i < j && key <= a[j])/*而寻找结束的条件就是,1,找到一个小于或者大于key的数(大于或小于取决于你想升序还是降序)2,没有符合条件1的,并且i与j的大小没有反转*/ 
14         {
15             j--;/*向前寻找*/
16         }
17         a[i] = a[j];/*找到一个这样的数后就把它赋给前面的被拿走的i的值(如果第一次循环且key是a[left],那么就是给key)*/
18          
19         while(i < j && key >= a[i])/*这是i在当组内向前寻找,同上,不过注意与key的大小关系停止循环和上面相反,因为排序思想是把数往两边扔,所以左右两边的数大小与key的关系相反*/
20         {
21             i++;
22         }
23         a[j] = a[i];
24     }
25      
26     a[i] = key;/*当在当组内找完一遍以后就把中间数key回归*/
27     Qsort2(a, left, i - 1);/*最后用同样的方式对分出来的左边的小组进行同上的做法*/
28     Qsort2(a, i + 1, right);/*用同样的方式对分出来的右边的小组进行同上的做法*/
29                        /*当然最后可能会出现很多分左右,直到每一组的i = j 为止*/
30 }
View Code

代码三、坐在马桶上看算法:快速排序。   链接:http://developer.51cto.com/art/201403/430986.htm

(来源页面评论代码有误,测试没发现问题。)

 1 void Qsort3(int a[],int left,int right) //坐在马桶上看算法:快速排序。http://developer.51cto.com/art/201403/430986.htm 
 2 { 
 3     int i,j,t,temp; 
 4     if(left>right) return; 
 5                                 
 6     temp=a[left]; //temp中存的就是基准数 
 7     i=left; 
 8     j=right; 
 9     while(i!=j) 
10     { 
11         //顺序很重要,要先从右边开始找 
12         while(i<j && a[j]>=temp) 
13             j--; 
14         //再找右边的 
15         while(i<j && a[i]<=temp) 
16             i++; 
17         //交换两个数在数组中的位置 
18         if(i<j) 
19         { 
20             t=a[i]; a[i]=a[j]; a[j]=t; 
21         } 
22     } 
23     //最终将基准数归位 
24     a[left]=a[i]; 
25     a[i]=temp; 
26                              
27     Qsort3(a,left,i-1);//继续处理左边的,这里是一个递归的过程 
28     Qsort3(a,i+1,right);//继续处理右边的 ,这里是一个递归的过程 
29 }
View Code

代码四、白话经典算法系列之六 快速排序   链接: http://blog.csdn.net/morewindows/article/details/6684558#

链接页面评论一致认为作者讲解非常棒。

 1 void Qsort4(int s[], int l, int r)//白话经典算法系列之六 快速排序 http://blog.csdn.net/morewindows/article/details/6684558#
 2 {  
 3     if (l < r)  
 4     { 
 5         int i = l, j = r, x = s[l];
 6         while (i < j)
 7         {
 8             while(i < j && s[j] >= x) // 从右向左找第一个小于x的数  
 9                 j--;    
10             if(i < j)   
11                 s[i++] = s[j];  
12               
13             while(i < j && s[i] < x) // 从左向右找第一个大于等于x的数  
14                 i++;    
15             if(i < j)   
16                 s[j--] = s[i];  
17         }
18         s[i] = x;  
19         Qsort4(s, l, i - 1); // 递归调用   
20         Qsort4(s, i + 1, r);  
21     }
22 }  
View Code

代码五、博客园~大器晚成~的代码  链接:http://www.cnblogs.com/luchen927/archive/2012/02/29/2368070.html

原文代码有误,评论里面已经有园友指出。这里摘抄时已经修改,否则当待排序列有相等值则可能会死循环 。

 1 void Qsort5(int *v, int left, int right)//博客园“大器晚成”的代码http://www.cnblogs.com/luchen927/archive/2012/02/29/2368070.html 
 2 {//原文代码有错误,已经修改,否则当待排序列有相等值则会死循环 。修改以后,本代码与百度百科代码是相同 
 3     if(left < right)
 4     {
 5         int key = v[left];
 6         int low = left;
 7         int high = right;
 8         while(low < high)
 9         {
10             while(low < high && v[high] >= key)//原文 while(low < high && v[high] > key)
11             {
12                 high--;
13             }
14             v[low] = v[high];
15             while(low < high && v[low] <= key)//原文while(low < high && v[low] < key)
16             {
17                 low++;
18             }
19             v[high] = v[low];
20         }
21         v[low] = key;
22         Qsort5(v,left,low-1);
23         Qsort5(v,low+1,right);
24     }
25 }
View Code

代码六、《C++一本通》page191快速排序代码

 1 void Qsort6(int *a,int l,int r)//《C++一本通》page191快速排序代码 
 2 {  
 3     int i,j,mid,p;
 4     i=l;
 5     j=r; 
 6     mid=a[(l+r) / 2]; //将当前序列在中间位置的数定义为分隔数
 7     do
 8     {
 9         while (a[i]<mid) i++;//在左半部分寻找比中间数大的数
10         while (a[j]>mid) j--;//在右半部分寻找比中间数小的数
11         if (i<=j) 
12         { //若找到一组与排序目标不一致的数对则交换它们
13             p=a[i];a[i]=a[j];a[j]=p;
14             i++;j--; //继续找
15         }
16     }while(i<=j);//注意这里不能少等号
17     if (l<j)  Qsort6(a,l,j);//若未到两个数的边界,则递归搜索左右区间
18     if (i<r)  Qsort6(a,i,r);
19 }
View Code

 

测试用的主函数

 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 #include<time.h>
 4 
 5 int cmp(const void *a,const void *b)
 6 {    return *(int*)a - *(int*)b;   }
 7 int main()
 8 {
 9     int a[50],b[50],c[50],d[50],e[50],f[50],g[50],h[50];
10     int n,i,k=100000,index=1,count=0;
11     srand((unsigned)time(0));
12     
13     freopen("res.out","w",stdout);
14     for(;k>0;k--)
15     {
16         n=(rand()%2==1?49:50);
17          for(i=0;i<n;i++)
18          {
19              a[i]=rand()%3000;
20              h[i]=g[i]=f[i]=e[i]=d[i]=c[i]=b[i]=a[i];
21         }
22         
23         Qsort1(a, 0, n - 1);
24         Qsort2(b, 0, n - 1);
25          qsort(c,n,sizeof(c[0]),cmp);
26          Qsort3(e,0,n-1);
27          Qsort4(f,0,n-1);
28          Qsort5(g,0,n-1);
29          Qsort6(h,0,n-1);
30          
31         for(i= 0; i < n; i++)
32         {
33             if(a[i]!=c[i]||b[i]!=c[i]||e[i]!=c[i]||f[i]!=c[i]||g[i]!=c[i]||h[i]!=c[i]) 
34                 break;
35         }
36         if(i<n)
37         {
38             printf("case %d:\n",index);
39             printf("A:");//Qsort1的结果 
40             for(i=0;i<n;i++)
41                 printf("%d ",a[i]);
42                printf("\n");
43                
44                printf("B:");//Qsort2的结果 
45             for(i=0;i<n;i++)
46                 printf("%d ",b[i]);
47                printf("\n");
48                
49                printf("C:");//标准结果序列 
50             for(i=0;i<n;i++)
51                 printf("%d ",c[i]);
52                printf("\n");
53                
54                printf("E:");//Qsort3的结果 
55             for(i=0;i<n;i++)
56                 printf("%d ",e[i]);
57                printf("\n");
58                
59                printf("F:");//Qsort4的结果 
60             for(i=0;i<n;i++)
61                 printf("%d ",f[i]);
62                printf("\n");
63                
64                printf("G:");//Qsort5的结果 
65             for(i=0;i<n;i++)
66                 printf("%d ",g[i]);
67                printf("\n");
68                
69                printf("H:");//Qsort6的结果 
70             for(i=0;i<n;i++)
71                 printf("%d ",h[i]);
72                printf("\n");
73                
74                printf("D:");//原未排序序列 
75             for(i=0;i<n;i++)
76                 printf("%d ",d[i]);
77                printf("\n");
78         }
79         else { printf("case %d is ok!\n",index); count++;}
80         index++;
81     }
82     printf("%d of %d is ok!\n",count,index-1);
83     return 0;
84 }
View Code

 

其实 Qsort1、Qsort2、Qsort5(博客园代码修改以后)三份代码是一样的
Qsort4跟上面几个是差不多的,但稍有一点点改变
Qsort3思路变化比较大一些。
Qsort6简直就是另类代码风格,瞎搞的,不过也是对的。
学习记住 Qsort1、Qsort2、Qsort5之一或者Qsort4即可。

 

注意:在快排过程中划分区间时,必须要有等号,比如:

    int i=left,j=right,key=a[left];
    while(i<j)
    {
        while(i<j&&key>=a[j]) j--;//必须取等号,否则当数组两头的数相等时会死循环 
        a[i]=a[j];
        while(i<j&&key<=a[i]) i++;//必须取等号,否则当数组两头的数相等时会死循环
        a[j]=a[i];
    }

这种地方>=不能改为>,否则可能死循环。

 

相关文章
|
4月前
数据结构堆排序中堆的建立、调整、插入、删除等操作的详解(题目讲解 简单易懂)
数据结构堆排序中堆的建立、调整、插入、删除等操作的详解(题目讲解 简单易懂)
121 0
|
3月前
|
Java
使用Java实现合并两个数组[归并排序]
使用Java实现合并两个数组[归并排序]
|
4月前
|
人工智能 供应链 搜索推荐
①归并排序、快速排序 、堆排序、计数排序[算法、代码模板、面试题]
①归并排序、快速排序 、堆排序、计数排序[算法、代码模板、面试题]
56 0
|
11月前
|
Java C语言 C++
数据结构之排序【快速排序和归并排序的非递归代码实现及分析】
数据结构之排序【快速排序和归并排序的非递归代码实现及分析】
|
算法 搜索推荐 C语言
用或不用大O来优化代码(选择排序)
用或不用大O来优化代码(选择排序)
68 0
|
存储 算法 搜索推荐
【C语言程序设计】知识点汇总7——排序与查找原理与代码(冒泡排序,选择排序,插入排序,二分查找)
【C语言程序设计】知识点汇总7——排序与查找原理与代码(冒泡排序,选择排序,插入排序,二分查找)
134 0
|
算法 搜索推荐
基础的排序算法(选择,插入)
基础的排序算法(选择,插入)
|
机器学习/深度学习
快速排序的原理及代码
给定你一个长度为 nn 的整数数列。 请你使用快速排序对这个数列按照从小到大进行排序。 并将排好序的数列按顺序输出。
97 0
|
算法
【刷算法】合并两个排序的单链表
【刷算法】合并两个排序的单链表
|
存储 算法 搜索推荐
【排序算法】图解直接插入排序(图解堪比Debug显示每次循环结果)
本文主要介绍直接插入排序算法,通过图片一步步解释每一趟每一次的后移。代码通过C#实现,并输出每一次交换的情况和比较次数,方便各位小伙伴比较算法的优缺点。图解堪比Debug,一步步分析每次循环结果。
【排序算法】图解直接插入排序(图解堪比Debug显示每次循环结果)

热门文章

最新文章