Chapter 7 Sorting Algorithms (6) (Quick Sort)

7.9 Quick Sort

7.9.1 Quick sort method introduction:

Quicksort (Quicksort) is an improvement on bubble sort . The basic idea is: divide the data to be sorted into two independent parts by one-pass sorting, all the data in one part is smaller than all the data in the other part, and then quickly sort the two parts of the data according to this method, The entire sorting process can be performed recursively , so that the entire data becomes an ordered sequence

7.9.2 Schematic diagram of quick sort method:

insert image description here
insert image description here

7.9.3 Application example of quick sort method:

Requirement: To sort [-9,78,0,23,-567,70] from small to large, it is required to use the quick sort method. [Test 8w and 800w]
Explanation [Verification Analysis]:
1) If left and right recursion is canceled, the result is -9 -567 0 23 78 70
2) If right recursion is canceled, the result is -567 -9 0 23 78 70
3) If left and right recursion is canceled Left recursion, the result is -9 -567 0 23 70 78
4) Code implementation

quick sort

import java.util.Arrays;

/**
 * 快速排序
 */
public class QuickSort {
    
    
    public static void main(String[] args) {
    
    
        int[] arr = {
    
    -9, 78, 0, 23, -567, 70};
        System.out.println("排序前:" + Arrays.toString(arr));
        quickSort(arr, 0, arr.length - 1);
        System.out.println("排序后:" + Arrays.toString(arr));
    }

    public static void quickSort(int[] arr, int left, int right) {
    
    
        int l = left;//左下标
        int r = right;//右下标
        //pivot中轴值
        int pivot = arr[(left + right) / 2];
        int temp = 0;//临时遍历,作为交换时使用
        //while循环的目的是,让比pivot值 小的,放到左边
        //比pivot值大的,放到右边
        while (l < r) {
    
    
            //在pivot的左边一直找,找到大于等于pivot值,才退出
            while (arr[l] < pivot) {
    
    
                l += 1;
            }
            //在pivot的右边一直找,找到小于等于pivot值,才退出
            while (arr[r] > pivot) {
    
    
                r -= 1;
            }
            //如果 l >= r ,说明pivot的左右两的值,已经按照左边全部是
            //小于等于pivot值,右边全部是大于等于pivot值
            if (l >= r) {
    
    
                break;
            }

            //交换
            temp = arr[l];
            arr[l] = arr[r];
            arr[r] = temp;

            //如果交换完后,发现这个arr[l] == pivot值,相等 r--, 前移
            if (arr[l] == pivot) {
    
    
                r -= 1;
            }
            //如果交换完后,发现这个arr[r] == pivot值,相等 l++, 后移
            if (arr[l] == pivot) {
    
    
                l += 1;
            }
        }

        //如果 l == r, 必须 l++, r--,否则会出现栈溢出
        if (l == r) {
    
    
            l += 1;
            r -= 1;
        }
        //向左递归
        if (left < r) {
    
    
            quickSort(arr, left, r);
        }
        //向右递归
        if (right > l) {
    
    
            quickSort(arr, l, right);
        }
    }
}

排序前:[-9, 78, 0, 23, -567, 70]
排序后:[-567, -9, 0, 23, 70, 78]

test speed

import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;

/**
 * 快速排序
 */
public class QuickSort {
    
    
    public static void main(String[] args) {
    
    
        //测试快速排序的速度, 给80000个数据 测试
        int arr[] = new int[80000];
        for (int i = 0, size = arr.length; i < size; i++) {
    
    
            arr[i] = (int) (Math.random() * 80000);//生成一个【0,80000)数
        }

        long startTime = System.currentTimeMillis();
        quickSort(arr, 0, arr.length - 1);
        long endTime = System.currentTimeMillis();

        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String start = dateFormat.format(new Date(startTime));
        String end = dateFormat.format(new Date(endTime));
        System.out.println("排序前时间:" + start);// 2023-08-20 15:11:38
        System.out.println("排序后时间:" + end);// 2023-08-20 15:11:38
    }

    public static void quickSort(int[] arr, int left, int right) {
    
    
        int l = left;//左下标
        int r = right;//右下标
        //pivot中轴值
        int pivot = arr[(left + right) / 2];
        int temp = 0;//临时遍历,作为交换时使用
        //while循环的目的是,让比pivot值 小的,放到左边
        //比pivot值大的,放到右边
        while (l < r) {
    
    
            //在pivot的左边一直找,找到大于等于pivot值,才退出
            while (arr[l] < pivot) {
    
    
                l += 1;
            }
            //在pivot的右边一直找,找到小于等于pivot值,才退出
            while (arr[r] > pivot) {
    
    
                r -= 1;
            }
            //如果 l >= r ,说明pivot的左右两的值,已经按照左边全部是
            //小于等于pivot值,右边全部是大于等于pivot值
            if (l >= r) {
    
    
                break;
            }

            //交换
            temp = arr[l];
            arr[l] = arr[r];
            arr[r] = temp;

            //如果交换完后,发现这个arr[l] == pivot值,相等 r--, 前移
            if (arr[l] == pivot) {
    
    
                r -= 1;
            }
            //如果交换完后,发现这个arr[r] == pivot值,相等 l++, 后移
            if (arr[l] == pivot) {
    
    
                l += 1;
            }
        }

        //如果 l == r, 必须 l++, r--,否则会出现栈溢出
        if (l == r) {
    
    
            l += 1;
            r -= 1;
        }
        //向左递归
        if (left < r) {
    
    
            quickSort(arr, left, r);
        }
        //向右递归
        if (right > l) {
    
    
            quickSort(arr, l, right);
        }
    }
}

Guess you like

Origin blog.csdn.net/weixin_45828554/article/details/132520490
Recommended