1. 程式人生 > >python實現二叉查詢樹

python實現二叉查詢樹

1. 定義

二叉查詢樹(Binary Search Tree),又稱為二叉搜尋樹、二叉排序樹。其或者是一棵空樹;或者是具有以下性質的二叉樹:

  • 若左子樹不空,則左子樹上所有結點的值均小於或等於它的根結點的值
  • 若右子樹不空,則右子樹上所有結點的值均大於或等於它的根結點的值
  • 左、右子樹也分別為二叉排序樹
    圖 1
    圖 1

    樹中節點的定義如下:
class Node:
    def __init__(self, data):
        self.data = data
        self.lchild = None
        self.rchild = None

2. 查詢與插入

當二叉查詢樹不為空時:

  • 首先將給定值與根結點的關鍵字比較,若相等,則查詢成功
  • 若小於根結點的關鍵字值,遞迴查左子樹
  • 若大於根結點的關鍵字值,遞迴查右子樹
  • 若子樹為空,查詢不成功

二叉排序樹是一種動態樹表。其特點是:樹的結構通常不是一次生成的,而是在查詢過程中,當樹中不存在關鍵字等於給定值的結點時再進行插入。新插入的結點一定是一個新新增的葉子結點,並且是查詢不成功時查詢路徑上訪問的最後一個結點的左孩子或右孩子結點。如下圖所示:

這裡寫圖片描述

插入與搜尋的程式碼:

     # 搜尋
    def search(self, node, parent, data):
        if
node is None: return False, node, parent if node.data == data: return True, node, parent if node.data > data: return self.search(node.lchild, node, data) else: return self.search(node.rchild, node, data) # 插入 def insert
(self, data):
flag, n, p = self.search(self.root, self.root, data) if not flag: new_node = Node(data) if data > p.data: p.rchild = new_node else: p.lchild = new_node

3. 刪除

二叉查詢樹的刪除操作分為三種情況:

  1. 如果待刪除的節點是葉子節點,那麼可以立即被刪除,如下圖所示:
    這裡寫圖片描述
  2. 如果節點只有一個兒子,則將此節點parent的指標指向此節點的兒子,然後刪除節點,如下圖所示:
    這裡寫圖片描述
  3. 如果節點有兩個兒子,則將其右子樹的最小資料代替此節點的資料,並將其右子樹的最小資料刪除,如下圖所示:
    這裡寫圖片描述

刪除節點的程式碼:

    # 刪除
    def delete(self, root, data):
        flag, n, p = self.search(root, root, data)
        if flag is False:
            print "無該關鍵字,刪除失敗"
        else:
            if n.lchild is None:
                if n == p.lchild:
                    p.lchild = n.rchild
                else:
                    p.rchild = n.rchild
                del n
            elif n.rchild is None:
                if n == p.lchild:
                    p.lchild = n.lchild
                else:
                    p.rchild = n.lchild
                del n
            else:  # 左右子樹均不為空
                pre = n.rchild
                if pre.lchild is None:
                    n.data = pre.data
                    n.rchild = pre.rchild
                    del pre
                else:
                    next = pre.lchild
                    while next.lchild is not None:
                        pre = next
                        next = next.lchild
                    n.data = next.data
                    pre.lchild = next.rchild
                    del next

4. 遍歷

1. 先序遍歷

訪問順序如下:

  • 訪問根節點
  • 先序遍歷左子樹
  • 先序遍歷右子樹

以圖 1為例,訪問順序為:4,2,1,3,5,6

    # 先序遍歷
    def preOrderTraverse(self, node):
        if node is not None:
            print node.data,
            self.preOrderTraverse(node.lchild)
            self.preOrderTraverse(node.rchild)

2. 中序遍歷

訪問順序如下:

  • 中序遍歷左子樹
  • 訪問根節點
  • 中序遍歷右子樹

以圖 1為例,訪問順序為:1,2,3,5,7,9

    # 中序遍歷
    def inOrderTraverse(self, node):
        if node is not None:
            self.inOrderTraverse(node.lchild)
            print node.data,
            self.inOrderTraverse(node.rchild)

3. 後序遍歷

訪問順序如下:

  • 後序遍歷左子樹
  • 後序遍歷右子樹
  • 訪問根節點
    以圖 1為例,訪問順序為:1,3,2,9,7,5
    # 後序遍歷
    def postOrderTraverse(self, node):
        if node is not None:
            self.postOrderTraverse(node.lchild)
            self.postOrderTraverse(node.rchild)
            print node.data,

5. 完整程式碼

# encoding: utf-8
class Node:
    def __init__(self, data):
        self.data = data
        self.lchild = None
        self.rchild = None

class BST:
    def __init__(self, node_list):
        self.root = Node(node_list[0])
        for data in node_list[1:]:
            self.insert(data)

    # 搜尋
    def search(self, node, parent, data):
        if node is None:
            return False, node, parent
        if node.data == data:
            return True, node, parent
        if node.data > data:
            return self.search(node.lchild, node, data)
        else:
            return self.search(node.rchild, node, data)

    # 插入
    def insert(self, data):
        flag, n, p = self.search(self.root, self.root, data)
        if not flag:
            new_node = Node(data)
            if data > p.data:
                p.rchild = new_node
            else:
                p.lchild = new_node

    # 刪除
    def delete(self, root, data):
        flag, n, p = self.search(root, root, data)
        if flag is False:
            print "無該關鍵字,刪除失敗"
        else:
            if n.lchild is None:
                if n == p.lchild:
                    p.lchild = n.rchild
                else:
                    p.rchild = n.rchild
                del p
            elif n.rchild is None:
                if n == p.lchild:
                    p.lchild = n.lchild
                else:
                    p.rchild = n.lchild
                del p
            else:  # 左右子樹均不為空
                pre = n.rchild
                if pre.lchild is None:
                    n.data = pre.data
                    n.rchild = pre.rchild
                    del pre
                else:
                    next = pre.lchild
                    while next.lchild is not None:
                        pre = next
                        next = next.lchild
                    n.data = next.data
                    pre.lchild = next.rchild
                    del p


    # 先序遍歷
    def preOrderTraverse(self, node):
        if node is not None:
            print node.data,
            self.preOrderTraverse(node.lchild)
            self.preOrderTraverse(node.rchild)

    # 中序遍歷
    def inOrderTraverse(self, node):
        if node is not None:
            self.inOrderTraverse(node.lchild)
            print node.data,
            self.inOrderTraverse(node.rchild)

    # 後序遍歷
    def postOrderTraverse(self, node):
        if node is not None:
            self.postOrderTraverse(node.lchild)
            self.postOrderTraverse(node.rchild)
            print node.data,

a = [49, 38, 65, 97, 60, 76, 13, 27, 5, 1]
bst = BST(a)  # 建立二叉查詢樹
bst.inOrderTraverse(bst.root)  # 中序遍歷

bst.delete(bst.root, 49)
print
bst.inOrderTraverse(bst.root)

相關推薦

python實現查詢

1. 定義 二叉查詢樹(Binary Search Tree),又稱為二叉搜尋樹、二叉排序樹。其或者是一棵空樹;或者是具有以下性質的二叉樹: 若左子樹不空,則左子樹上所有結點的值均小於或等於它的根結點的值 若右子樹不空,則右子樹上所有結點的值均大於或等於它

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

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

JS 實現查詢(Binary Search Tree)

知識點 二叉查詢樹,也稱二叉搜尋樹、有序二叉樹(英語:ordered binary tree)是指一棵空樹 任意節點的左子樹不空,則左子樹上所有結點的值均小於它的根結點的值; 任意節點的右子樹不空,則右子樹上所有結點的值均大於它的根結點的值; 任意節點的左、

python3 實現查詢的搜尋、插入、刪除

1. 定義 二叉查詢樹(Binary Search Tree),又稱為二叉搜尋樹、二叉排序樹。其或者是一棵空樹;或者是具有以下性質的二叉樹: 若左子樹不空,則左子樹上所有結點的值均小於或等於它的根結點的值 若右子樹不空,則右子樹上所有結點的值均大於或等於它的

前端你也需要了解的演算法,概念及JS實現查詢

前述:樹是電腦科學中經常用到的一種資料結構。樹是一種非線性的資料結構,以分層的形式儲存資料。樹被用來儲存具有層級關係的資料結構,比如檔案系統中的檔案;樹還被用來儲存有序列表。 樹的定義 樹是由一組以邊連線的節點組成。公司的組織結構圖就是一個樹的例子。 二叉樹 二叉

js實現查詢的建立、插入、刪除、遍歷操作

1 概念 二叉排序樹(二叉查詢樹),它或者是一顆空樹,或者是具有以下性質的二叉樹: 任意一個結點左子樹上的所有結點值均小於該結點值 任意一個結點右子樹上的所有結點值均大於該結點值 例如下圖: 2 插入和建立二叉排序樹 結點的資料結構 fu

Python實現搜尋

class TreeNode: def __init__(self, key, val, left=None, right=None, parent=None): self.key = key self.payload = val self.leftChild

[C語言實現]實現查詢基本操作(遞迴版,圖示)

定義 二叉查詢樹是一種特殊的二叉樹,它不僅是一顆二叉樹,還滿足如下性質 對於任何非葉子節點,他的左節點都小於它本身,而右節點都大於其本身. 它的左右子樹也分別而二叉搜尋樹 一般情況下,在這麼一棵樹中進行查詢,它的時間複雜度是 longnlon

C#實現查詢

/// <summary> /// 二叉樹節點的定義 /// </summary> public class Node { //本身的資料 public int dat

C語言實現查詢(BST)的基本操作

     我們在上一篇部落格中講解了二叉樹,這一次我們來實現二叉樹的進階——二叉查詢樹(Binary Search Tree),又稱二插排序樹(Binary Sort Tree)。所以簡稱為BST。二插查詢樹的定義如下:1.若左子樹不為空,則左子樹上所有節點的值均小於它的根節

java實現查詢(插入、刪除、遍歷、查詢)

閒話: 繼續擼資料結構和演算法。看資料結構推薦一個視覺化工具吧(http://visualgo.net/),沒有圖憑腦袋想是很痛苦的。 正文: 二叉查詢樹,也叫二叉搜尋樹、有序二叉樹,排序二叉樹,滿足以下性質(非嚴謹描述):       1.對於每個節點,其左子節點要麼

C語言實現查詢的輸出

二叉樹是資料結構和演算法中的重要部分。本文將簡單介紹其中的一類——二叉查詢樹:         二叉排序樹(BinarySortTree),又稱二叉查詢樹、二叉搜尋樹。它或者是一棵空樹;或者是具有下列

java實現查詢

package ustc.zyy.ArrayList; /** * @author zhang yin ye * @date 2014 6 17 * */ import java.util.DuplicateFormatFlagsException; pu

查詢(binary search tree)——python實現

二叉查詢樹(binary search tree) 顧名思義二叉查詢樹中每個節點至多有兩個子節點,並且還對儲存於每個節點中的關鍵字值有個小小的要求, 即只要這個節點有左節點或右節點,那麼其關鍵字值總的大於其左節點的關鍵字值,小於其右節點的關鍵字值,如下圖: 因為樹的結

查詢Python實現

 二叉查詢樹,即左孩子小於根節點,右孩子大於根節點。 對於每一次新的節點插入操作,依據這個規則進行插入,最終使得樹的最右端為最大值,最左端為最小值。 由於二叉查詢樹是進入AVL平衡二叉樹的學習的前提,因此先進行這個的實現。   可以通過對節點的info屬性進行賦值,以作查

查詢python實現

1. 二叉查詢樹的定義: 左子樹不為空的時候,左子樹的結點值小於根節點,右子樹不為空時,右子樹的結點值大於根節點,左右子樹分別為二叉查詢樹 2. 二叉查詢樹的最左邊的結點即為最小值,要查詢最小值,只需遍歷左子樹的結點直到為空為止,同理,最右邊的結點結尾最大值,要查詢最大值,

Python實現的遍歷

二叉樹的遍歷 終端 ini right name 一個 pan 樹的遍歷 二叉樹 二叉樹是有限個元素的集合,該集合或者為空、或者有一個稱為根節點(root)的元素及兩個互不相交的、分別被稱為左子樹和右子樹的二叉樹組成。 二叉樹的每個結點至多只有二棵子樹(不存在度大於2的結

python-實現

__main__ 處理 後序 print binary pos 優先 pan 實現 # encoding=utf-8 class Node(object): def __init__(self, item): self.item = item

Python實現的非遞歸先序遍歷

結果 leetcode logs [] 列表 遍歷 不存在 preorder bin 思路: 1. 使用列表保存結果; 2. 使用棧(列表實現)存儲結點; 3. 當根結點存在,保存結果,根結點入棧; 4. 將根結點指向左子樹; 5. 根結點不存在,棧頂元素出棧,並將根結點指

Python實現的建立以及遍歷(遞迴前序、中序、後序遍歷,隊棧前序、中序、後序、層次遍歷)

class Node: def __init__(self,data): self.data=data self.lchild=None self.rchild=None class Tree: def __init__(se