快速排序
部分内容转自坐在马桶上看算法:快速排序和啊哈算法关于快速排序法为什么一定要从右边开始的原因。
快速排序的思想是选一个基准数,然后找到这个基准数在数组里的位置,将大于它的放到它的右边,小于它的放到它的左边。
指针从两边向中间跑:
static void Main(string[] args) { int[] a = { 45, 80, 55, 40, 42, 85 }; quickSort(a, 0, a.Length - 1); foreach (var b in a) { Console.WriteLine(b.ToString()); } Console.ReadLine(); } static void quickSort(int[] array, int left, int right) { int i, j, temp; if (left > right) return; temp = array[left]; i = left; j = right; while (i != j) { while (array[j] >= array[left] && j > i) j--; while (array[i] <= array[left] && j > i) i++; temp = array[i]; array[i] = array[j]; array[j] = temp; } temp = array[i]; array[i] = array[left]; array[left] = temp; quickSort(array, left, i - 1); quickSort(array, i + 1, right); }
指针从左往右跑:
public static int Partition(int[] a, int p, int r) { int x = a[r]; int i = p; int temp; for (int j = p; j <= r; j++) { if (a[j] < x) { temp = a[j]; a[j] = a[i]; a[i] = temp; i++; } } temp = a[r]; a[r] = a[i]; a[i] = temp; return i; } public static void QuickSort(int[] a, int p, int r) { if (p < r) { int q = Partition(a, p, r); QuickSort(a, p, q - 1); QuickSort(a, q + 1, r); } } static void Main(String[] args) { int[] a = { 7, 10, 3, 5, 4, 6, 2, 8, 9, 9 }; QuickSort(a, 0, 9); for (int i = 0; i < a.Length; i++) Console.WriteLine(a[i].ToString()); Console.ReadLine(); }
快速排序详解:

关于为什么要让哨兵j先动:
while(arr[j]>=temp&&i<j){ j--; } while(arr[i]<=temp&&i<j){ i++; }
这里两个while的顺序是不能改变的,想一想:
假设对如下进行排序:

如上图,6在左,9在右 我们将6作为基数。
假设从左边开始(与正确程序正好相反)
于是i 就会移动到现在的数字7那个位置停下来,而j原来在数字9那个位置 ,因为
while(arr[j]>=temp&&i<j)
于是,j 也会停留在数字7那个位置,于是问题来了。当你最后交换基数6与7时,不对呀!!。
问题在于当我们先从在边开始时,那么 i 所停留的那个位置肯定是大于基数6的,而在上述例子中,为了满足 i<j 于是 j也停留在7的位置
但最后交换回去的时候,7就到了左边,不行,因为我们原本 交换后数字6在边应该是全部小于6,右边全部大于6.但现在不行了。
于是,我们必须从右边开始,也就是从基数的对面开始。

浙公网安备 33010602011771号