众所周知,快速排序的时间复杂度是O(nlgn)的。然而因为我太菜,写出来的快速排序一不小心就成了O(n2)…
这个辣鸡问题
这个应该都知道,当待排序数组已经有序时,固定选择某一个位置的数字当哨兵的快排会变成O(n2)。一个解决方法就是随机选择哨兵,或者干脆将输入的数组打乱后再排序。
然而,如果输入的数组数字全部相同呢?
当然这在实际中很少见,但是在实现的时候就要小心。在这种情况下,所实现的快排必须对于相同数字也交换位置,否则就会退化为O(n2)。
比如说,这个
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| void quicksort(int left,int right) { int i,j,t,temp; if(left>right) return;
temp=a[left]; i=left; j=right; while(i!=j) { while(a[j]>=temp && i<j) j--; while(a[i]<=temp && i<j) i++; if(i<j) { t=a[i]; a[i]=a[j]; a[j]=t; } }
a[left]=a[i]; a[i]=temp;
quicksort(left,i-1); quicksort(i+1,right); }
|
还有这个,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| void quick_sort(int s[], int l, int r) { if (l < r) { int i = l, j = r, x = s[l]; while (i < j) { while(i < j && s[j] >= x) j--; if(i < j) s[i++] = s[j]; while(i < j && s[i] < x) i++; if(i < j) s[j--] = s[i]; } s[i] = x; quick_sort(s, l, i - 1); quick_sort(s, i + 1, r); } }
|
它们都会跳过相同的数字,每次排序后哨兵总会在边界上,导致算法劣化到O(n2)。
大概就是这回事,没别的了。这种情况当然有改进的快速排序可以直接避免这种罕见的情况,在不大幅度改动算法的前提下,就要对相同的元素也进行换位才可以,即使会增加交换次数。