1. 程式人生 > >用python實現二叉搜尋樹/查詢樹的簡單實現及驗證(判斷)(三)(棧中根序遍歷)

用python實現二叉搜尋樹/查詢樹的簡單實現及驗證(判斷)(三)(棧中根序遍歷)

基於棧的中根序深度優先遍歷判斷法(天然排序,每次比上一個值大即可)。

由搜尋樹的性質推得中根序深度遍歷為一個從小到大的有序序列。所以根據這一性質事情就好辦了,只要在遍歷過程中加入與前一值得比較判斷即能達到目的(複雜度O(n),推薦演算法)。程式碼如下:

def midorder(t):   #中根序遍歷比較判斷,複雜度O(n)推薦演算法
    s = []            #工作棧,為省事直接用list沒有從新定義一個棧類再用
    a = []  #一個表記錄已經遍歷過的結點以便回溯時不再次遍歷
    b = float('-Inf') #用於記錄上一單位遍歷的值,初始化為負無窮
    while t or len(s):  #t不為None或棧不空
        if ((not t.right)and(not t.left))or t in a:  #無子節點或已遍歷過
            if t.data <= b:  #比較判斷


                return False
            else:
                b = t.data
                if len(s):
                    t = s.pop()    #彈出下一個
                else:
                    return True  #棧空,執行完沒False則返回True
            continue  #再從迴圈體頭部開始執行
        else:         #有子節點且沒遍歷過,依次將右子,中,左子入棧
            if t.right:       
                s.append(t.right)
            s.append(t)
            if t.left:
                s.append(t.left)
            a.append(t)       #記錄此節點已遍歷過

        t = s.pop()  #彈出下一個

這個是O(n)(約4n,中根序遍歷3n)複雜度的演算法,已測過可用。其它幾篇思路可行,但有的複雜度不是最優,所以只寫出來記錄下。不放心的也可以再測下:

class Node(object):
    def __init__(self,data,left=0,right=0):
        self.data=data
        self.left=left

        self.right=right

if __name__ == '__main__':
    # 手動建立一課二叉樹
    tree = Node(1)
    tree.left = Node(2, None, None)
    tree.right = Node(3, None, None)
    tree.left.left = Node(4, None, None)
    tree.left.right = Node(5, None, None)
    tree.right.left = Node(6, None, None)
    tree.right.right = Node(7, None, None)
    tree.left.left.left = Node(8, None, None)
    tree.left.left.right = Node(9, None, None)
    tree.left.right.left = Node(10, None, None)
    tree.left.right.left.right = Node(11, None, None)
    print("手動建立一個二叉樹(非搜尋樹)並判斷")
    print(midorder(tree))


    #再建立一個搜尋樹
    print("再建立一個二叉樹(搜尋樹)並判斷")
    tree0 = Node(8)
    tree0.left = Node(5, None, None)
    tree0.right = Node(10, None, None)
    
    tree0.left.left = Node(3, None, None)
    tree0.left.right = Node(6, None, None)
    tree0.right.left = Node(9, None, None)
    tree0.right.right = Node(11, None, None)
    tree0.left.left.left = Node(2, None, None)
    tree0.left.left.right = Node(4, None, None)

    print(midorder(tree0))

                                               ————全文完,歡迎轉載,但請註明出處!