Skip to content

Commit ead08a0

Browse files
committed
[Function add]
1.Use insertSort to replace quickSort when doing small array. 2.Three way quick sort. Using three pionters to main less, equal, large to increase the efficiency of having repeating elements.
1 parent 3acba48 commit ead08a0

File tree

2 files changed

+65
-7
lines changed

2 files changed

+65
-7
lines changed

Diff for: Algorithm(4th_Edition)/algorithm_note.txt

+41-3
Original file line numberDiff line numberDiff line change
@@ -585,11 +585,49 @@
585585
1 2 2 2 3 3 3 4 5 5 6 7 7 7 8 18 45 23 27 23 33 96 432 55
586586
1 2 2 2 3 3 3 4 5 5 6 7 7 7 8 18 23 23 27 33 45 96 55 432
587587
1 2 2 2 3 3 3 4 5 5 6 7 7 7 8 18 23 23 27 33 45 55 96 432
588+
分析:
589+
1.快速排序的最好情况是每次都能将数组对半分。
590+
2.在切分不平衡的时候这个程序会极其低效,若果数组本身就是顺序的,每次只会提取出一个元素,相当于遍历了整个数组。
588591

592+
->算法改进:
593+
1.在数组大小比较小的时候,切换到插入排序,因为快速排序本身需要用到递归,即使很小的数组也要用到递归。
594+
实现:
595+
public static int M = 5;
596+
public static void quickSort(Comparable[] a, int lo, int hi){
597+
// if(lo >= hi) return;
598+
if(lo + M >= hi) { //首先lo + M >= hi是lo >= hi的子集。
599+
insertSort(a); //对于小数组就使用插入排序,跳过快速排序。
600+
return;
601+
}
602+
int j = partition(a, lo, hi);
603+
quickSort(a, lo, j-1);
604+
quickSort(a, j+1, hi);
605+
}
589606

590-
591-
592-
607+
2.三取样切分:
608+
->因为快速排序的最优情况是每次取出的数都是在数组的最中间,所以可以考虑中位数,但是计算中位数是额外的开销。
609+
->取前几个数的中位数而不是选整个数组的中位数。
610+
611+
3.熵最优的排序:
612+
->针对于含有大量重复数据的情况,使用快速排序仍然会进行切分并进行递归调用,效率低下。我们可以维护成三取样,小于当前切分元素的部分,等于当前切分元素的部分,大于当前切分元素的部分。
613+
对于小于,大于两部分再进行递归调用。
614+
->a[i]小于v,将a[lt]和a[i]交换,将lt和i加一;
615+
a[i]大于v,将a[gt]和a[i]交换,将gt减一;
616+
a[i]等于v,将i加一。
617+
实现:ca.mcmaster.chapter.two.Sort.Sort#quickSort3Way(Comparable[], int, int)
618+
public static void quickSort3Way(Comparable[] a, int lo, int hi){
619+
if(lo >= hi) return;
620+
int lt = lo, i = lo + 1, gt = hi; //初始化三个指针,lt指向第一个大于等于v的数字,i是一个中间变量,指向第一个大于v的数字,gt从结束开始遍历,向前迭代,指向第一个不大于v的数字。
621+
Comparable v = a[lo];
622+
while(i <= gt){
623+
int cmp = a[i].compareTo(v);
624+
if(cmp < 0) swap(a, lt++, i++);
625+
else if(cmp > 0) swap(a, i, gt--);
626+
else i++;
627+
}
628+
quickSort3Way(a, lo, lt - 1);
629+
quickSort3Way(a, gt + 1, hi);
630+
}
593631

594632

595633

Diff for: Algorithm(4th_Edition)/src/ca/mcmaster/chapter/two/Sort/Sort.java

+24-4
Original file line numberDiff line numberDiff line change
@@ -101,23 +101,43 @@ public static int partition(Comparable[] a, int lo, int hi){
101101
return j;
102102
}
103103

104+
public static int M = 5;
104105
public static void quickSort(Comparable[] a, int lo, int hi){
105-
if(lo >= hi) return;
106+
// if(lo >= hi) return;
107+
if(lo + M >= hi) {
108+
insertSort(a);
109+
return;
110+
}
106111
int j = partition(a, lo, hi);
107112
quickSort(a, lo, j-1);
108113
quickSort(a, j+1, hi);
109114
}
110115

116+
public static void quickSort3Way(Comparable[] a, int lo, int hi){
117+
if(lo >= hi) return;
118+
int lt = lo, i = lo + 1, gt = hi;
119+
Comparable v = a[lo];
120+
while(i <= gt){
121+
int cmp = a[i].compareTo(v);
122+
if(cmp < 0) swap(a, lt++, i++);
123+
else if(cmp > 0) swap(a, i, gt--);
124+
else i++;
125+
}
126+
quickSort3Way(a, lo, lt - 1);
127+
quickSort3Way(a, gt + 1, hi);
128+
}
129+
111130
public static void main(String[] args) {
112-
// Integer[] a = new Integer[]{18,27,33,55,6,3,23,2,3,5,2,45,1,4,2,5,7,3,7,432,96,7,23,8};
131+
Integer[] a = new Integer[]{18,27,33,55,6,3,23,2,3,5,2,45,1,4,2,5,7,3,7,432,96,7,23,8};
113132
// Integer[] a = new Integer[]{1,3,5,9,2,5,6,7};
114-
Integer[] a = new Integer[]{2,1,3,4,5,6,7,8,9};
133+
// Integer[] a = new Integer[]{2,1,3,4,5,6,7,8,9};
115134
// selectionSort(a);
116135
// insertSort(a);
117136
// ShellSort(a);
118137
// merge(a, 0, 3, 7);
119138
// mergeSortBU(a);
120-
quickSort(a, 0, a.length -1);
139+
// quickSort(a, 0, a.length -1);
140+
quickSort3Way(a, 0, a.length - 1);
121141
show(a);
122142
}
123143
}

0 commit comments

Comments
 (0)