总体上讲排序有以下五种:以身边常见的扑克牌为例来理解比较容易些。
插入排序:(基本思想)每一趟将一个待排序的记录,按照其关键字大小插入到已经安排好的一组记录的适当位置上,直到所有待排序记录全部插入为止。例如 希尔(shell)排序。
(举例)打扑克牌在抓牌时要保证抓过的牌有序排列,则每抓一张牌,就插入到合适的位置,直到抓完牌为止,即可得到一个有序序列。
交换排序:(基本思想)两两比较待排序记录的关键字,一旦发现两个记录不满足次序要求时则进行交换,直到整个序列全部满足要求为止。例如 冒泡排序和快速排序。
选择排序:(基本思想)每一趟从待排的记录中选出关键字最小的记录,按顺序放在已排序的记录序列的最后,直到全部排完为止。例如 堆排序。
归并排序:(基本思想)将两个或两个以上的有序表合并成一个有序表的过程。
基数排序:(基本思想)和前面所述各类比较方法完全不同的一种排序方法。前面各类排序方法都是建立在关键字比较的基础上,而基数排序不比较关键字中各位的值,通过对待排序记录进行若干趟“分配”和“收集”来实现排序的。
- 冒泡排序
- 快速排序
- Shell排序
- 堆排序
交换排序的基本思想是:两两比较待排序记录的关键字,发现两个记录的次序相反时即进行交换,直到没有反序的记录为止。
应用交换排序基本思想的主要排序方法有:冒泡排序和快速排序。
1.冒泡排序-BubbleSorting
将被排序的记录数组R[1..n]垂直排列,每个记录R[i]看作是重量为R[i].key的气泡。根据轻气泡不能在重气泡之下的原则,从下往上扫描数组R:凡扫描到违反本原则的轻气泡,就使其向上"飘浮"。如此反复进行,直到最后任何两个气泡都是轻者在上,重者在下为止。
下面这个动画斜过来气泡往上走会更直观:
方法A:(比较直白、跟算法思想很贴切) 第一遍是数组的第一个元素跟第二个比较,第二个元素跟第三个元素比较。。。最终把最小的放到第一个位置;第二遍是数组的第二个元素跟第三个比较,第三个元素跟第四个比较。。。最终把次小的放到第二个位置,。。。以此类推。。。每一遍都是相邻两个元素比较。
1 using System; 2 3 namespace SortFunction 4 { 5 class BubbleSort 6 { 7 static void Main(string[] args) 8 { 9 int[] a = { 10, 1, 2, 3, 4, 9 }; 10 BubbleSort BS = new BubbleSort(); 11 int[] b = BS.sortArray(a); 12 for (int i = 0; i < b.Length; i++) 13 { 14 Console.WriteLine(b[i]); 15 } 16 Console.ReadLine(); 17 } 18 19 int[] sortArray(int[] inputArray) 20 { 21 for (int i = 0; i < inputArray.Length; i++) 22 { 23 // exchange can speed up the sorting in specail occasion. 24 bool exchange = false; 25 for (int j = i; j < inputArray.Length - 1; j++) 26 { 27 if (inputArray[j] > inputArray[j + 1]) 28 { 29 int tmp = inputArray[j + 1]; 30 inputArray[j + 1] = inputArray[j]; 31 inputArray[j] = tmp; 32 exchange = true; 33 } 34 } 35 36 if (!exchange) 37 { 38 break; 39 } 40 } 41 return inputArray; 42 } 43 } 44 }
方法B1:第一遍是数组的第一个元素跟它后面的第二个、第三个....最后一个元素比较,最终把最小的放到第一个位置;第二遍,把第二个元素跟它后面的所有元素依次比较最后得到第二小的元素;以此类推得到一个从小到大排好序的数组。每一遍都是第N个元素和它后面所有其他元素比较。
2 {
3 int tmp;
4 for ( int i = 0 ; i < list.Length - 1 ; i ++ )
5 {
6 for ( int j = i + 1 ; j < list.Length; j ++ )
7 {
8 if (list[i] > list[j])
9 {
10 tmp = list[i];
11 list[i] = list[j];
12 list[j] = tmp;
13 }
14 }
15 }
16
17 return list;
18 }
方法B2:
2 {
3 int tmp;
4 for ( int i = 0 ; i < list.Length - 1 ; i ++ ) // 这一步很多人都是i<list.Length,不知道用list.Length-1会不会更好些呢?
5 {
6 for ( int j = list.Length - 1 ; j > i; j -- )
7 {
8 if (list[i] > list[j])
9 {
10 tmp = list[j];
11 list[j] = list[i];
12 list[i] = tmp;
13 }
14 }
15 }
16 return list;
17 }
18
2.快速排序(Quicksort)是对冒泡排序的一种改进。它的基本思想基于分治策略:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然 后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
平均时间复杂度为:Ο(n log n)
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5
6 namespace ConsoleApplication4
7 {
8 class Sorting
9 {
10 static void Main( string [] args)
11 {
12 int [] a = { 1 , 5 , 6 , 4 , 2 , 3 };
13 QuickSort(a, 0 , 5 );
14 for ( int i = 0 ;i < a.Length;i ++ )
15 {
16 Console.WriteLine(a[i].ToString() + " " );
17 }
18 Console.ReadLine();
19
20 }
21 // numbers 要排序的数组
22 // left 数组排序起始位置
23 // right 数组排序终止位置
24 // middle数组中值在left和right之间的数,默认设为left
25 private static void QuickSort( int [] numbers, int left, int right)
26 {
27 int i = left, j = right;
28 int middle;
29 if (left < right)
30 {
31 middle = numbers[left];
32 while (i != j)
33 {
34 while (j > i && numbers[j] > middle)
35 j -- ;
36 if (i < j)
37 {
38 numbers[i] = numbers[j];
39 i ++ ;
40 }
41 while (i < j && numbers[i] < middle)
42 i ++ ;
43 if (j > i)
44 {
45 numbers[j] = numbers[i];
46 j -- ;
47 }
48 }
49
50 numbers[i] = middle;
51 QuickSort(numbers, left, i - 1 ); // 递归调用,将middle左边的数进行排序
52 QuickSort(numbers, j + 1 , right); // 递归调用,将middle右边的数进行排序
53 }
54 }
55
56 }
57 }
58
1 using System; 2 3 namespace SortFunction 4 { 5 class QuickSort 6 { 7 static void Main(string[] args) 8 { 9 int[] a = { 10, 1, 2, 3, 4, 9, 5 }; 10 QuickSort QS = new QuickSort(); 11 QS.quickSort(a, 0, a.Length - 1); 12 for (int i = 0; i < a.Length; i++) 13 { 14 Console.WriteLine(a[i]); 15 } 16 Console.ReadLine(); 17 } 18 19 // inputArray is the array we will sort. 20 // left is the start position of inputArray. 21 // right is the ending position of inputArray. 22 // middle is the element between the left position and the right position. It is the element on the left by default. 23 // pay attention to the use of while. think about why we use while instead of if below. 24 25 void quickSort(int[] inputArray, int left, int right) 26 { 27 int i = left, j = right; 28 int middle; 29 if (left < right) 30 { 31 middle = inputArray[left]; 32 while (i < j) 33 { 34 while ((i < j) && (inputArray[j] >= middle)) 35 { 36 j--; 37 } 38 inputArray[i] = inputArray[j]; 39 i++; 40 41 while ((i < j) && (inputArray[i] <= middle)) 42 { 43 i++; 44 } 45 inputArray[j] = inputArray[i]; 46 j--; 47 } 48 inputArray[i] = middle; 49 quickSort(inputArray, left, i - 1); 50 quickSort(inputArray, j + 1, right); 51 } 52 } 53 } 54 }
动画参考http://blog.jobbole.com/11745/