zoukankan      html  css  js  c++  java
  • 算法导论83(b)习题解答(trie树)

    CLRS 8-3(b) :

            给定一个字符串数组,其中不同的串包含的字符数可能不同,但所有串中总的字符个数为n。说明如何在O(n)时间内对该数组进行排序。

    算法思想:

    1.在这里用空间来换取时间,因而采用trie树,即字典树,顾名思义,像一本字典一样。

    2.将每个字符串插入到trie树中,到达特定的结尾节点时,在这个节点上进行标记,如插入"afb",第一个字母为a,沿着a往下,然后第二个字母为f,沿着f往下,第三个为b,沿着b往下,由于字符串最后一个字符为'\0',因而结束,不再往下了,然后在这个节点上标记afb.count++,即其个数增加1.

    3.通过前序遍历此树,即可得到字符串从小到大的顺序。

    #include <iostream>
    #include
    <string>
    using namespace std;

    #define NUM 26

    class Node
    {
    public:
      int count; //记录该处字符串个数
      Node* char_arr[NUM]; //分支
      char* current_str; //记录到达此处的路径上的所有字母组成的字符串
      Node();
    };

    class Trie
    {
    public:
      Node
    * root;
      Trie();

      void insert(char* str);
      void output(Node*&node, char** str, int& count);
    };

    //程序未考虑delete动态内存
    int main()
    {
      char** str =newchar*[12];
      str[
    0] ="zbdfasd";
      str[
    1] ="zbcfd";
      str[
    2] ="zbcdfdasfasf";
      str[
    3] ="abcdaf";
      str[
    4] ="defdasfa";
      str[
    5] ="fedfasfd";
      str[
    6] ="dfdfsa";
      str[
    7] ="dadfd";
      str[
    8] ="dfdfasf";
      str[
    9] ="abcfdfa";
      str[
    10] ="fbcdfd";
      str[
    11] ="abcdaf";

      //建立trie树
      Trie* trie =new Trie();
      for(int i =0; i <12; i++)
      trie
    ->insert(str[i]);

      int count =0;
      trie
    ->output(trie->root, str, count);

      for(int i =0; i <12; i++)
        cout
    <<str[i]<<endl;

      return 0;
    }

    Node::Node()
    {
      count
    =0;
      for(int i =0; i < NUM; i++)
        char_arr[i]
    = NULL;
      current_str
    new char[100];
      current_str[
    0] '\0';
    }

    Trie::Trie()
    {
      root
    new Node();
    }

    void Trie::insert(char* str)
    {
      int i =0;
      Node
    * parent = root;

      //将str[i]插入到trie树中
      while(str[i] !='\0')
      {
        //如果包含str[i]的分支存在,则新建此分支
        if(parent->char_arr[str[i] -'a'] == NULL)
        {
          parent
    ->char_arr[str[i] -'a'] =new Node();
          //将父节点中的字符串添加到当前节点的字符串中
          strcat(parent->char_arr[str[i] -'a']->current_str, parent->current_str);

          char str_tmp[2];
          str_tmp[
    0] = str[i];
          str_tmp[
    1] ='\0';

          //将str[i]添加到当前节点的字符串中
          strcat(parent->char_arr[str[i] -'a']->current_str, str_tmp);

          parent
    = parent->char_arr[str[i] -'a'];
        }
        else
        {
          parent
    = parent->char_arr[str[i] -'a'];
        }
        i
    ++;
      }
      parent
    ->count++;
    }

    //采用前序遍历
    void Trie::output(Node*&node, char** str, int& count)
    {
      if(node != NULL)
      {
        if(node->count !=0)
        {
          for(int i =0; i < node->count; i++)
          str[count
    ++] = node->current_str;
        }
        for(int i =0; i < NUM; i++)
        {
          output(node
    ->char_arr[i], str, count);
        }
      }
    }
    ---
    可以转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明
  • 相关阅读:
    第4月第1天 makefile automake
    第3月30天 UIImage imageWithContentsOfFile卡顿 Can't add self as subview MPMoviePlayerControlle rcrash
    第3月第27天 uitableviewcell复用
    learning uboot fstype command
    learning uboot part command
    linux command dialog
    linux command curl and sha256sum implement download verification package
    learning shell script prompt to run with superuser privileges (4)
    learning shell get script absolute path (3)
    learning shell args handing key=value example (2)
  • 原文地址:https://www.cnblogs.com/null00/p/2065069.html
Copyright © 2011-2022 走看看