算法导论-12-2-基数树

来源:互联网 发布:淘宝一键上传插件 编辑:程序博客网 时间:2024/05/29 04:11

算法导论-12-2-基数树

分类: 算法导论 471人阅读 评论(0) 收藏 举报

题目:

给定两个串a = a0a1……ap和b = b0b1……b1,其中每一个ai和每一个bj都属于某个有序字符集,如果下面两条规则之一成立,则说串a按字典序小于串b:

1)存在一个整数j,0<=j<=min(p,q),使得ai=bi,i=0,1,……,j-1,且aj<bj;

2)p<q,且ai=bi,对所有的i=0,1,……,p成立

例如,如果a和b是位串,则根据规则1)(设j=3),有10100 < 10110;根据规则2),有10100 < 101000。这与英语字典中的排序很相似。

图12-5中示出的是基数树(radix tree)数据结构,其中存储了位串1011、10、011、100和0。当查找某个关键字a = a0a1……ap时,在深度为i的一个结点处,若ai = 0则向左转;若ai = 1则向右转。设S为一组不同的二进制串构成的集合,各串的长度之和为n。说明如何利用基数树,在O(n)时间内对S按字典序排序。例如,对图12-5中每个结点的关键字,排序的输出应该是序列0、011、10、100、1011

思考:

就是字典树的一种特殊情况,字典树的模版见用指针传递的字典树

这题在以前的题目里面出现过,使用了另一种解法,见算法导论-8-3-排序不同长度的数据项中的b

代码:

[cpp] view plaincopy
  1. #include <iostream>  
  2. #include <string>  
  3. using namespace std;  
  4.   
  5. //基数树结点结构  
  6. struct node  
  7. {  
  8.     node *left;  
  9.     node *right;  
  10.     node *p;  
  11.     string str;  
  12.     node():left(NULL),right(NULL),p(NULL),str(""){}  
  13. };  
  14. //基数树结点  
  15. struct Radix_Tree  
  16. {  
  17.     node *root;  
  18.     Radix_Tree(){root = new node;}  
  19. };  
  20. //向基数树中插入一个位串  
  21. void Insert(Radix_Tree *T, string s)  
  22. {  
  23.     int i;  
  24.     node *t = T->root, *p;  
  25.     //顺着串依次向下找  
  26.     for(i = 0; i <s.length(); i++ )  
  27.     {  
  28.         //如果第i位是0,把串插入到左子树的某个位置  
  29.         if(s[i] == '0')  
  30.         {  
  31.             //还没有左子树,就开辟一个  
  32.             if(t->left == NULL)  
  33.             {  
  34.                 p = new node;  
  35.                 p->p = t;  
  36.                 t->left = p;  
  37.             }  
  38.             else  
  39.                 p = t->left;  
  40.         }  
  41.         //如果第i位是1,把串插入到左子树的某个位置  
  42.         else  
  43.         {  
  44.             //还没有左子树,就开辟一个  
  45.             if(t->right == NULL)  
  46.             {  
  47.                 p = new node;  
  48.                 p->p = t;  
  49.                 t->right = p;  
  50.             }  
  51.             else  
  52.                 p = t->right;  
  53.         }  
  54.         //一直找到串的最后一个字符,把串的内容存入这个节点中  
  55.         if(i == s.length() - 1)  
  56.             p->str = s;  
  57.         else t = p;  
  58.     }  
  59. }  
  60. //按字典序输出,其实是先序遍历的过程  
  61. void Print(node *t)  
  62. {  
  63.     if(t == NULL)  
  64.         return;  
  65.     //如果某个节点有串的信息,就将它输出  
  66.     if(t->str != "")  
  67.         cout<<t->str<<endl;  
  68.     Print(t->left);  
  69.     Print(t->right);  
  70. }  
  71. int main()  
  72. {  
  73.     string str, x;  
  74.     Radix_Tree *T = new Radix_Tree;  
  75.     while(1)  
  76.     {  
  77.         cin>>str;  
  78.         if(str == "I")  
  79.         {  
  80.             cin>>x;  
  81.             Insert(T, x);  
  82.         }  
  83.         else if(str == "P")  
  84.         {  
  85.             Print(T->root);  
  86.             cout<<endl;  
  87.         }  
  88.     }  
  89.     return 0;  
  90. }  
原创粉丝点击