快速排序---分治+代码解读

啊哈算法理解快速排序
文末进行关键代码解读

在这里插入图片描述

#include <stdio.h>
#include <stdlib.h>
int n,a[101];
void quicksort(int left,int right)
{
    int i,j,t,temp;
    if(left>right) return;
    temp=a[left];//temp中存的就是基准数
    i=left;
    j=right;
    while(i!=j)
        //这块循环的终止条件就是保证i==j
        //那么i左侧所有数据全部小于等于a[left];
        //i右侧所有数据全部大于a[left]
    {
        //顺序很重要,从右边开始找
        //为什么一定要先从右边往左边寻找呢?
        //往下看 有详解
        while(a[j]>=temp&&i<j)
            j--;
        while(a[i]<=temp&&i<j)
            i++;
        //如果i==j 说明j的左侧所有数据全部小于等于a[left]
        //那么i,j所停的位置就是a[left]要填入的位置
        if(i<j)
        {
            t=a[i];
            a[i]=a[j];
            a[i]=t;
        }
    }
    //基数归位
    a[left]=a[i];
    a[i]=temp;
    quicksort(left,i-1);//继续处理左边的
    quicksort(i+1,right);//继续处理右边的
}
int main()
{
    int i,j,t;
    scanf("%d",&n);
    for(i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
    }
    quicksort(1,n);//调用快速排序
    //输出排序后结果
    for(i=1;i<=n;i++)
        printf("%d ",a[i]);
    getchar();getchar();
    return 0;
}

为什么left位置是基准点 要从右向左寻找呢?
这么想 如果说先从左边开始寻找的话(我先拿具体例子说明)
!!那么i所停留的位置一定是大于a[left]值数据的位置或者是j位置!!
①停留在j位置:(5 4 3 2 1数据) 走到了j位置 那么i等于j跳出循环 之后a[left]=a[i]=1 a[i]=temp=5 显然不正确
② 如果说停留的位置是大于a[left]值数据的位置(例如6 1 2 7 9或者6 1 7 2 9)
如果是6 1 2 7 9的话,那么之后j向左移锁停留的位置一定也是7位置(由于i==j跳出循环),最终基数归位a[left]=a[i]=7 a[i]=temp=6 显然不正确
如果是6 1 7 2 9的话,我们发现最终结果是正确的

这是反例说明 其实从根上去想其中的逻辑的话,如果基准点是最左边,从左边遍开始寻找的话,它可以保证左边的数字都是小于基准值的,但是可能会造成i,j相遇时的位置元素是大于基准值的情况(结合上边实例思考),这时跳出循环,进行交换,是不是把大于基准值的那个值与基准值进行交换了呢??所以错误
而从右边开始寻找的话,它可以保证右边的数字都是大于基准值的,但是i,j相遇时的位置元素必定小于或等于基准值,这样再交换就是正确的了。

当然 如果你基准点在最右侧 就要从左边开始寻找了

————————————————————————
时间复杂度分析:
最好情况:每次划分对一个记录定位后 该记录的左侧子序列与右侧子序列的长度相同。在具有n个记录的序列中,一次划分需要对整个带划分序列扫描一遍,则所需时间为O(n)。
那么T(n)=2T(n/2)+n = 2(2T(n/4)+n/2))+n=4T(n/4)+2n
=8T(n/8)+3n

=nT(1)+nlgn=O(nlgn)
最坏情况下,待排序记录序列是正序或逆序,每次划分只得到一个比上一次划分少一个记录的子序列(另一个子序列为空)。这样子,必须经过n-1次递归调用才能把所有记录定位,第i次划分需要经过n-i次比较才能找到第i个记录的位置,时间复杂度为
i=1->i=n-1 每次(n-i)次求和=2/1 * n * (n-1)=O(n²)

平均情况:在这里插入图片描述
空间复杂度:O(logn)

发布了19 篇原创文章 · 获赞 2 · 访问量 751

猜你喜欢

转载自blog.csdn.net/qq_45639157/article/details/104750087
今日推荐