十大经典排序算法动画与解析,看我就够了!(配代码完全版) (4)

重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作;

递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序;

6.2 动画演示

image

image

6.3 参考代码 1//Java 代码实现
2public class QuickSort implements IArraySort {
3
4    @Override
5    public int[] sort(int[] sourceArray) throws Exception {
6        // 对 arr 进行拷贝,不改变参数内容
7        int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);
8
9        return quickSort(arr, 0, arr.length - 1);
10    }
11
12    private int[] quickSort(int[] arr, int left, int right) {
13        if (left < right) {
14            int partitionIndex = partition(arr, left, right);
15            quickSort(arr, left, partitionIndex - 1);
16            quickSort(arr, partitionIndex + 1, right);
17        }
18        return arr;
19    }
20
21    private int partition(int[] arr, int left, int right) {
22        // 设定基准值(pivot)
23        int pivot = left;
24        int index = pivot + 1;
25        for (int i = index; i <= right; i++) {
26            if (arr[i] < arr[pivot]) {
27                swap(arr, i, index);
28                index++;
29            }
30        }
31        swap(arr, pivot, index - 1);
32        return index - 1;
33    }
34
35    private void swap(int[] arr, int i, int j) {
36        int temp = arr[i];
37        arr[i] = arr[j];
38        arr[j] = temp;
39    }
40
41}
7. 堆排序 7.1 算法步骤

创建一个堆 H[0……n-1];

把堆首(最大值)和堆尾互换;

把堆的尺寸缩小 1,并调用 shift_down(0),目的是把新的数组顶端数据调整到相应位置;

重复步骤 2,直到堆的尺寸为 1。

7.2 动画演示

image

image

7.3 参考代码 1//Java 代码实现
2public class HeapSort implements IArraySort {
3
4    @Override
5    public int[] sort(int[] sourceArray) throws Exception {
6        // 对 arr 进行拷贝,不改变参数内容
7        int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);
8
9        int len = arr.length;
10
11        buildMaxHeap(arr, len);
12
13        for (int i = len - 1; i > 0; i--) {
14            swap(arr, 0, i);
15            len--;
16            heapify(arr, 0, len);
17        }
18        return arr;
19    }
20
21    private void buildMaxHeap(int[] arr, int len) {
22        for (int i = (int) Math.floor(len / 2); i >= 0; i--) {
23            heapify(arr, i, len);
24        }
25    }
26
27    private void heapify(int[] arr, int i, int len) {
28        int left = 2 * i + 1;
29        int right = 2 * i + 2;
30        int largest = i;
31
32        if (left < len && arr[left] > arr[largest]) {
33            largest = left;
34        }
35
36        if (right < len && arr[right] > arr[largest]) {
37            largest = right;
38        }
39
40        if (largest != i) {
41            swap(arr, i, largest);
42            heapify(arr, largest, len);
43        }
44    }
45
46    private void swap(int[] arr, int i, int j) {
47        int temp = arr[i];
48        arr[i] = arr[j];
49        arr[j] = temp;
50    }
51
52}
8. 计数排序 8.1 算法步骤

花O(n)的时间扫描一下整个序列 A,获取最小值 min 和最大值 max

开辟一块新的空间创建新的数组 B,长度为 ( max - min + 1)

数组 B 中 index 的元素记录的值是 A 中某元素出现的次数

最后输出目标整数序列,具体的逻辑是遍历数组 B,输出相应元素以及对应的个数

8.2 动画演示

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wsfpsj.html