Skip to content

Commit 431f58d

Browse files
committed
update
1 parent b04be58 commit 431f58d

File tree

4 files changed

+134
-3
lines changed

4 files changed

+134
-3
lines changed

src/com/duweri/interview/sort/BubbleSort.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,7 @@ public static void bubbleSort(int[] numbers) {
1414
int size = numbers.length;
1515
for (int i = 0; i < size - 1; i++) {
1616
for (int j = 0; j < size - 1 - i; j++) {
17-
if (numbers[j] > numbers[j + 1]) //交换两数位置
18-
{
17+
if (numbers[j] > numbers[j + 1]){ //交换两数位置
1918
temp = numbers[j];
2019
numbers[j] = numbers[j + 1];
2120
numbers[j + 1] = temp;
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package com.duweri.interview.sort;
2+
3+
import java.util.Arrays;
4+
5+
public class HeapSort {
6+
public static void main(String[] args) {
7+
int[] array = new int[] { 2, 1, 4, 3, 6, 5, 8, 7 };
8+
sort(array);
9+
System.out.println(Arrays.toString(array));
10+
}
11+
12+
public static void sort(int[] array) {
13+
// 按照完全二叉树的特点,从最后一个非叶子节点开始,对于整棵树进行大根堆的调整
14+
// 也就是说,是按照自下而上,每一层都是自右向左来进行调整的
15+
// 注意,这里元素的索引是从0开始的
16+
// 另一件需要注意的事情,这里的建堆,是用堆调整的方式来做的
17+
// 堆调整的逻辑在建堆和后续排序过程中复用的
18+
for (int i = array.length / 2 - 1; i >= 0; i--) {
19+
adjustHeap(array, i, array.length);
20+
}
21+
22+
// 上述逻辑,建堆结束
23+
// 下面,开始排序逻辑
24+
for (int j = array.length - 1; j > 0; j--) {
25+
// 元素交换
26+
// 说是交换,其实质就是把大顶堆的根元素,放到数组的最后;换句话说,就是每一次的堆调整之后,都会有一个元素到达自己的最终位置
27+
swap(array, 0, j);
28+
// 元素交换之后,毫无疑问,最后一个元素无需再考虑排序问题了。
29+
// 接下来我们需要排序的,就是已经去掉了部分元素的堆了,这也是为什么此方法放在循环里的原因
30+
// 而这里,实质上是自上而下,自左向右进行调整的
31+
adjustHeap(array, 0, j);
32+
}
33+
}
34+
35+
/**
36+
* 这里,是整个堆排序最关键的地方,正是因为把这个方法抽取出来,才更好理解了堆排序的精髓,会尽可能仔细讲解
37+
*/
38+
public static void adjustHeap(int[] array, int i, int length) {
39+
// 先把当前元素取出来,因为当前元素可能要一直移动
40+
int temp = array[i];
41+
// 可以参照sort中的调用逻辑,在堆建成,且完成第一次交换之后,实质上i=0;也就是说,是从根所在的最小子树开始调整的
42+
// 接下来的讲解,都是按照i的初始值为0来讲述的
43+
// 这一段很好理解,如果i=0;则k=1;k+1=2
44+
// 实质上,就是根节点和其左右子节点记性比较,让k指向这个不超过三个节点的子树中最大的值
45+
// 这里,必须要说下为什么k值是跳跃性的。
46+
// 首先,举个例子,如果a[0] > a[1]&&a[0]>a[2],说明0,1,2这棵树不需要调整,那么,下一步该到哪个节点了呢?肯定是a[1]所在的子树了,
47+
// 也就是说,是以本节点的左子节点为根的那棵小的子树
48+
// 而如果a[0}<a[2]呢,那就调整a[0]和a[2]的位置,然后继续调整以a[2]为根节点的那棵子树,而且肯定是从左子树开始调整的
49+
// 所以,这里面的用意就在于,自上而下,自左向右一点点调整整棵树的部分,直到每一颗小子树都满足大根堆的规律为止
50+
for (int k = 2 * i + 1; k < length; k = 2 * k + 1) {
51+
// 让k先指向子节点中最大的节点
52+
if (k + 1 < length && array[k] < array[k + 1]) {
53+
k++;
54+
}
55+
56+
// 如果发现子节点更大,则进行值的交换
57+
if (array[k] > temp) {
58+
swap(array, i, k);
59+
// 下面就是非常关键的一步了
60+
// 如果子节点更换了,那么,以子节点为根的子树会不会受到影响呢?
61+
// 所以,循环对子节点所在的树继续进行判断
62+
i = k;
63+
// 如果不用交换,那么,就直接终止循环了
64+
} else {
65+
break;
66+
}
67+
}
68+
}
69+
70+
public static void swap(int[] arr, int a, int b) {
71+
int temp = arr[a];
72+
arr[a] = arr[b];
73+
arr[b] = temp;
74+
}
75+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,61 @@
11
package com.duweri.interview.sort;
22

3+
import java.util.Arrays;
4+
5+
/**
6+
* https://juejin.im/post/5b55660ee51d4519202e2003
7+
*/
38
public class QuickSort {
9+
private static void printArr(int[] arr) {
10+
for (int anArr : arr) {
11+
System.out.print(anArr + " ");
12+
}
13+
}
14+
15+
/**
16+
* 快排一次划分
17+
* @param arr
18+
* @param left
19+
* @param right
20+
* @return
21+
*/
22+
private static int partition(int[] arr, int left, int right) {
23+
int temp = arr[left];
24+
while (right > left) {
25+
// 先判断基准数和后面的数依次比较
26+
while (temp <= arr[right] && left < right) {
27+
--right;
28+
}
29+
// 当基准数大于了 arr[right],则填坑
30+
if (left < right) {
31+
arr[left] = arr[right];
32+
++left;
33+
}
34+
// 现在是 arr[right] 需要填坑了
35+
while (temp >= arr[left] && left < right) {
36+
++left;
37+
}
38+
if (left < right) {
39+
arr[right] = arr[left];
40+
--right;
41+
}
42+
}
43+
arr[left] = temp;
44+
return left;
45+
}
46+
47+
private static void quickSort(int[] arr, int left, int right) {
48+
if (arr == null || left >= right || arr.length <= 1)
49+
return;
50+
int mid = partition(arr, left, right);
51+
quickSort(arr, left, mid);
52+
quickSort(arr, mid + 1, right);
53+
}
54+
55+
56+
public static void main(String[] args) {
57+
int[] arr = {6, 4, 3, 2, 7, 9, 1, 8, 5};
58+
quickSort(arr, 0, arr.length - 1);
59+
printArr(arr);
60+
}
461
}

src/com/duweri/interview/sort/SelectSort.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ public static void selectSort(int[] numbers) {
1515
int temp = 0; //中间变量
1616

1717
for (int i = 0; i < size; i++) {
18-
int k = i; //待确定的位置
18+
int k = i; //待确定的位置,标记最小值的坐标
1919
//选择出应该在第i个位置的数
2020
for (int j = size - 1; j > i; j--) {
2121
if (numbers[j] < numbers[k]) {

0 commit comments

Comments
 (0)