数据结构回顾
(Trie, Heap, Segment Tree)
 Retired Member 洪泽华 / 2012.5.19
堆(优先队列)
Heap(Priority Queue)
什么是堆?
 堆是一棵二叉树


 满足所有节点小于或大于其所有子
节点的树

 用于解决在一堆数中快速查询和维
护最大(或最小)的数的问题
堆的图示
                       12




               7                8




           4       6        5       3




       1
堆的结构定义
   int heap[maxnode], size=0;



   …
   没有了?

   对,堆的结构定义就是这么简单。
堆的插入
堆的插入(代码)
   void up(int pos){
     int I;
     for (i=pos; i>0; i=(i-1)/2){
       if (heap[i] > heap[(i-1)/2]) break;
       else swap(heap[i], heap[(i-1)/2]);
      }
   }

   void push(int x){
     heap[size] = x;
     up(size);
     size++;
   }
堆的删除
堆的删除
堆的删除 (代码)
   void down(int pos) {
     int i, j;
     for(i=pos; i*2+1<size;){
       j=i*2+1;
       if (j+1<size&&heap[j+1]<heap[j]) j++;
       if( heap[i] < heap[j]) break;
       else swap(heap[i], heap[j]);
       i=j;
      }
    }
    void pop(){
      size--;
      heap[0] = heap[size];
      down(0);
    }
堆的应用

   堆排序:
      将N个数一次插入
    堆中,然后做N次删除
    堆顶元素操作,就可
    以获得顺序的排列。

   时间复杂度:
      O(n*log(n))
完成练习
   练习题集地址:
   http://acm.hust.edu.cn:8080/judge/contest/contest/vi
    ew.action?cid=8278#overview

   Problem A CodeForces 140C New Year Snowmen
    Problem B HDU 2680 Choose the best route
字典树
 Trie
字典树 导引问题 (HDOJ-1251)
 Ignatius最近遇到一个难题,老师交
给他很多单词(只有小写字母组
成,不会有重复的单词出现),现在老
师要他统计出以某个字符串为前缀
的单词数量(单词本身也是自己的
前缀).
字典树 导引问题 (HDOJ-1251)
 假设单词表容量为M,需要统计的
前缀数量为N,单词的平均长度为L,
则常规算法的时间复杂度是?

 如果单词表容量很大->查找效率?     -
  >低
 更有效率的方法:字典树
什么是字典树
 字典树:又称为Trie,是一种用于快速
检索的多叉树结构。Trie把要查找的关
键词看作一个字符序列,并根据构成
关键词字符的先后顺序构造用于检索
的树结构;一棵m度的Trie树或者为
空,或者由m棵m度的Trie树构成。

 特别地:和二叉查找树不同,在Trie树
中,每个结点上并非存储一个元素。
字典树的图示
         特点:
          利用串的公共前缀-
           >节约内存
          根结点不包含任何
           字母
          其余结点仅包含一
           个字母(非元素)
          每个结点的子节点
           包含字母不同
字典树的结构定义
   struct dictree
   {
      struct dictree *child[26];
      int n;
   };

   附注解:
   1:child[26]中的26表示字符集大小,也可以是
    10,可以是52,依据具体情况而定。
   2:int n是附加属性,在这个题里用于统计单词出
    现的次数,如果只需要统计某个单词是否出现
    过,其实还可以定义为一个布尔变量,比如bool
    touch;
字典树的建立过程
   void insert (char *source)
   {
       int len,i,j;
       struct dictree *current,*newnode;
       len=strlen(source);
       if(len==0) return;
       current=root;
       for(i=0;i<len;i++)
       {
           if(current->child[source[i]-'a']!=0)
           {
               current=current->child[source[i]-'a'];
               current->n=current->n+1;
           }
           else
           {
               newnode=(struct dictree *)malloc(sizeof(struct dictree));
               for(j=0;j<26;j++)
                   newnode->child[j]=0;
               current->child[source[i]-'a']=newnode;
               current=newnode;
               current->n=1;
           }
       }
   }
字典树的查找(主要操作)
   int find(char *source)
   {
       int i,len;
       struct dictree *current;
       len=strlen(source);
       if(len==0) return 0;
       current=root;
       for(i=0;i<len;i++)
       {
           if(current->child[source[i]-'a']!=0)
               current=current->child[source[i]-'a'];
           else return 0;
       }
       return current->n;
   }
内存申请的小优化
   malloc过程是非常占用时间的,一个题目中字典树需
    要消耗的最大内存通常是可以估计的,因此一个优化
    的办法是,提前申请好内存,比如:
       在程序开始阶段定义一个数组dictree mem[maxnode];
       和一个当前已使用节点数的计数变量size_t mpt=0;
           newnode=(struct dictree *)malloc(sizeof(struct dictree));
           修改为
           Newnode=&mem[mpt++];



   这样可以节省不少建立字典树的时间。
完成练习
   练习题集地址:
   http://acm.hust.edu.cn:8080/judge/contest/contest/vi
    ew.action?cid=8278#overview

   Problem C POJ 2513 Colored Sticks
   Problem D POJ 2503 Babelfish
线段树
Segment Tree
线段树
 请参照罗康琦的课件
完成练习
   练习题集地址:
   http://acm.hust.edu.cn:8080/judge/contest/contest/vi
    ew.action?cid=8278#overview

   Problem E POJ 2528 Mayor's posters
   Problem F POJ 2777 Count Color
   Problem G POJ 3277 City Horizon
   Problem H POJ 1177 Picture
   Problem I POJ 1151 Atlantis
   Problem J POJ 3368 Frequent values
   Problem K POJ 3225 Help with Intervals
Referance
   1、ACM程序设计集训队讲座(二)
                            刘春英
   2、《ACM/ICPC系列讲座》万丈高楼平地起——
    基本算法及应用
                                戎术


             谢谢他们的ppt
             谢谢大家光临!

数据结构回顾