算法_樹和二叉樹簡介

1、樹html

一、什麼是樹?node

樹狀圖是一種 數據結構,它是由n(n>=1)個有限節點組成一個具備層次關係的 集合。把它叫作「樹」是由於它看起來像一棵倒掛的樹,也就是說它是根朝上,而葉朝下的。它具備如下的特色:
每一個節點有零個或多個子節點;沒有父節點的節點稱爲根節點;每個非根節點有且只有一個父節點;除了根節點外,每一個子節點能夠分爲多個不相交的子樹;
樹(tree)是包含n(n>0)個結點的有窮集,其中:
(1)每一個元素稱爲結點(node);
(2)有一個特定的結點被稱爲根結點或樹根(root)。
(3)除根結點以外的其他數據元素被分爲m(m≥0)個互不相交的集合T1,T2,……Tm-1,其中每個集合Ti(1<=i<=m)自己也是一棵樹,被稱做原樹的子樹(subtree)。
 
二、相關術語
  • 節點的度:一個節點含有的子樹的個數稱爲該節點的度;
  • 葉節點或終端節點:度爲0的節點稱爲葉節點;
  • 非終端節點或分支節點:度不爲0的節點;
  • 雙親節點或父節點:若一個節點含有子節點,則這個節點稱爲其子節點的父節點;
  • 孩子節點或子節點:一個節點含有的子樹的根節點稱爲該節點的子節點;
  • 兄弟節點:具備相同父節點的節點互稱爲兄弟節點;
  • 樹的度:一棵樹中,最大的節點的度稱爲樹的度;
  • 節點的層次:從根開始定義起,根爲第1層,根的子節點爲第2層,以此類推;
  • 樹的高度或深度:樹中節點的最大層次;
  • 堂兄弟節點:雙親在同一層的節點互爲堂兄弟;
  • 節點的祖先:從根到該節點所經分支上的全部節點;
  • 子孫:以某節點爲根的子樹中任一節點都稱爲該節點的子孫。
  • 森林:由m(m>=0)棵互不相交的樹的集合稱爲森林;

2、二叉樹數據庫

一、什麼是二叉樹?數據結構

二叉樹,就是度不差過2的樹(節點最多有兩個叉)app

3、兩種特殊的二叉樹spa

一、滿二叉樹.net

一個二叉樹,若是每個層的結點數都達到最大值,則這個二叉樹就是滿二叉樹。指針

二、徹底二叉樹code

葉節點只能出如今最下層和次下層,而且最下面一層的結點都集中在該層最左邊的若干位置的二叉樹htm

滿二叉樹必定是徹底二叉樹,可是徹底二叉樹不必定是滿二叉樹

3、二叉樹的存儲方式

一、鏈式存儲方式

a、二叉樹的鏈式存儲:將二叉樹的節點定義爲一個對象,節點之間經過相似鏈表的連接方式來鏈接。

b、節點定義

class BiTreeNode:
    def __init__(self,data):  #data就是傳進去的節點的值
        self.data = data
        self.lchild = None
        self.rchild = None

c、二叉樹的遍歷:

I 、先(前)序遍歷:訪問根結點的操做發生在遍歷其左右子樹以前

   具體操做:若二叉樹非空,則依次執行以下操做:
  • ⑴ 訪問根結點;
  • ⑵ 遍歷左子樹;
  • ⑶ 遍歷右子樹。

II、中序遍歷:訪問根結點的操做發生在遍歷其左右子樹之中(間)。

     具體操做: 若二叉樹非空,則依次執行以下操做:
  • ⑴遍歷左子樹;
  • ⑵訪問根結點;
  • ⑶遍歷右子樹。

III、後序遍歷:訪問根結點的操做發生在遍歷其左右子樹以後。

      若二叉樹非空,則依次執行以下操做:
  • ⑴遍歷左子樹;
  • ⑵遍歷右子樹;
  • ⑶訪問根結點。

IV、層次遍歷

用一個隊列保存被訪問的當前節點的左右孩子以實現層序遍歷。

二叉樹的遍歷代碼以下

from collections import deque   #雙向隊列
from queue import Queue    #單向隊列

# import queue
# q = queue.Queue()
# q.put('ggg')
# q.get()
class BiTreeNode:
    def __init__(self,data):
        self.data = data
        self.lchild = None
        self.rchild = None

    @classmethod
    def pre_order(self,root):
        '''前序遍歷(根左右)'''
        if root: #若是有根節點
            print(root.data,end='')
            self.pre_order(root.lchild)
            self.pre_order(root.rchild)

    @classmethod
    def in_order(self,root):
        '''中序遍歷(左根右)'''
        if root:
            self.in_order(root.lchild)
            print(root.data,end='')
            self.in_order(root.rchild)

    @classmethod
    def out_order(self, root):
        '''後序遍歷(左右根)'''
        if root:
            self.out_order(root.lchild)
            self.out_order(root.rchild)
            print(root.data, end='')

    @classmethod
    def level_order(self,root):
        '''層次遍歷(第一層,第二層,第三層...藉助隊列來實現)'''
        queue = deque()
        queue.append(root)
        while len(queue) > 0:
            node = queue.popleft()
            print(node.data,end='')
            if node.lchild:
                queue.append(node.lchild)
            if node.rchild:
                queue.append(node.rchild)



#建立二叉樹
a = BiTreeNode("A")
b = BiTreeNode("B")
c = BiTreeNode("C")
d = BiTreeNode("D")
e = BiTreeNode("E")
f = BiTreeNode("F")
g = BiTreeNode("G")
e.lchild = a
e.rchild = g
a.rchild = c
c.lchild = b
c.rchild = d
g.rchild = f
root = e

#查看前序遍歷的結果
BiTreeNode.pre_order(root)   #EACBDGF
print('')
BiTreeNode.in_order(root)    #ABCDEGF
print('')
BiTreeNode.out_order(root)  #BDCAFGE
print('')
BiTreeNode.level_order(root)  #EAGCFBD

二、順序存儲方式

如上圖二叉樹標出了元素所對應的索引,那麼能夠有一下結論

一、父節點和左孩子節點的編號下標有什麼關係?

若是已知父親節點爲i,那麼他的左孩子節點爲2i+1

二、父節點和右孩子節點的編號下標有什麼關係?

三、反過來知道孩子找父親

(n-1)/2=i  # 左孩子求父節點
(n-2)/2=i  # 右孩子求父節點

4、二叉搜索樹

一、定義

二叉搜索樹是一棵二叉樹且知足性質:設X是二叉樹的一個節點。若是Y是X左子樹的一個節點,那麼Y.key <=X.key;

若是Y是X右子樹的一個節點,那麼Y.key>= X.key  (X.key表明X節點對應的值)

通俗的說也就是 若它的左子樹不空,則左子樹上全部結點的值均小於它的根結點的值; 若它的右子樹不空,則右子樹上全部結點的值均大於它的根結點的值; 它的左、右子樹也分別爲二叉搜索樹。

二、原理

二叉排序樹的查找過程和次優二叉樹相似,一般採起二叉鏈表做爲二叉排序樹存儲結構中序遍歷二叉排序樹可獲得一個關鍵字的有序序列,一個無序序列能夠經過構造一棵二叉排序樹變成一個有序序列,構造樹的過程即爲對無序序列進行排序的過程。每次插入的新的結點都是二叉排序樹上新的葉子結點,在進行插入操做時,沒必要移動其它結點,只需改動某個結點的指針,由空變爲非空便可。搜索,插入,刪除的複雜度等於樹高,O(log(n)).

三、二叉搜索樹的建立

可參考連接:https://visualgo.net/en/bst

四、二叉搜索樹的遍歷

五、二叉搜索樹的查詢、插入、刪除

插入:

刪除

好比要刪除65

好比要刪除66

代碼實現:

 待續....

六、二叉搜索樹存在的問題

存在的問題:當插入的是有序的時候,假如插入的數據特別多,找是能找到,可是是很花費時間的。

能夠有如下解決辦法:

  一、隨機化的二叉搜索樹(打亂順序插入)

   二、AVL樹

查找方法有:二分查找、二叉搜索樹、哈希查找、順序查找、斐波那契查找

5、AVL樹-----擴展(瞭解)

一、AVL樹:AVL樹是一棵自平衡的二叉搜索樹

二、AVL樹具備如下性質:  

  • 根的左右子樹的高度只差的絕對值不能超過1
  • 根的左右子樹都是平衡二叉樹

三、AVL的實現方式:旋轉

 

6、B樹

一、B樹:B樹是一棵自平衡的多路搜索樹。經常使用於數據庫的索引

 

7、其餘

 

參考or轉發

http://www.cnblogs.com/haiyan123/p/8400284.html

相關文章
相關標籤/搜索