【算法】——快速排序算法的详解,并使用Python、Java代码实现

快速排序法

基本思想:通过一趟排序,将待排序记录分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,然后分别对这两部分记录再进行分割排序,重复执行,直到整个序列有序为止。

过程需要:

  • low:待排序列中的首个元素的索引
  • high:待排序列的最后一个元素的索引
  • pivot:基准,序列中挑选出的一个作为标准参考的元素(这里让基准 = 待排序列中的首个元素)
  • left,right:先备份待排序列中的首尾索引,用于分组之后的赋值

比如:一组序列从 low 到 high ,一趟排序分组之后,low和high的值都变了,而且low值等于high值,分开的两组中,第一组为 left 到 low-1,第二组为 low+1 到 right,因为此时low指向的值恰为基准,所以不再参与下次排序。

排序过程:

  • 从最后面的元素开始查找,指针high指向最后一个元素
  • 若有大于基准值的元素,则不处理,指针high向左移一位
  • 若有小于基准值的元素,则将此元素(high指向的)与low指针所指向的元素交换
  •  
  • 然后再排查左面low指针所指向的值
  • 若有小于基准值的元素,则low指针右移
  • 若有大于基准值的元素,则将此元素(low指向的)与high指针所指向的元素交换
  •  
  • 重复上述过程,直到low指针与high指针重合或交叉,则完成一趟排序

然后递归执行分组之后的排序,重复上述过程

Python代码

def quick_sort(lists, low, high):
    # 结束条件
    if low >= high:
        return
    # 让 基准 = 待排序列表中的第一个数
    pivot = lists[low]
    # 将待排序列表中两头的值先备份,用于下面递归时的赋值
    left = low
    right = high
    while low < high:
        # 查找右面第一个小于pivot的数,进行交换
        while low < high and pivot <= lists[high]:
            high -= 1
        lists[low], lists[high] = lists[high], lists[low]
        # 查找左面第一个大于pivot的数,进行交换
        while low < high and pivot >= lists[low]:
            low += 1
        lists[low], lists[high] = lists[high], lists[low]
    # 左面的一组,再进行上面的操作
    quick_sort(lists, left, low - 1)
    # 右面的一组,再进行上面的操作
    quick_sort(lists, low + 1, right)
    return lists


if __name__ == '__main__':
    array = [5, 2, 0, 1, 3, 1, 4, 12, 9, 3, 15]
    print(array)
    quick_sort(array, 0, len(array) - 1)
    print(array)

Java代码

package algorithm;

public class Sort {

    // 快速排序算法
    private static void quickSort(int[] array, int low, int high) {
        if (low >= high) {
            return;
        }
        // 每次基准都等于待排序列的第一个元素
        int pivot = array[low];
        int left = low;
        int right = high;
        // 进行一趟排序,并分组
        while (low < high) {
            // 在右面查找第一个小于基准的数
            while (low < high && pivot <= array[high]) {
                high -= 1;
            }
            // 然后进行交换
            int temp = array[high];
            array[high] = array[low];
            array[low] = temp;

            // 在左面找到第一个大于基准的数
            while (low < high && pivot >= array[low]) {
                low += 1;
            }
            // 然后进行交换
            int temps = array[high];
            array[high] = array[low];
            array[low] = temps;
        }
        // 一趟结束之后,应该是low = high
        // 然后以这个位置为分界线,把待排序列分成了两组

        // 对左面的一组,再进行上述操作
        quickSort(array, left, low - 1);
        // 对右面的一组,再进行上述操作
        quickSort(array, low + 1, right);
    }

    public static void main(String[] args) {
        int[] array = new int[]{5, 2, 0, 1, 3, 1, 4};
        Sort.quickSort(array, 0, array.length - 1);
        // 打印数组
        for (int i = 0 ; i < array.length ; i++) {
            System.out.print(array[i] + " ");
        }
    }
}

时间复杂度:

最好情况:每次总是选到中间值作为基准,T(n) = O(nlog₂n)

最坏情况:每次总是选到最大或最小值作为基准,T(n) = O(n²)

平均情况:T(n) = O(nlog₂n),是所有同数量级的排序算法中最好的一种

发布了22 篇原创文章 · 获赞 17 · 访问量 5845

猜你喜欢

转载自blog.csdn.net/weixin_42193813/article/details/105016716