比较排序:各个元素的次序基于输入元素间的比较。下界为Ω(nlgn)。
线性排序:用非比较的操作来确定元素的顺序。
决策树
比较排序可以抽象地视为决策树,表示某排序算法对输入元素的所有比较。下图为插入排序对于三个元素的输入序列上的决策树:
对于n个元素,排序结果有n!种排列,对应与决策树上的每一个叶子。一个正确的排序算法必须可以产生每一种排列,对于决策树来说就是从根结点出发可以到达每一个
叶结点。
在决策树中,从根到任一个叶结点之间最长路径的长度表示对应的排序算法中最坏情况下的比较次数。
因此,一个比较排序的最坏情况比较次数与其决策树的高度相等。
所以可得任意一个比较排序在最坏情况下,都需要做Ω(nlgn)次比较。
假设一个决策树高度为h、有l个叶结点,对应n个输入元素。
n个元素有n!种排列,因此n! < l。
高度为h的树,叶结点数目最多为2h。
可得:n! ≤ l ≤ 2h
取对数得 h ≥ lg(n!) = Ω(nlgn)
计数排序
计数排序假设n个输入元素都是位于[0, k]之间的整数。
基本思想为对于每一个输入元素x,确定出小于x的元素个数,然后直接将x放置在最终数组的位置上。
1 #include <stdio.h> 2 #include <stdlib.h> 3 4 void counting_sort(int A[], int B[], int length, int max); 5 6 int main(){ 7 int num, i; 8 printf("Input the number:\n"); 9 scanf("%d", &num); 10 int *array = malloc((num + 1) * sizeof(int)); 11 int *arrayB = malloc((num + 1) * sizeof(int)); 12 int max = -1; 13 printf("Input the element:"); 14 for(i = 1; i <= num; i++){ 15 scanf("%d", &array[i]); 16 if(max < array[i]) 17 max = array[i]; 18 } 19 20 counting_sort(array, arrayB, num, max); 21 for(i = 1; i <= num; i++) 22 printf("%d ", arrayB[i]); 23 printf("\n"); 24 25 return 0; 26 } 27 28 /* 29 * 基本思想是对每一个输入元素x,统计小于x元素的个数,然后把x直接放到最终输出的数组中的正确位置上。 30 * 当出现多个元素值一样的时候,需要一些修改,因为不能把相同的元素放到同一个位置上。 31 * 数组A为输入数组,数组B为存放最终结果。 32 */ 33 void counting_sort(int A[], int B[], int length, int max){ 34 int i; 35 int *C = malloc((max+1) * sizeof(int)); //数组C提供临时存储区 36 for(i = 0; i <= max; i++) 37 C[i] = 0; 38 39 int j; 40 for(j = 1; j <= length; j++) 41 C[A[j]]++; 42 /*C[j]记录等于j的元素个数*/ 43 44 for(i = 1; i <= max; i++) 45 C[i] += C[i-1]; 46 /*C[j]此时存储的值为小于等于j的元素个数*/ 47 48 for(j = length; j >= 1; j--){ 49 B[C[A[j]]] = A[j]; 50 C[A[j]]--; 51 } 52 53 /* 54 for(j = 1; j <= length; j++){ 55 B[C[A[j]]] = A[j]; 56 C[A[j]]--; 57 } 58 */ 59 }