数据结构与算法基础(王卓)(35):交换排序之快排【第二阶段:标准答案、初步发现问题】

目录

第二阶段:一分为二

整个快排算法的程序运行大框架:

做出的改动(和原来程序的区别):

 Project 1:

PPT标准答案:

 Project 1小问题:

 Project 1还存在着一个巨大的问题:

具体问题:

具体深挖解决问题建下节



第二阶段:一分为二

分别对该表划分为的两个子表分别进行该遍历排序操作,再划分为更细分的子表

直至子表单位为1(一个元素)为止

没错,他说的也有道理,我上面写的操作,

其实只能对整张表的第一个元素进行操作,未免有些不太灵活

按他的思路基于上面写的程序进行修改,并补充完整快排算法的整个框架程序:


整个快排算法的程序运行大框架:

  1. 确定中枢
  2. 对前半个表进行遍历(嵌套递归我们对整个表的算法操作)
  3. 对后半个表进行遍历

做出的改动(和原来程序的区别):

传入int low,int high两个元素:

确定(限制)整个程序该循环内所能进行操作改动的范围


L.r[0]初值改为 L.r[low]:


让这个遍历的函数变得更加灵活,不必每次都只能对第一个元素进行比较遍历


函数的功能定制为:

  • 操作的数据范围为:high到low
  • 用来作为程序比较遍历的对象为:传入的low的初值

 Project 1:

int 遍历(SqList &L, int low, int high)
{
    L.r[0] = L.r[low];
    while (low < high)
    {
        if (L.r[high].key < L.r[0].key)
        {
            L.r[low] = L.r[high];
            low++;
        }
        else
            high--;
        if (L.r[0].key < L.r[low].key)
        {
            L.r[high] = L.r[low];
            high--;
        }
        else
            low++;
    }
    L.r[low] = L.r[high] = L.r[0];
    return low;
}

void QuickSort(SqList& L, int low, int high)
{
    int pivot = 遍历(L, low, high);
    QuickSort(L, low, pivot-1);
    QuickSort(L, pivot + 1, high);
}

然后这个时候我本以为我们写的已经差不多了,然后去看了一下标准答案:


PPT标准答案:

int Partition(SqList& L, int low, int high)
{
    L.r[0] = L.r[low];  //复制到哨兵位置
    KeyType pivotkey = L.r[low].key;
    while (low < high) 
    {
        while (low < high && L.r[high].key >= pivotkey)
            high--;  
        L.r[low] = L.r[high];

        while (low < high && L.r[low].key < pivotkey)
            low++;
        L.r[high] = L.r[low];

    }
    L.r[low] = L.r[0];
    return low;
}

void QuickSort(SqList& L, int low, int high) {
    if (low < high)
    {
        int pivotloc = Partition(L, low, high);  //将L一份为二
        QuickSort(L, low, pivotloc - 1);  //对低子表递归排序
        QuickSort(L, pivotloc + 1, high);  //对高子表递归排序
    }
}

OK,本来我也觉得不以为然,乍一看没什么大问题了,只剩下一个无伤大雅的


 Project 1小问题:

补充条件语句:快排要求必须 (low < high)

结果到整的去尝试了一下带入实例了以后发现


 Project 1还存在着一个巨大的问题:

具体问题:

运行逻辑机制问题,我们就拿PPT上的实例来说事吧:

将逐次具体操作转化为表格展示如下: 

第几步 操作 Low指向 High指向
第1步 49变哨兵 1 8
第2步

49'不动,high--(第一个 if / else 判断)

1 7
第3步 49不动,low++(第二个 if / else 判断) 2 7


这里到了第三步,明显就开始出问题了:

空格里面还没有元素呢,你这个算法就开始超过他、跳跃到下一格,干什么?

重复比较无伤大雅,但是low移动了,危险!!!(要出错了)

这里很明显,我们可以看到,问题出在:

在第一个处理的元素被放到哨兵里后,我们又去拿这个元素本身比较哨兵

也就是自己比较自己,错过了这个空格;

而不是用这个空格来装第一个小于哨兵的元素

具体深挖解决问题见下节

猜你喜欢

转载自blog.csdn.net/Zz_zzzzzzz__/article/details/130514255