快速排序算法

快速排序:

1、选取基准数(这里以序列的第一个元素为基准数)。分配 左、右指针(左指针一开始指向序列的最左端,即 left = 0,右指针一开始指向序列的最右端,即 right = nums.Length - 1)

2、右指针先往左走,当右指针指向元素比基准数小时,将该元素放到左指针指向的位置(这么做是为了把该数放到基准数的左边)

3、右指针把元素放到左指针位置后,左指针开始向右走。当左指针指向元素比基准数大时,把该元素放到右指针的位置。

4、填了右边的空缺后,右指针继续向左移动,开始填左边的空缺,填了左边 接着填右边,填了右边 接着填左边,直到 左指针 与 右指针相遇,此时 两个指针共同指向的位置是一个 “空缺”,我们把基准数 “填” 到该 “空缺” 中,这样 基准数 左边的元素都小于基准数,基准数右边的元素都大于基准数,基准数排序到了争取的位置。

5、基准数把序列分成了 左序列 和 右序列,递归地对 左序列 和 右序列 执行上面的步骤。这样,每排序出一个基准数,就会把序列分的更细。

终止条件:当前被分离的序列长度只有 1 时,就无需再排序了。

//快排就是给基准元素找位置的过程
private static void quickSort(int[] arr, int low, int high) {
    //递归的终止条件
    if(low>high) return;
    //找出基准元素的位置
    int index = getIndex(arr,low,high);
    //进行迭代对index之前和之后的数组进行相同的操作使整个数组变成有序
    quickSort(arr,low,index-1);
    quickSort(arr,index+1,high);
}

//目标是将比基准元素大的数据放到基准元素的右边,把比基准元素小的数据放到基准元素的左边
//当两个指针重合时就是基准元素的位置
private static int getIndex(int[] arr, int low, int high) {
    //利用一个临时变量,将基准数据保存下来
    int tmp = arr[low];

    while (low<high){
        //先从后到前进行扫描,如果尾部的元素大于等于基准数据tmp,就将high--
        while (low<high && arr[high]>=tmp){
            high--;
        }
        //否则如果尾部元素小于tmp了,需要将其赋值给low
        arr[low] = arr[high];

        //再从后向前进行扫描,如果头部的元素小于等于基准数据tmp,就将low++
        while (low<high && arr[low]<=tmp){
            low++;
        }
        //否则如果头部元素大于tmp了,需要将其赋值给low
        arr[high] = arr[low];
    }
    //退出循环后,说明此时high==low,让基准数组赋值给当前值
    arr[low] = tmp;
    //返回基准位置,此事比基准数据大的都在基准数据的右边,比它小的都在左边
    return low;
}

你可能感兴趣的:(剑指Offer)