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的添加操作的時間複雜度只正比與你當前要添加的字符串長度!

若有還可以改進、優化的地方,還請小夥伴們批評指正!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章