mirror of
https://github.com/CyC2018/Interview-Notebook.git
synced 2026-10-29 23:23:43 +00:00
Update 算法 - 排序.md
重新绘制配图,调整快速排序和堆示例代码中的方法签名,文字校对,补充参考资料。
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 90 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 144 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 105 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 111 KiB |
+12
-7
@@ -114,7 +114,7 @@ public class Insertion<T extends Comparable<T>> extends Sort<T> {
|
||||
|
||||
希尔排序使用插入排序对间隔 h 的序列进行排序。通过不断减小 h,最后令 h=1,就可以使得整个数组是有序的。
|
||||
|
||||
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/7818c574-97a8-48db-8e62-8bfb030b02ba.png" width="450px"> </div><br>
|
||||
<div align="center"> <img src="pics/sort-shell.png" width="560px"/> </div><br>
|
||||
|
||||
```java
|
||||
public class Shell<T extends Comparable<T>> extends Sort<T> {
|
||||
@@ -148,7 +148,7 @@ public class Shell<T extends Comparable<T>> extends Sort<T> {
|
||||
|
||||
归并排序的思想是将数组分成两部分,分别进行排序,然后归并起来。
|
||||
|
||||
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/ec840967-d127-4da3-b6bb-186996c56746.png" width="300px"> </div><br>
|
||||
<div align="center"> <img src="pics/sort-merge.png" width="578px"/> </div><br>
|
||||
|
||||
### 1. 归并方法
|
||||
|
||||
@@ -244,7 +244,7 @@ public class Down2UpMergeSort<T extends Comparable<T>> extends MergeSort<T> {
|
||||
- 归并排序将数组分为两个子数组分别排序,并将有序的子数组归并使得整个数组排序;
|
||||
- 快速排序通过一个切分元素将数组分为两个子数组,左子数组小于等于切分元素,右子数组大于等于切分元素,将这两个子数组排序也就将整个数组排序了。
|
||||
|
||||
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/6234eb3d-ccf2-4987-a724-235aef6957b1.png" width="280px"> </div><br>
|
||||
<div align="center"> <img src="pics/sort-quick.png" width="520px"/> </div><br>
|
||||
|
||||
```java
|
||||
public class QuickSort<T extends Comparable<T>> extends Sort<T> {
|
||||
@@ -255,7 +255,7 @@ public class QuickSort<T extends Comparable<T>> extends Sort<T> {
|
||||
sort(nums, 0, nums.length - 1);
|
||||
}
|
||||
|
||||
private void sort(T[] nums, int l, int h) {
|
||||
protected void sort(T[] nums, int l, int h) {
|
||||
if (h <= l)
|
||||
return;
|
||||
int j = partition(nums, l, h);
|
||||
@@ -379,7 +379,7 @@ public T select(T[] nums, int k) {
|
||||
|
||||
堆可以用数组来表示,这是因为堆是完全二叉树,而完全二叉树很容易就存储在数组中。位置 k 的节点的父节点位置为 k/2,而它的两个子节点的位置分别为 2k 和 2k+1。这里不使用数组索引为 0 的位置,是为了更清晰地描述节点的位置关系。
|
||||
|
||||
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/f48883c8-9d8a-494e-99a4-317d8ddb8552.png" width="170px"> </div><br>
|
||||
<div align="center"> <img src="pics/heap-array.png" width="460px"/> </div><br>
|
||||
|
||||
```java
|
||||
public class Heap<T extends Comparable<T>> {
|
||||
@@ -449,7 +449,7 @@ private void sink(int k) {
|
||||
将新元素放到数组末尾,然后上浮到合适的位置。
|
||||
|
||||
```java
|
||||
public void insert(Comparable v) {
|
||||
public void insert(T v) {
|
||||
heap[++N] = v;
|
||||
swim(N);
|
||||
}
|
||||
@@ -475,7 +475,7 @@ public T delMax() {
|
||||
|
||||
##### 5.1 构建堆
|
||||
|
||||
无序数组建立堆最直接的方法是从左到右遍历数组进行上浮操作。一个更高效的方法是从右至左进行下沉操作,如果一个节点的两个节点都已经是堆有序,那么进行下沉操作可以使得这个节点为根节点的堆有序。叶子节点不需要进行下沉操作,可以忽略叶子节点的元素,因此只需要遍历一半的元素即可。
|
||||
无序数组建立堆最直接的方法是从左到右遍历数组进行上浮操作。一个更高效的方法是从右至左进行下沉操作,如果一个节点的两个子节点都已经是堆有序,那么进行下沉操作可以使得这个节点为根节点的堆有序。叶子节点不需要进行下沉操作,可以忽略叶子节点的元素,因此只需要遍历一半的元素即可。
|
||||
|
||||
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/c2ca8dd2-8d00-4a3e-bece-db7849ac9cfd.gif" width="210px"> </div><br>
|
||||
|
||||
@@ -552,3 +552,8 @@ public class HeapSort<T extends Comparable<T>> extends Sort<T> {
|
||||
### 2. Java 的排序算法实现
|
||||
|
||||
Java 主要排序方法为 java.util.Arrays.sort(),对于原始数据类型使用双轴快速排序(Dual-Pivot Quicksort),对于引用类型使用 TimSort,它是归并排序的改进版本。
|
||||
|
||||
## 参考资料
|
||||
|
||||
- Sedgewick R, Wayne K. 算法(第 4 版)[M]. 人民邮电出版社, 2012.
|
||||
- [Algorithms, 4th Edition](https://algs4.cs.princeton.edu/home/)
|
||||
|
||||
Reference in New Issue
Block a user