现在的位置: 首页 > 综合 > 正文

算法导论——第五章——线性时间排序

2012年10月30日 ⁄ 综合 ⁄ 共 2857字 ⁄ 字号 评论关闭

 

1.决策树模型

比较排序的过程可以被抽象地视为决策树。一棵决策树是一棵满二叉树,表示某排序算法作用于给定输入所做的所有比较。排序算法的执行对应于遍历一条从树的根到叶节点的路径。每个内结点对应一个比较ai&aj,左子树决定着ai<=aj以后的比较,右子树决定着ai>aj以后的比较。当到达一个叶节点时,排序算法就已确定。排序算法能够正确工作的的必要条件是,n个元素的n!种排列都要作为决策树的一个叶节点出现。设决策树的高度为h,叶子数目为l,那么有 2h>=l>=n!,于是有 h>lgn!
= Ω(nlgn)
。 这说明比较排序的最坏时间复杂度为Ω(nlgn)。这也说明合并排序和堆排序的复杂度已经渐进最优了。

2.计数排序

假设n个输入元素的每一个都是介于0到k之间的整数,此处k为某个整数。当k=O(n)时,计数排序的运行时间为Θ(n)。 计数排序的思想就是对每一个输入元素x,确定出小于x的元素个数。有了这一信息,就可以把x直接放到最终输出数组的位置上。

假定输入是数组A[1...n], 存放排序结果的B[1...n],以及提供计数临时存储的C[0...k]。

COUNTING-SORT(A,B,k)jk

   for  i<- 0 to k

       do C[i] i<- 0 //初始化临时存储数组

   for j i<-1 to length[A]

       do C[A[j]] =C[A[j]]+1

//到此时C[i]中数值表示A中等于i的元素个数

   for i <-1 to k

       do C[i] = C[i] + C[i-1]

//到此时C[i]中数值表示A中等于小鱼等于i的元素个数

   for i <- length[A] downto 1

       do B[C[A[i]] = A[i]

            C[A[i]] = C[A[i]] -1  //important

第七行,从length[A] downto 1是为了正确解决由相同元素时的排序情况,保证算法稳定。若改为for
i<- 1 upto length[A]
,则排序不稳定。


05 #include <vector>
06 #include <iostream>
07 using namespace std;
08 //此程序是实现计数排序算法,要特别注意指标问题
10 void counting_sort(vector<int> A, vector<int>& B, int k);
11 int main()
12 {
13     int a[]={1,4,3,2,0,4,3,5,7,5,4,6,7,8,5,9,6,4,3,4,0};
14     int k=9;
15     vector<int> A(a,a+20);
16     vector<int> B(20,0);
17     counting_sort(A, B, k);
18     vector<int>::iterator i;
19     for(i=B.begin();i!=B.end();i++)
20         cout<<*i<< ";
21     return 0;
22 }
23   
24 void counting_sort(vector<int> A, vector<int>& B, int k)
25 {
26     vector<int> C(k+1,0);
27     //统计A中重复元素的个数,C的指标表示这个元素的值,C的值表示对应元素的个数
28     for(int j=0;j<A.size();j++)
29         C[A[j]]=C[A[j]]+1;
30     //统计这个值在数组中的放置的位置,即排在第几位
31     for(int i=1;i<=k;i++)
32         C[i]=C[i]+C[i-1];
33     //一次将A中的每个元素放到正确的位置,计入数组下标应从0开始,因此用C[A[j]]减去1
34     for(int j=A.size()-1;j>=0;j--)
35     {
36         B[C[A[j]]-1]=A[j];
37         C[A[j]]=C[A[j]]-1;
38     }
39 }

3.基数排序

基本思想:按组成关键字的各个位的值来实现排序的

基数:计算的基数就是基本的单元数。比如10进制的基数就是10,二进制的基数就2,八进制的基数是8等等。

基数排序说通俗点,就是把带排序的N个数字右对齐排成一列。然后把相同的位数互相比较,来排序

 6 #include <iostream>
 7 #include <cstring>
 8 using namespace std;
 9  
10 int arr[100], res[100], hash[10];
11 int n;
12  
13 int maxbit()
14 {
15        int _max = 0;
16        int temp[100];
17        for(int i=0i<n; ++i)
18            temp[i] = arr[i];
19  
20        for (int i=0i<n; ++i)
21        {
22               int tt = 1;
23               while(temp[i]/10 > 0)
24               {
25                      tt++;
26                      temp[i] /= 10;
27               }
28               if(_max < tt)
29                      _max = tt;
30        }
31        cout << "_max " << _max << endl;
32        return _max;
33 }
34  
35 void radixSort()
36 {
37     memset(res, 0sizeof(res));
38     int nbit = maxbit();
39     int tmp;
40     int radix = 1;
41     // 以下和计数排序一样
42     for(int i=1i<=nbit; ++i)
43     {
44         for(int j=0j<10++j)
45             hash[j] = 0;
46         for(int j=0j<n; ++j)
47         {
48             tmp = (arr[j]/radix)%10;
49             ++hash[tmp];
50         }
51         for(int j=1j<10++

抱歉!评论已关闭.