数据结构——键树

转载 2012年03月22日 17:47:06

学到“键树”,实在不知道这个有什么用途,上网搜索也没有什么答案,找到一篇,先转了备用。


http://blog.csdn.net/xiashengwang/article/details/6722059


偶然在网上看见C#实现的键树,以前不知这东东是啥玩意(数据结构没过关),有何用途?于是仔细研学了一把,本人对这种算法的东西,看着就头痛,自己照着做了一遍。基本参考网上已实现的代码算法,放于此,给自己做个参考,以备查阅。以下是代码: 

using System;
using System.Collections.Generic;
using System.Text;

namespace AlgorithmTest
{
    /// <summary>
    /// 键树(一般应用于大数据量的查找)
    /// <remarks>
    /// 如果一个关键字可以表示成字符的序号,即字符串,那么可以用键树(keyword tree),
    /// 又称数字搜索树(digital search tree)或字符树,来表示这样的字符串的集合。
    /// 键树是一棵多叉树,树中每个结点并不代表一个关键字或元素,而只代表字符串中的一个字符。
    /// 例如,它可以表示数字串中的一个数位,或单词中的一个字母等等。根结点不代表任何字符,
    /// 根以下第一层的结点对应于字符串的第一个字符,第二层的结点对应于字符串的第二个字符……
    /// 每个字符串可由一个特殊的字符如“$”等作为字符串的结束符,用一个叶子结点来表示该特殊字符。
    /// 把从根到叶子的路径上,所有结点(除根以外)对应的字符连接起来,就得到一个字符串。因此,
    /// 每个叶子结点对应一个关键字。在叶子结点还可以包含一个指针,指向该关键字所对应的元素。
    /// 整个字符串集合中的字符串的数目等于叶子结点的数目。如果一个集合中的关键字都具有这样的字符串特性,
    /// 那么,该关键字集合就可采用这样一棵键树来表示。事实上,还可以赋予“字符串”更广泛的含义,
    /// 它可以是任何类型的对象组成的串。
    /// </remarks>
    /// </summary>
    [Serializable()]
    public class KeyTree
    {
        private bool _keyChanged = false;
        //根节点
        private KeyTreeNode rootNode = new KeyTreeNode();
        //添加数到键数中
        public void AddKey(long key)
        {
            string strKey = key.ToString();
            KeyTreeNode tempNode = rootNode;
            for (int i = 0; i < strKey.Length; i++)
            {
                int index = int.Parse(strKey[i].ToString());
                if (i == strKey.Length - 1)
                {
                    tempNode.endFlags[index] = true;
                    _keyChanged = true;
                    break;
                }
                if (tempNode.pointers[index] == null)
                    tempNode.pointers[index] = new KeyTreeNode();
                tempNode = tempNode.pointers[index];
            }
        }
        //删除key
        public void RemoveKey(long key)
        {
            string strKey = key.ToString();
            KeyTreeNode tempNode = rootNode;
            for (int i = 0; i < strKey.Length; i++)
            {
                int index = int.Parse(strKey[i].ToString());
                if (tempNode != null)
                {
                    if (i == strKey.Length - 1 && tempNode.endFlags[index] == true)
                    {
                        tempNode.endFlags[index] = false;
                        _keyChanged = true;
                    }
                    else
                    {
                        tempNode = tempNode.pointers[index];
                    }
                }
                else
                {
                    break;
                }
            }
        }
        //key存在判定
        public bool IsExist(long key)
        {
            string strKey = key.ToString();
            KeyTreeNode tempNode = rootNode;
            for(int i =0;i<strKey.Length;i++)
            {
                int index = int.Parse(strKey[i].ToString());
                if (tempNode != null)
                {
                    if (i == strKey.Length - 1 && tempNode.endFlags[index] == true)
                        return true;
                    else
                        tempNode = tempNode.pointers[index];
                }
                else
                {
                    return false;
                }
            }
            return false;
        }
        //key清除
        public void Clear()
        {
            for (int i = 0; i < rootNode.pointers.Length; i++)
            {
                rootNode.pointers[i] = null;
                rootNode.endFlags[i] = false;
            }
            _keyChanged = true;
            _lstKey.Clear();
        }
        //取得全部的key
        private List<long> _lstKey = new List<long>();
        public List<long> Keys
        {
            get
            {
                if (_keyChanged)
                {
                    _lstKey.Clear();
                    FindAllKey(rootNode, "", ref _lstKey);
                    _keyChanged = false;
                }
                return _lstKey;
            }
        }
        //(这个递归,头都想大了,我太菜了。。。)
        private void FindAllKey(KeyTreeNode treeNode, string strKey, ref List<long> lstKey)
        {
            for (int i = 0; i < treeNode.pointers.Length; i++)
            {
                string keyTemp = strKey + i.ToString();
                if (treeNode.endFlags[i] == true)
                {
                    lstKey.Add(Convert.ToInt64(keyTemp));
                }  
                if (treeNode.pointers[i] != null)
                {
                    FindAllKey(treeNode.pointers[i], keyTemp, ref lstKey);
                }              
            }
        }
    }
    [Serializable]
    public class KeyTreeNode
    {
        public KeyTreeNode[] pointers = new KeyTreeNode[10];
        public bool[] endFlags = new bool[10];
    }    
}

测试代码:

            m_keyTree.Clear();
            System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
            sw.Start();
            for (long i = 0; i < long.Parse(this.textBox1.Text); i++)
            {
                m_keyTree.AddKey(i);
            }
            sw.Stop();
            MessageBox.Show("time:" + sw.ElapsedMilliseconds);
            System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bf = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
            System.IO.MemoryStream ms = new System.IO.MemoryStream();
            bf.Serialize(ms, m_keyTree);
            MessageBox.Show("byte(kb):" + ms.Length / 1024);  


经过测试,发现这种键数的查找速度和HashTable基本相当,但是内存用量却只有HashTable的一半不到。这个对于大容量的数据查找还是一种可行的方法。

备注:key值为long型,对于一些字符串或对象集合的查找处理,可用对象的GetHashCode()方法转换成一个哈希值,再使用KeyTree。

看数据结构写代码(59) 键树的双链表示法

杂谈; 打败自己的 往往不是敌人,而是自己。坚持不易,且行且珍惜。 键树 是一种 把  把  非叶子节点 当成索引,叶子节点保存具体信息的一种树。 例如:   它的 键树形式如下: 键树 有...
  • fuming0210sc
  • fuming0210sc
  • 2015年04月28日 21:59
  • 581

数据结构——键树之Tire树

#include "stdio.h" #include "stdlib.h" #include "string.h" #include "ctype.h" #define OK 1 #d...
  • minyuanxiani
  • minyuanxiani
  • 2013年09月03日 16:38
  • 414

键树

键树又称为数字查找树,它是一颗度大于等于2的树,树中的每个结点中不是包含一个或几个关键字,而是只含有组成关键字的符号。例如,若关键字为数值,则结点中只包含一个数位;若关键字为单词,则结点中只包含一个字...
  • mevicky
  • mevicky
  • 2015年05月27日 08:02
  • 1290

数据结构——键树

偶然在网上看见C#实现的键树,以前不知这东东是啥玩意(数据结构没过关),有何用途?于是仔细研学了一把,本人对这种算法的东西,看着就头痛,自己照着做了一遍。基本参考网上已实现的代码算法,放于此,给自己做...
  • xiashengwang
  • xiashengwang
  • 2011年08月26日 15:10
  • 1179

从零开始_学_数据结构(二)——树的基本概念

相比之前的帖子,对其进行了增添和完善。 ps:本颜色的字体是后续添加内容 —————————————————— 参考链接: 大话数据结构.pdf 图解数据结构(6)——树及树的遍历 ...
  • qq20004604
  • qq20004604
  • 2016年03月20日 16:07
  • 8648

数据结构-树(基本概念整合)

树形结构是一张非常重要的非线性数据结构。其中
  • DouBoomFly
  • DouBoomFly
  • 2017年05月01日 00:16
  • 679

数据结构------树

树 什么是树呢?树是以递归的方式进行定义,树是有且仅有一个根结点,其余各结点构成互不相交的子树。 其实学习“树”个人认为需要首先学习“递归”。当然不必深入的学习,需要把基本的例子能用代码实现,如:...
  • maidi_2015
  • maidi_2015
  • 2015年08月26日 16:41
  • 1032

B-tree B+tree 数据结构解析

B-tree,B是balance,一般用于数据库的索引。使用B-tree结构可以显著减少定位记录时所经历的中间过程,从而加快存取速度。而B+tree是B-tree的一个变种,大名鼎鼎的MySQL就普遍...
  • wlchn
  • wlchn
  • 2015年08月10日 19:15
  • 1470

数据结构学习——树的基本分类

自学数据结构已经很久了,使用的教材是《数据结构与算法分析——C语言描述》。现在回过头来再看一遍此书,重新梳理一下数据结构的相关知识。 以下是摘自维基百科的一些树的基本分类: 无序树:树中任意节点...
  • u010275850
  • u010275850
  • 2015年03月29日 20:21
  • 1748

数据结构复习之【树】

名词解释    树这个数据结构用到了递归的概念:树的子树还是树; 度:节点的子树个数; 树的度:树中任意节点的度的最大值; 兄弟:两节点的parent相同; 层:根在第一层,以此类推; ...
  • xiazdong
  • xiazdong
  • 2012年02月26日 20:36
  • 25388
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:数据结构——键树
举报原因:
原因补充:

(最多只允许输入30个字)