×

快速排序算法 排序 快速排序

快速排序算法(快速排序的算法实现)

admin admin 发表于2022-09-07 16:50:18 浏览154 评论0

抢沙发发表评论

本文目录

快速排序的算法实现


#include《iostream》
using namespace std;
const int n=10;
void input(int a,int n)
{
for(int i=0;i《n;++i)
a[i]=rand()%100;
}
void print(int a,int n)
{
for(int i=0;i《n;++i)
cout《《a[i]《《’\t’;
cout《《endl;
}
int p(int a,int l,int r)
{
int i=l,j=r; //初始化
while(i《j)
{
while(i《j&&a[i]《a[j]) j--; //右侧扫描
if(i《j)
{
swap(a[i],a[j]);//将较小记录交换到前面
i++;
}
while(i《j&&a[i]《a[j]) i++;//左侧扫描
if(i《j)
{
swap(a[j],a[i]);//将较大记录交换到后面
j--;
}
}
return i; // i位轴值记录的最终位置
}
void quicksort(int a,int l,int r)
{
if(l《r)
{
int pivot=p(a,l,r); //一次划分
quicksort(a,l,pivot-1);//递归对左侧子序列快排
quicksort(a,pivot+1,r);//递归对右侧子序列快排
}
}
int main()
{
int a[n];
input(a, n);
print(a, n);
quicksort(a, 0,n-1);
print(a, n);
return 0;
}

C语言的快速排序的算法是什么啊


快速排序(Quicksort)是对冒泡排序的一种改进。由C. A. R. Hoare在1962年提出。它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。 算法过程  设要排序的数组是A……A[N-1],首先任意选取一个数据(通常选用第一个数据)作为关键数据,然后将所有比它小的数都放到它前面,所有比它大的数都放到它后面,这个过程称为一趟快速排序。值得注意的是,快速排序不是一种稳定的排序算法,也就是说,多个相同的值的相对位置也许会在算法结束时产生变动。   一趟快速排序的算法是:   1)设置两个变量I、J,排序开始的时候:I=0,J=N-1;   2)以第一个数组元素作为关键数据,赋值给key,即 key=A;   3)从J开始向前搜索,即由后开始向前搜索(J=J-1),找到第一个小于key的值A[J],并与key交换;   4)从I开始向后搜索,即由前开始向后搜索(I=I+1),找到第一个大于key的A[I],与key交换;   5)重复第3、4、5步,直到 I=J; (3,4步是在程序中没找到时候j=j-1,i=i+1,直至找到为止。找到并交换的时候i, j指针位置不变。另外当i=j这过程一定正好是i+或j-完成的最后另循环结束。)   例如:待排序的数组A的值分别是:(初始关键数据:X=49) 注意关键X永远不变,永远是和X进行比较,无论在什么位子,最后的目的就是把X放在中间,小的放前面大的放后面。   A A A A A A A:   49 38 65 97 76 13 27   进行第一次交换后:27 38 65 97 76 13 49   ( 按照算法的第三步从后面开始找)   进行第二次交换后:27 38 49 97 76 13 65   ( 按照算法的第四步从前面开始找》X的值,65》49,两者交换,此时:I=3 )   进行第三次交换后:27 38 13 97 76 49 65   ( 按照算法的第五步将又一次执行算法的第三步从后开始找   进行第四次交换后:27 38 13 49 76 97 65   ( 按照算法的第四步从前面开始找大于X的值,97》49,两者交换,此时:I=4,J=6 )   此时再执行第三步的时候就发现I=J,从而结束一趟快速排序,那么经过一趟快速排序之后的结果是:27 38 13 49 76 97 65,即所有大于49的数全部在49的后面,所有小于49的数全部在49的前面。   快速排序就是递归调用此过程——在以49为中点分割这个数据序列,分别对前面一部分和后面一部分进行类似的快速排序,从而完成全部数据序列的快速排序,最后把此数据序列变成一个有序的序列,根据这种思想对于上述数组A的快速排序的全过程如图6所示:   初始状态 {49 38 65 97 76 13 27}   进行一次快速排序之后划分为 {27 38 13} 49 {76 97 65}   分别对前后两部分进行快速排序 {27 38 13} 经第三步和第四步交换后变成 {13 27 38} 完成排序。   {76 97 65} 经第三步和第四步交换后变成 {65 76 97} 完成排序。   

快速排序算法的示例代码


    using System;     using System.Collections.Generic;     using System.Linq;     using System.Text;    namespace test{    class QuickSort    {        static void Main(string args)        {            int array = { 49, 38, 65, 97, 76, 13, 27 };            sort(array, 0, array.Length - 1);            Console.ReadLine();        }        /**一次排序单元,完成此方法,key左边都比key小,key右边都比key大。         **@param array排序数组          **@param low排序起始位置          **@param high排序结束位置         **@return单元排序后的数组 */        private static int sortUnit(int array, int low, int high)        {            int key = array[low];            while (low 《 high)            {                /*从后向前搜索比key小的值*/                while (array[high] 》= key && high 》 low)                    --high;                 /*比key小的放左边*/                array[low] = array[high];                   /*从前向后搜索比key大的值,比key大的放右边*/                while (array[low] 《= key && high 》 low)                    ++low;                 /*比key大的放右边*/                array[high] = array[low];            }            /*左边都比key小,右边都比key大。//将key放在游标当前位置。//此时low等于high */            array[low] = key;            foreach (int i in array)            {                Console.Write({0}\t, i);            }            Console.WriteLine();            return high;        }            /**快速排序 *@paramarry *@return */        public static void sort(int array, int low, int high)        {            if (low 》= high)                return;             /*完成一次单元排序*/            int index = sortUnit(array, low, high);             /*对左边单元进行排序*/            sort(array, low, index - 1);            /*对右边单元进行排序*/            sort(array, index + 1, high);        }    }} 运行结果:27 38 13 49 76 97 65
13 27 38 49 76 97 65  13 27 38 49 65 76 97
快速排序就是递归调用此过程——在以49为中点分割这个数据序列,分别对前面一部分和后面一部分进行类似的快速排序,从而完成全部数据序列的快速排序,最后把此数据序列变成一个有序的序列,根据这种思想对于上述数组A的快速排序的全过程如图6所示:
初始状态 {49 38 65 97 76 13 27} 进行一次快速排序之后划分为 {27 38 13} 49 {76 97 65} 分别对前后两部分进行快速排序{27 38 13} 经第三步和第四步交换后变成 {13 27 38} 完成排序。{76 97 65} 经第三步和第四步交换后变成 {65 76 97} 完成排序。图示 快速排序的最坏情况基于每次划分对主元的选择。基本的快速排序选取第一个元素作为主元。这样在数组已经有序的情况下,每次划分将得到最坏的结果。一种比较常见的优化方法是随机化算法,即随机选取一个元素作为主元。这种情况下虽然最坏情况仍然是O(n^2),但最坏情况不再依赖于输入数据,而是由于随机函数取值不佳。实际上,随机化快速排序得到理论最坏情况的可能性仅为1/(2^n)。所以随机化快速排序可以对于绝大多数输入数据达到O(nlogn)的期望时间复杂度。一位前辈做出了一个精辟的总结:“随机化快速排序可以满足一个人一辈子的人品需求。”
随机化快速排序的唯一缺点在于,一旦输入数据中有很多的相同数据,随机化的效果将直接减弱。对于极限情况,即对于n个相同的数排序,随机化快速排序的时间复杂度将毫无疑问的降低到O(n^2)。解决方法是用一种方法进行扫描,使没有交换的情况下主元保留在原位置。 QUICKSORT(A,p,r)
1 if p《r
2 then q ←PARTITION(A,p,r)
3 QUICKSORT(A,p,q-1)
4 QUICKSORT(A,q+1,r)
为排序一个完整的数组A,最初的调用是QUICKSORT(A,1,length[A])。
快速排序算法的关键是PARTITION过程,它对子数组A[p..r]进行就地重排:
PARTITION(A,p,r)
1 x←A[r]
2 i←p-1
3 for j←p to r-1
4 do if A[j]≤x
5 then i←i+1
6 exchange A[i]←→A[j]
7 exchange A[i+1]←→A[r]
8 return i+1 对PARTITION和QUICKSORT所作的改动比较小。在新的划分过程中,我们在真正进行划分之前实现交换:
(其中PARTITION过程同快速排序伪代码(非随机))
RANDOMIZED-PARTITION(A,p,r)
1 i← RANDOM(p,r)
2 exchange A[r]←→A[i]
3 return PARTITION(A,p,r)
新的快速排序过程不再调用PARTITION,而是调用RANDOMIZED-PARTITION。
RANDOMIZED-QUICKSORT(A,p,r)
1 if p《r
2 then q← RANDOMIZED-PARTITION(A,p,r)
3 RANDOMIZED-QUICKSORT(A,p,q-1)
4 RANDOMIZED-QUICKSORT(A,q+1,r) 这里为方便起见,我们假设算法Quick_Sort的范围阈值为1(即一直将线性表分解到只剩一个元素),这对该算法复杂性的分析没有本质的影响。
我们先分析函数partition的性能,该函数对于确定的输入复杂性是确定的。观察该函数,我们发现,对于有n个元素的确定输入L[p..r],该函数运行时间显然为θ(n)。
最坏情况
无论适用哪一种方法来选择pivot,由于我们不知道各个元素间的相对大小关系(若知道就已经排好序了),所以我们无法确定pivot的选择对划分造成的影响。因此对各种pivot选择法而言,最坏情况和最好情况都是相同的。
我们从直觉上可以判断出最坏情况发生在每次划分过程产生的两个区间分别包含n-1个元素和1个元素的时候(设输入的表有n个元素)。下面我们暂时认为该猜测正确,在后文我们再详细证明该猜测。
对于有n个元素的表L[p..r],由于函数Partition的计算时间为θ(n),所以快速排序在序坏情况下的复杂性有递归式如下:
T(1)=θ(1),T(n)=T(n-1)+T(1)+θ(n) (1)
用迭代法可以解出上式的解为T(n)=θ(n2)。
这个最坏情况运行时间与插入排序是一样的。
下面我们来证明这种每次划分过程产生的两个区间分别包含n-1个元素和1个元素的情况就是最坏情况。
设T(n)是过程Quick_Sort作用于规模为n的输入上的最坏情况的时间,则
T(n)=max(T(q)+T(n-q))+θ(n),其中1≤q≤n-1 (2)
我们假设对于任何k《n,总有T(k)≤ck,其中c为常数;显然当k=1时是成立的。
将归纳假设代入(2),得到:
T(n)≤max(cq2+c(n-q)2)+θ(n)=c*max(q2+(n-q)2)+θ(n)
因为在[1,n-1]上q2+(n-q)2关于q递减,所以当q=1时q2+(n-q)2有最大值n2-2(n-1)。于是有:
T(n)≤cn2-2c(n-1)+θ(n)≤cn2
只要c足够大,上面的第二个小于等于号就可以成立。于是对于所有的n都有T(n)≤cn。
这样,排序算法的最坏情况运行时间为θ(n2),且最坏情况发生在每次划分过程产生的两个区间分别包含n-1个元素和1个元素的时候。
时间复杂度为o(n2)。
最好情况
如果每次划分过程产生的区间大小都为n/2,则快速排序法运行就快得多了。这时有:
T(n)=2T(n/2)+θ(n),T(1)=θ(1) (3)
解得:T(n)=θ(nlogn)
快速排序法最佳情况下执行过程的递归树如下图所示,图中lgn表示以10为底的对数,而本文中用logn表示以2为底的对数.
由于快速排序法也是基于比较的排序法,其运行时间为Ω(nlogn),所以如果每次划分过程产生的区间大小都为n/2,则运行时间θ(nlogn)就是最好情况运行时间。
但是,是否一定要每次平均划分才能达到最好情况呢?要理解这一点就必须理解对称性是如何在描述运行时间的递归式中反映的。我们假设每次划分过程都产生9:1的划分,乍一看该划分很不对称。我们可以得到递归式:
T(n)=T(n/10)+T(9n/10)+θ(n),T(1)=θ(1) (4)
请注意树的每一层都有代价n,直到在深度log10n=θ(logn)处达到边界条件,以后各层代价至多为n。递归于深度log10/9n=θ(logn)处结束。这样,快速排序的总时间代价为T(n)=θ(nlogn),从渐进意义上看就和划分是在中间进行的一样。事实上,即使是99:1的划分时间代价也为θ(nlogn)。其原因在于,任何一种按常数比例进行划分所产生的递归树的深度都为θ(nlogn),其中每一层的代价为O(n),因而不管常数比例是什么,总的运行时间都为θ(nlogn),只不过其中隐含的常数因子有所不同。(关于算法复杂性的渐进阶,请参阅算法的复杂性)
平均情况
快速排序的平均运行时间为θ(nlogn)。
我们对平均情况下的性能作直觉上的分析。
要想对快速排序的平均情况有个较为清楚的概念,我们就要对遇到的各种输入作个假设。通常都假设输入数据的所有排列都是等可能的。后文中我们要讨论这个假设。
当我们对一个随机的输入数组应用快速排序时,要想在每一层上都有同样的划分是不太可能的。我们所能期望的是某些划分较对称,另一些则很不对称。事实上,我们可以证明,如果选择L[p..r]的第一个元素作为支点元素,Partition所产生的划分80%以上都比9:1更对称,而另20%则比9:1差,这里证明从略。
平均情况下,Partition产生的划分中既有“好的”,又有“差的”。这时,与Partition执行过程对应的递归树中,好、差划分是随机地分布在树的各层上的。为与我们的直觉相一致,假设好、差划分交替出现在树的各层上,且好的划分是最佳情况划分,而差的划分是最坏情况下的划分。在根节点处,划分的代价为n,划分出来的两个子表的大小为n-1和1,即最坏情况。在根的下一层,大小为n-1的子表按最佳情况划分成大小各为(n-1)/2的两个子表。这儿我们假设含1个元素的子表的边界条件代价为1。
在一个差的划分后接一个好的划分后,产生出三个子表,大小各为1,(n-1)/2和(n-1)/2,代价共为2n-1=θ(n)。一层划分就产生出大小为(n-1)/2+1和(n-1)/2的两个子表,代价为n=θ(n)。这种划分差不多是完全对称的,比9:1的划分要好。从直觉上看,差的划分的代价θ(n)可被吸收到好的划分的代价θ(n)中去,结果是一个好的划分。这样,当好、差划分交替分布划分都是好的一样:仍是θ(nlogn),但θ记号中隐含的常数因子要略大一些。关于平均情况的严格分析将在后文给出。
在前文从直觉上探讨快速排序的平均性态过程中,我们已假定输入数据的所有排列都是等可能的。如果输入的分布满足这个假设时,快速排序是对足够大的输入的理想选择。但在实际应用中,这个假设就不会总是成立。
解决的方法是,利用随机化策略,能够克服分布的等可能性假设所带来的问题。
一种随机化策略是:与对输入的分布作“假设”不同的是对输入的分布作“规定”。具体地说,在排序输入的线性表前,对其元素加以随机排列,以强制的方法使每种排列满足等可能性。事实上,我们可以找到一个能在O(n)时间内对含n个元素的数组加以随机排列的算法。这种修改不改变算法的最坏情况运行时间,但它却使得运行时间能够独立于输入数据已排序的情况。
另一种随机化策略是:利用前文介绍的选择支点元素pivot的第四种方法,即随机地在L[p..r]中选择一个元素作为支点元素pivot。实际应用中通常采用这种方法。
快速排序的随机化版本有一个和其他随机化算法一样的有趣性质:没有一个特别的输入会导致最坏情况性态。这种算法的最坏情况性态是由随机数产生器决定的。你即使有意给出一个坏的输入也没用,因为随机化排列会使得输入数据的次序对算法不产生影响。只有在随机数产生器给出了一个很不巧的排列时,随机化算法的最坏情况性态才会出现。事实上可以证明几乎所有的排列都可使快速排序接近平均情况性态,只有非常少的几个排列才会导致算法的近最坏情况性态。
一般来说,当一个算法可按多条路子做下去,但又很难决定哪一条保证是好的选择时,随机化策略是很有用的。如果大部分选择都是好的,则随机地选一个就行了。通常,一个算法在其执行过程中要做很多选择。如果一个好的选择的获益大于坏的选择的代价,那么随机地做一个选择就能得到一个很有效的算法。我们在前文已经了解到,对快速排序来说,一组好坏相杂的划分仍能产生很好的运行时间 。因此我们可以认为该算法的随机化版本也能具有较好的性态。-快速排序


用C语言编写一个快速排序算法 输入10个数


1、“快速排序法”使用的是递归原理,下面一个例子来说明“快速排序法”的原理。首先给出一个数组{53,12,98,63,18,72,80,46, 32,21},先找到第一个数--53,把它作为中间值,也就是说,要把53放在一个位置,使得它左边的值比它小,右边的值比它大。{21,12,32, 46,18,53,80,72,63,98},这样一个数组的排序就变成了两个小数组的排序--53左边的数组和53右边的数组,而这两个数组继续用同样的方式继续下去,一直到顺序完全正确。一般来说,冒泡法是程序员最先接触的排序方法,它的优点是原理简单,编程实现容易,但它的缺点就是速度太慢。
2、快速排序代码:-排序

#include《stdio.h》
void quicksort(int a,int left,int right)
{
    int i,j,temp;
    i=left;
    j=right;
    temp=a[left];
    if(left》right)
        return;
    while(i!=j)
    {
        while(a[j]》=temp&&j》i)
            j--;
        if(j》i)
            a[i++]=a[j];
        while(a[i]《=temp&&j》i)
            i++;
        if(j》i)
            a[j--]=a[i];
        
    }
    a[i]=temp;
    quicksort(a,left,i-1);
    quicksort(a,i+1,right);
}
void main()
{
    int a={53,12,98,63,18,72,80,46,32,21};
    int i;
    quicksort(a,0,9);
    /*排好序的结果*/
    for(i=0;i《10;i++)
        printf(“%4d\n“,a[i]);
}
-快速排序

按键精灵快速排序(比冒泡更快更有效率的算法)是怎么样的


冒泡排序为O(N^2),在排序过程中其实是效率较低的。在扫拍卖或者其他需要比拼速度的时候,时间就是金钱~越快越能抢占先机。
今天我们介绍另一种更快更有效率的排序——快速排序,时间复杂度为O(n*logn)。
快速排序的算法思想
快速排序采用了一种分治的策略,通常称其为分治法(Divide-and-ConquerMethod)。
该方法的基本思想是:
1.先从数列中取出一个数作为基准数。(不要被这个名词吓到了,就是一个用来参照的数,待会你就知道它用来做啥的了)。
2.分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。
3 . 再对左右区间重复第二步,直到各区间只有一个数。
白话讲解算法:
假设我们现在对“6 1 2 7 9 3 4 5 10 8”这个10个数进行排序。就让第一个数6作为基准数吧。接下来,需要将这个序列中所有比基准数大的数放在6的右边,比基准数小的数放在6的左边。
方法其实很简单:分别从初始序列“6 1 2 7 9 3 4 5 10 8”两端开始“探测”。先从右往左找一个小于6的数,再从左往右找一个大于6的数,然后交换他们。这里可以用两个变量i和j,分别指向序列最左边和最右边。我们为这两个变量起个好听的名字“哨兵i”和“哨兵j”。刚开始的时候让哨兵i指向序列的最左边(即i=1),指向数字6。让哨兵j指向序列的最右边(即=10),指向数字。
2014-8-29 13:45 上传
下载附件 (9.51 KB)
首先哨兵j开始出动。因为此处设置的基准数是最左边的数,所以需要让哨兵j先出动,这一点非常重要(请自己想一想为什么)。哨兵j一步一步地向左挪动(即j--),直到找到一个小于6的数停下来。接下来哨兵i再一步一步向右挪动(即i++),直到找到一个数大于6的数停下来。最后哨兵j停在了数字5面前,哨兵i停在了数字7面前。
2014-8-29 13:45 上传
下载附件 (9.74 KB)
2014-8-29 13:45 上传
下载附件 (8.13 KB)
现在交换哨兵i和哨兵j所指向的元素的值。交换之后的序列如下:
6 1 2 5 9 3 4 7 10 8
2014-8-29 13:45 上传
下载附件 (9.74 KB)
2014-8-29 13:45 上传
下载附件 (8.37 KB)
到此,第一次交换结束。接下来开始哨兵j继续向左挪动(再友情提醒,每次必须是哨兵j先出发)。他发现了4(比基准数6要小,满足要求)之后停了下来。哨兵i也继续向右挪动的,他发现了9(比基准数6要大,满足要求)之后停了下来。此时再次进行交换,交换之后的序列如下:
6 1 2 5 4 3 9 7 10 8
第二次交换结束,“探测”继续。哨兵j继续向左挪动,他发现了3(比基准数6要小,满足要求)之后又停了下来。哨兵i继续向右移动,糟啦!此时哨兵i和哨兵j相遇了,哨兵i和哨兵j都走到3面前。说明此时“探测”结束。我们将基准数6和3进行交换。交换之后的序列如下:
3 1 2 5 4 6 9 7 10 8
2014-8-29 13:45 上传
下载附件 (8.28 KB)
2014-8-29 13:45 上传
下载附件 (10.45 KB)
2014-8-29 13:45 上传
下载附件 (8.48 KB)
到此第一轮“探测”真正结束。此时以基准数6为分界点,6左边的数都小于等于6,6右边的数都大于等于6。回顾一下刚才的过程,其实哨兵j的使命就是要找小于基准数的数,而哨兵i的使命就是要找大于基准数的数,直到i和j碰头为止。
OK,解释完毕。现在基准数6已经归位,它正好处在序列的第6位。
3

1

2

5

4

6

9

7

10

8
此时我们已经将原来的序列,以6为分界点拆分成了两个序列,左边的序列是“3 1 2 5 4”,右边的序列是“9 7 10 8”。接下来还需要分别处理这两个序列。因为6左边和右边的序列目前都还是很混乱的。不过不要紧,我们已经掌握了方法,接下来只要模拟刚才的方法分别处理6左边和右边的序列即可。现在先来处理6左边的序列现吧。
左边的序列是“3 1 2 5 4”。请将这个序列以3为基准数进行调整,使得3左边的数都小于等于3,3右边的数都大于等于3。
3

1

2

5

4
第一次交换完:以3为分界点,拆分了两个序列。左边都比3小,右边都比3大。
2

1

3

5

4
再分别处理3左右的两个序列“2 1”和“5 4”
1

2

3

4

5
这样,最初我们划分的6左侧的序列都已经处理好了~~我们再来处理6右侧的序列
9

7

10

8
以9为基准数,第一次交换完:
9

7

8

10
第二次交换:
8

7

9

10
再交换一次:
7

8

9

10
这样,我们整个序列就排序完毕了
1

2

3

4

5

6

7

8

9

10
快排算法代码实现:
su = “6|1|2|7|9|3|4|5|10|8“
su=Split(su, “|“)
L = UBound(su)
Call ks(0, L)
Function ks(L, B)
If L 》 B Then
Exit Function
End If //判断数组上标下标是否超出范围
i = L
j = B
key =int( su(L) ) //数组第一位提取作为基数
While j》i
While int ( su(j)) 》= key and j 》 i //要先从最右边开始找 找到第一个小于key的数 这里添加的j》i的判断是为了防止j的值不断递减导致下标越界
j = j - 1
Wend
While int (su(i)) 《= key and j 》 i //从最左边开始找 找到第一个大于key的数 (这里的字符串数组需要转换为数值型)
i = i + 1
Wend
If j》i then // 将和基数key对比得到的两个数对换 将大于key的值往右边放 小于key的值往左边放
T = su(i)
su(i) = su(j)
su(j) = T
End If
Wend // 这个 While 循环当i=j 第一轮比较完退出
su(L) = su(i) // 重新设置数组第一个元素为基数
su(i) = key// 基数归位 (排完一轮之后 左边的数《基数《右边的数 那么基数就到了排序中它该在的位置。)
Call ks(L, i - 1)//继续处理左边的数
Call ks(i + 1, B)//继续处理右边的数
End Function
For i = 0 To UBound(su)
TracePrint su(i)
Next
-排序

C语言快速排序的代码


首先我赞成你直接要代码的这种方法。
从你这个提问可以看出你对常用的排序算法都接触过,并且都没搞懂到底是怎么回事。
现在的电子平台资源都很丰富了,硬件平台的运行速度可以做到很高了,在大多数的情况下可以考虑用空间换时间的方法,也就是说你应该先搞懂算法的本质,然后再自己去实现它,开始的时候可以不考虑时间上的损耗。
排序的本质就是两个数比较大小,并根据其大小将其放到相应的位置。
记住其本质是什么,你自己绝对可以使用相应的语言实现它。
-快速排序

c语言快速排序 谁能给我讲讲下面的代码啥意思


设要排序的数组是A……A[N-1],首先任意选取一个数据(通常选用数组的第一个数)作为关键数据,
然后将所有比它小的数都放到它前面,所有比它大的数都放到它后面,这个过程称为一趟快速排序。
值得注意的是,快速排序不是一种稳定的排序算法,也就是说,
多个相同的值的相对位置也许会在算法结束时产生变动。
一趟快速排序的算法是:
1)设置两个变量i、j,排序开始的时候:i=0,j=N-1;
2)以第一个数组元素作为关键数据,赋值给key,即key=A;
3)从j开始向前搜索,即由后开始向前搜索(j--),找到第一个小于key的值A[j],将A[j]和A[i]互换;
4)从i开始向后搜索,即由前开始向后搜索(i++),找到第一个大于key的A[i],将A[i]和A[j]互换;
5)重复第3、4步,直到i=j; (3,4步中,没找到符合条件的值,即3中A[j]不小于key,
4中A[i]不大于key的时候改变j、i的值,使得j=j-1,i=i+1,直至找到为止。
找到符合条件的值,进行交换的时候i, j指针位置不变。
另外,i==j这一过程一定正好是i+或j-完成的时候,此时令循环结束)。
-排序

用C语言编程实现快速排序算法


给个快速排序你参考参考

/********************** 快速排序 ****************************
基本思想:在待排序的n个记录中任取一个记录(通常取第一个记录),
  以该记录为基准,将当前的无序区划分为左右两个较小的无
  序子区,使左边的记录均小于基准值,右边的记录均大于或
  等于基准值,基准值位于两个无序区的中间位置(即该记录
  最终的排序位置)。之后,分别对两个无序区进行上述的划
  分过程,直到无序区所有记录都排序完毕。
*************************************************************/
/*************************************************************
函数名称:static void swap(int *a, int *b)
参    数:int *a---整型指针
  int *b---整型指针
功    能:交换两个整数的位置
返 回 值:无
说    明:static关键字指明了该函数只能在本文件中使用
**************************************************************/
static void swap(int *a, int *b)
{  
    int temp = *a;
    *a = *b;
    *b = temp;
}
int quickSortNum = 0; // 快速排序算法所需的趟数
/*************************************************************
函数名称:static int partition(int a, int low, int high)
参    数:int a---待排序的数据
  int low---无序区的下限值
  int high---无序区的上限值
功    能:完成一趟快速排序
返 回 值:基准值的最终排序位置
说    明:static关键字指明了该函数只能在本文件中使用
**************************************************************/
static int partition(int a, int low, int high)
{
    int privotKey = a[low];  //基准元素
    while(low 《 high)
{   //从表的两端交替地向中间扫描  
        while(low 《 high  && a[high] 》= privotKey)   // 找到第一个小于privotKey的值
high--;  //从high所指位置向前搜索,至多到low+1位置  
        swap(&a[low], &a[high]);  // 将比基准元素小的交换到低端
        while(low 《 high  && a[low] 《= privotKey)   // 找到第一个大于privotKey的值
low++;  //从low所指位置向后搜索,至多到high-1位置
        swap(&a[low], &a[high]);  // 将比基准元素大的交换到高端
    }
quickSortNum++;  // 快速排序趟数加1
return low;  // 返回基准值所在的位置
}  
/*************************************************************
函数名称:void QuickSort(int a, int low, int high)
参    数:int a---待排序的数据
  int low---无序区的下限值
  int high---无序区的上限值
功    能:完成快速排序算法,并将排序完成的数据存放在数组a中
返 回 值:无
说    明:使用递归方式完成
**************************************************************/
void QuickSort(int a, int low, int high)
{  
    if(low 《 high)
{
        int privotLoc = partition(a, low, high); // 将表一分为二  
        QuickSort(a, low, privotLoc-1);          // 递归对低子表递归排序  
        QuickSort(a, privotLoc+1, high);         // 递归对高子表递归排序  
    }
}
-快速排序

c++快速排序算法代码


1.将i 和j分别指向待排序区域的最左侧记录和最右侧记录的位置;
2.重复下述过程,直到i=j
2.1右侧扫描,直到记录j的关键码小于基准记录的关键码;
2.2 如果i《j,则将r[j]与r[i]交换,并将i++;
2.3左侧扫描,直到记录i的关键码大于基准记录的关键码;
2.4 如果i《j,则将r[i]与r[j]交换,并将j--;
3.退出循环,说明i和j指向了基准记录所在位置,返回该位置;
void QuickSort(int r[ ], int first, int end)
{
if (first《end) { //递归结束
pivot=Partition(r, first, end); //一次划分
QuickSort(r, first, pivot-1); //递归地对左侧子序列进行快速排序
QuickSort(r, pivot+1, end); //递归地对右侧子序列进行快速排序
}
}
int Partition(int r[ ], int first, int end)
{
i=first; j=end; //初始化
while (i《j)
{
while (i《j && r[i]《= r[j]) j--; //右侧扫描
if (i《j) {
r[i]←→r[j]; //将较小记录交换到前面
i++;
}
while (i《j && r[i]《= r[j]) i++; //左侧扫描
if (i《j) {
r[j]←→r[i]; //将较大记录交换到后面
j--;
}
}
retutn i; //i为轴值记录的最终位置
}
-排序

C语言,快速排序算法


你好!
首先 0 ,n-1 。应该是 数组的坐标(因为n个数字。所以数组的坐标是0 到n-1)
而a是你传入的数组。所以他会根据数组的坐标到数组中找到元素。比较并进行排序。
递归这段理解如下:
首先要了解快速排序的思想:
1)随意找一个基准数 。将比基准小的都放到它左边。比它大的都放到它右边。所以当返回基准的坐标的时候。其实这个坐标左边都是小于它的,右边都是大于等于它的。(这里主要是看代码的实现。图中代码是大于等于在右边。也可以自己写小于等于在左边。这个不影响最后结果)
2)那么第二次对于返回基准坐标的左右两边。我们同样利用返回的基准坐标找到两个“基准”(如下图)。就会使得返回的这两个基准左右两边有序
第三次  用返回的两个基准找到四个基准(如图)
然后不断递归..不断的在整体有序的情况下使局部变的有序。
假设 为  532348789
第一次以a【0】 5为基准 。
则:

图中红色标识为基准元素 最后会使得数组全局有序。
希望能对你有所帮助。
-快速排序