Python数据结构与算法(十六、基于Trie和二分搜索树的字符串集合的性能比较)

保证一周更两篇吧,以此来督促自己好好的学习!代码的很多地方我都给予了详细的解释,帮助理解。好了,干就完了~加油!
声明:本python数据结构与算法是imooc上liuyubobobo老师java数据结构的python改写,并添加了一些自己的理解和新的东西,liuyubobobo老师真的是一位很棒的老师!超级喜欢他~
如有错误,还请小伙伴们不吝指出,一起学习~
No fears, No distractions.

一、背景阐述

我们上一章实现了Trie树,别忘了我们的Trie树是不包含重复字符串的哦,所以天然可以用来当做字符串集合来使用。而且我们在前面的章节也实现了一个基于二分搜索树的集合,本章我们来对它俩做一个关于“添加元素”的性能上的比较。

二、注意事项

  1. 一般有意义的字符串的长度不超过15,即人们无论是在网页还是一些网页版字典上所查询的字符串长度一般不会很大,这是前提,如果你用它俩来对比长字符串的添加操作性能,可以明确的告诉你,Trie完败/(ㄒoㄒ)/~~,因为它的性能是正比于字符串的长度的。
  2. 我们以前实现的二分搜索树不是像红黑树那样是一种平衡二叉树,我们的这个树在某些时候会退化成链表的性能,红黑树后面会讲的!所以在这里比较它俩的性能对基于二分搜索树的集合来说可能有点不公平- -。

二、测试代码设计

# -*- coding: utf-8 -*-
# Author: Annihilation7
# Data: 2018-12-22 16:14
# Python version: 3.6

import sys 
sys.path.append('/home/tony/Code/data_structure') 
from SET.bstSet import BstSet # 导入我们以前实现的以二分搜索树作为底层数据结构的集合类
from queue.testQueueAndLoopqueue import count_time   # 导入我们以前实现的记录操作所用时间的装饰器
from dict_tree.trie import Trie # 导入我们刚刚实现的trie类

import numpy as np 

keys = u"小菜逼学数据结构与算法的心酸历程,这其中lsnf;sdnfajn;slfjndjwoiruf98273lksjhdflzvn,m.alkfjo23谁特么知道。。。"


def gen_string(keys, nums):
    """ 生成不定长字符串数组的辅助函数 Params: - keys: 包含待筛选的character的字符集 - nums: 生成多少个字符串呢 Returns: 一个list,包含全部生成的字符串,list长度肯定是nums啦。 """
    keys_character = list(keys)
    ret = []
    for count in range(nums):
        len_string = np.random.randint(10) # 要注意这里我测试的字符串长度都不超过10,因为实际上有意义的字符串一般也不会特别大
        # 你在跑的时候可以把len_string调大,会发现trie要比bst_set慢很多。
        assert 10 < len(keys), '???'
        ret.append(''.join(np.random.choice(keys_character, len_string)))
    return ret 


@count_time
def test_trie():
    """测试trie树的性能"""
    global trie_set, data
    for data_element in data:
        trie_set.add(data_element)


@count_time
def test_bstSet():
    """ 测试bst_set的性能,这里做个小声明吧,我们以前实现的二分搜索树在某些情况下性能会退化成一个链表的性能,等 后面讲完红黑树这些平衡二叉树就好了,在这里对我们的集合进行测试对它有一点点不公平/(ㄒoㄒ)/~~ """
    global bst_set, data
    for data_element in data:
        bst_set.add(data_element)


if __name__ == '__main__':
    bst_set = BstSet()
    trie_set = Trie()
    data = gen_string(keys, 80000)  # 生成80000个字符串吧
    print('测试trie树的添加字符串性能:')
    test_trie()
    print('=' * 20)
    print('测试以二分搜索树为底层的集合的添加相同字符串性能:')
    test_bstSet()

三、输出

测试trie树的添加字符串性能:
共用时: 0.6621====================
测试以二分搜索树为底层的集合的添加相同字符串性能:
共用时: 0.876852

四、总结

  1. Trie在80000这个数据容量的条件下性能略优于前面我们实现的基于二分搜索树的集合。
  2. 如果你承载的字符串数量越多(这里是80000),trie树的优势就越明显。如果你能塞到千万级别甚至亿万级别数据的话,这个优势会非常的大,因为Trie的添加操作的时间复杂度只正比与你当前要添加的字符串长度!

若有还可以改进、优化的地方,还请小伙伴们批评指正!

    原文作者:Trie树
    原文地址: https://blog.csdn.net/Annihilation7/article/details/85210534
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞