Skip to content

Commit 420e3f5

Browse files
Merge pull request #412 from lovelife-li/master
优化跳表,便于学习理解
2 parents 712d77a + 8dde3c4 commit 420e3f5

File tree

3 files changed

+821
-0
lines changed

3 files changed

+821
-0
lines changed

java/12_sorts/Sorts.java

Lines changed: 395 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,395 @@
1+
package com.study.sort;
2+
3+
import java.util.Arrays;
4+
5+
/**
6+
* 冒泡,选择,插入,快速,归并
7+
*
8+
* @author ldb
9+
* @date 2019-10-08 16:09
10+
*/
11+
public class Sorts {
12+
13+
/**
14+
* 冒泡排序
15+
*
16+
* @param arr
17+
*/
18+
public static void bubbleSort(int[] arr) {
19+
for (int i = 0; i < arr.length; i++) {
20+
for (int j = 0; j < arr.length - 1 - i; j++) {
21+
if (arr[j] > arr[j + 1]) {
22+
int temp = arr[j];
23+
arr[j] = arr[j + 1];
24+
arr[j + 1] = temp;
25+
}
26+
}
27+
}
28+
}
29+
30+
/**
31+
* 优化冒泡排序
32+
*
33+
* @param arr
34+
*/
35+
public static void bubbleSort2(int[] arr) {
36+
for (int i = 0; i < arr.length - 1; i++) {
37+
boolean flag = true;
38+
for (int j = 0; j < arr.length - 1 - i; j++) {
39+
if (arr[j] > arr[j + 1]) {
40+
int temp = arr[j];
41+
arr[j] = arr[j + 1];
42+
arr[j + 1] = temp;
43+
flag = false;
44+
}
45+
}
46+
if (flag) {
47+
break;
48+
}
49+
}
50+
}
51+
52+
/**
53+
* 插入排序
54+
*
55+
* @param arr
56+
*/
57+
public static void insertSort(int[] arr) {
58+
for (int i = 1; i < arr.length; i++) {
59+
int val = arr[i];
60+
int index = i - 1;
61+
while (index >= 0 && arr[index] > val) {
62+
arr[index + 1] = arr[index];
63+
index--;
64+
}
65+
arr[index + 1] = val;
66+
}
67+
}
68+
69+
/**
70+
* 插入排序
71+
*
72+
* @param arr
73+
* @param n 表示数组有用大小
74+
*/
75+
public static void insertSort(int[] arr, int n) {
76+
for (int i = 1; i < n; i++) {
77+
int val = arr[i];
78+
int index = i - 1;
79+
while (index >= 0 && arr[index] > val) {
80+
arr[index + 1] = arr[index];
81+
index--;
82+
}
83+
arr[index + 1] = val;
84+
}
85+
}
86+
87+
/**
88+
* 选择排序
89+
*
90+
* @param arr
91+
*/
92+
public static void selectSort(int[] arr) {
93+
94+
for (int i = 0; i < arr.length - 1; i++) {
95+
int minIndex = i;
96+
for (int j = i + 1; j < arr.length; j++) {
97+
if (arr[minIndex] > arr[j]) {
98+
minIndex = j;
99+
}
100+
}
101+
// 交换
102+
int temp = arr[i];
103+
arr[i] = arr[minIndex];
104+
arr[minIndex] = temp;
105+
}
106+
}
107+
108+
/**
109+
* 归并排序
110+
*
111+
* @param arr
112+
*/
113+
public static void mergeSort(int[] arr, int left, int right) {
114+
if (left >= right) {
115+
return;
116+
}
117+
int q = (left + right) / 2;
118+
mergeSort(arr, left, q);
119+
mergeSort(arr, q + 1, right);
120+
merge2(arr, left, q, right);
121+
122+
}
123+
124+
private static void merge2(int[] arr, int left, int q, int right) {
125+
int[] leftArr = new int[q - left + 2];
126+
int[] rightArr = new int[right - q + 1];
127+
128+
for (int i = 0; i <= q - left; i++) {
129+
leftArr[i] = arr[left + i];
130+
}
131+
// 第一个数组添加哨兵(最大值)
132+
leftArr[q - left + 1] = Integer.MAX_VALUE;
133+
134+
for (int i = 0; i < right - q; i++) {
135+
rightArr[i] = arr[q + 1 + i];
136+
}
137+
// 第二个数组添加哨兵(最大值)
138+
rightArr[right - q] = Integer.MAX_VALUE;
139+
140+
int i = 0;
141+
int j = 0;
142+
int k = left;
143+
while (k <= right) {
144+
// 当左边数组到达哨兵值时,i不再增加,直到右边数组读取完剩余值,同理右边数组也一样
145+
if (leftArr[i] <= rightArr[j]) {
146+
arr[k++] = leftArr[i++];
147+
} else {
148+
arr[k++] = rightArr[j++];
149+
}
150+
}
151+
}
152+
153+
private static void merge(int[] arr, int left, int q, int right) {
154+
int i = left;
155+
int j = q + 1;
156+
int k = 0;
157+
int[] tmp = new int[right - left + 1];
158+
while (i <= q && j <= right) {
159+
if (arr[i] <= arr[j]) {
160+
tmp[k++] = arr[i++];
161+
} else {
162+
tmp[k++] = arr[j++];
163+
}
164+
}
165+
int start = i;
166+
int end = q;
167+
if (j <= right) {
168+
start = j;
169+
end = right;
170+
}
171+
while (start <= end) {
172+
tmp[k++] = arr[start++];
173+
}
174+
for (int l = 0; l <= right - left; l++) {
175+
arr[l + left] = tmp[l];
176+
}
177+
178+
}
179+
180+
/**
181+
* 快速排序
182+
*
183+
* @param arr
184+
*/
185+
public static void quickSort(int[] arr, int left, int right) {
186+
if (left >= right) {
187+
return;
188+
}
189+
int q = partition2(arr, left, right);
190+
quickSort(arr, left, q - 1);
191+
quickSort(arr, q + 1, right);
192+
}
193+
194+
private static int partition(int[] arr, int left, int right) {
195+
int pivot = arr[right];
196+
int i = left;
197+
for (int j = left; j < right; j++) {
198+
if (arr[j] < pivot) {
199+
if (i == j) {
200+
++i;
201+
} else {
202+
int tmp = arr[i];
203+
arr[i++] = arr[j];
204+
arr[j] = tmp;
205+
}
206+
}
207+
}
208+
int tmp = arr[i];
209+
arr[i] = arr[right];
210+
arr[right] = tmp;
211+
return i;
212+
}
213+
214+
private static int partition2(int[] arr, int left, int right) {
215+
// 三数取中法 , 随机数在这里写
216+
int middle = (left + right) / 2;
217+
int pivot = arr[middle];
218+
// 交换到最右边
219+
int val = arr[right];
220+
arr[right] = pivot;
221+
arr[middle] = val;
222+
int i = left;
223+
for (int j = left; j < right; j++) {
224+
if (arr[j] < pivot) {
225+
if (i == j) {
226+
++i;
227+
} else {
228+
int tmp = arr[i];
229+
arr[i++] = arr[j];
230+
arr[j] = tmp;
231+
}
232+
}
233+
}
234+
int tmp = arr[i];
235+
arr[i] = arr[right];
236+
arr[right] = tmp;
237+
return i;
238+
}
239+
240+
/**
241+
* 三向切分快速排序
242+
*
243+
* @param arr
244+
* @param left
245+
* @param right
246+
* @return
247+
*/
248+
private static void quickSort3(int[] arr, int left, int right) {
249+
if (left >= right) {
250+
return;
251+
}
252+
int l = left;
253+
int k = left + 1;
254+
int r = right;
255+
int pivot = arr[l];
256+
257+
while (k <= r) {
258+
if (arr[k] < pivot) {
259+
int tmp = arr[l];
260+
arr[l] = arr[k];
261+
arr[k] = tmp;
262+
l++;
263+
k++;
264+
} else if (arr[k] == pivot) {
265+
k++;
266+
} else {
267+
if (arr[r] > pivot) {
268+
r--;
269+
} else if (arr[r] == pivot) {
270+
int tmp = arr[k];
271+
arr[k] = arr[r];
272+
arr[r] = tmp;
273+
k++;
274+
r--;
275+
} else {
276+
int tmp = arr[l];
277+
arr[l] = arr[r];
278+
arr[r] = arr[k];
279+
arr[k] = tmp;
280+
l++;
281+
k++;
282+
r--;
283+
}
284+
}
285+
}
286+
287+
quickSort(arr, left, l - 1);
288+
quickSort(arr, r + 1, right);
289+
}
290+
291+
/**
292+
* 双轴快速排序
293+
*
294+
* @param arr
295+
* @param left
296+
* @param right
297+
*/
298+
private static void quickSort4(int[] arr, int left, int right) {
299+
if (left >= right) {
300+
return;
301+
}
302+
int l = left;
303+
int k = left + 1;
304+
int r = right;
305+
// 判断pivot1 与 pivot2 大小
306+
if (arr[l] > arr[r]) {
307+
int tmp = arr[l];
308+
arr[l] = arr[r];
309+
arr[r] = tmp;
310+
}
311+
int pivot1 = arr[l];
312+
int pivot2 = arr[r];
313+
314+
while (k < r) {
315+
if (arr[k] < pivot1) {
316+
l++;
317+
if (l != k) {
318+
int tmp = arr[l];
319+
arr[l] = arr[k];
320+
arr[k] = tmp;
321+
}
322+
k++;
323+
} else if (arr[k] >= pivot1 && arr[k] <= pivot2) {
324+
k++;
325+
} else {
326+
--r;
327+
if (arr[r] > pivot2) {
328+
} else if (arr[r] >= pivot1 && arr[r] <= pivot2) {
329+
int tmp = arr[k];
330+
arr[k] = arr[r];
331+
arr[r] = tmp;
332+
k++;
333+
} else {
334+
l++;
335+
int tmp = arr[l];
336+
arr[l] = arr[r];
337+
arr[r] = arr[k];
338+
arr[k] = tmp;
339+
k++;
340+
}
341+
}
342+
}
343+
344+
// 交换pivot1 和 pivot2
345+
arr[left] = arr[l];
346+
arr[l] = pivot1;
347+
arr[right] = arr[r];
348+
arr[r] = pivot2;
349+
350+
quickSort(arr, left, l - 1);
351+
quickSort(arr, l + 1, r - 1);
352+
quickSort(arr, r + 1, right);
353+
}
354+
355+
/**
356+
* O(n) 时间复杂度内求无序数组中的第 K 大元素。比如, 4 , 2 , 5 , 12 , 3 这样一组数据,第 3 大元素就是 4 。
357+
*
358+
* @param arr
359+
*/
360+
public static int sort(int[] arr, int l, int r, int k) {
361+
if (l >= r) {
362+
return 0;
363+
}
364+
int p = partition(arr, l, r);
365+
if ((p + 1) == k) {
366+
return arr[p];
367+
} else if ((p + 1) < k) {
368+
return sort(arr, p + 1, r, k);
369+
} else {
370+
return sort(arr, l, p - 1, k);
371+
}
372+
}
373+
374+
public static void main(String[] args) {
375+
int[] arr = {2, 1, 5, 6, 8, 4, 12, 11, 13, 15, 7, 9, 0, -1};
376+
// bubbleSort(arr);
377+
// bubbleSort2(arr);
378+
// selectSort(arr);
379+
// mergeSort(arr, 0, arr.length - 1);
380+
// quickSort4(arr, 0, arr.length - 1);
381+
382+
Arrays.sort(arr);
383+
print(arr);
384+
385+
}
386+
387+
public static void print(int[] arr) {
388+
for (int i : arr) {
389+
System.out.print(i + " ");
390+
}
391+
System.out.println();
392+
}
393+
394+
395+
}

0 commit comments

Comments
 (0)