排序算法分析 --- 快速排序

一 算法描述

假设有n个元素,现在要把这些元素按照从小到大的顺序进行排序,那么算法步骤如下,

  1. 选择中间位置的元素作为基准值(pivot value),其索引为( 0 + (n-1) ) / 2
  2. 从第0个元素开始从左往右找到比基准值大的元素,其索引为 i
  3. 从第n-1个元素开始从右往左找到比基准值小的元素,其索引为 j
  4. 交换这两个元素
  5. 从索引 i 开始,继续从左往右找到比基准值大的元素
  6. 从索引 j 开始,继续从右往左找到比基准值小的元素
  7. 交换这2个元素
  8. 继续查找交换,直到 i > j,即发生了相遇
  9. 根据 ij 这2个索引,把元素分成两部分,即[0, j]和[i, n-1],然后在这两个部分里继续进行步骤1~8的操作

ps:基准值不一定要选择中间位置的元素,可以选择任意位置的元素


二 C代码

void quickSort(int arr[], int left, int right)
{
    int i = left, j = right; // 对i和j进行初始化
    int pivot = arr[(left+right)/2]; // 基准值选择中间位置的元素
    int temp = 0;

    while (i <= j) // 跳出while循环说明i>j,而且i-j等于1
    {
        while (arr[i] < pivot && i <= right) // 从左到右,找到比pivot大的元素
            ++i;

        while (arr[j] > pivot && j >= left) // 从右到左,找到比pivot小的元素
            --j;

        if (i <= j) //进行交换操作
        {
            temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
            
            /* 一定要有这2步对i和j的更新,不然当i=j时while循环会无限执行下去 */
            ++i;
            --j;
            /******************************************************/
        }
    }
    //对[left, j]做快速排序
    if (left < j)
        quickSort(arr, left, j);
        
    //对[i, right]做快速排序
    if (right > i)
        quickSort(arr, i, right);
}

注释:

  • while循环结束后,i 大于 j,且 j-i 等于1,这样就把所有的元素分割成独立的2块,即[left, j]和[j, right],然后就可以进行递归操作继续排序
  • 假设有10个元素,那么该函数调用方式为quickSort(arr, 0, 9)

三 总结

快速排序使用了分而治之的思想,设计比较巧妙。理解的关键就是弄清从左到右和从右到左两个方向的查找和交换,以及这2个方向的相遇点。

如果有写的不对的地方,希望能留言指正,谢谢阅读。

猜你喜欢

转载自blog.csdn.net/whahu1989/article/details/83218072
今日推荐