數據結構之樹與二叉樹

北航軟件工程專業考研991數據結構總結:

五、樹與二叉樹
1.樹與二叉樹的基本概念,基本特徵、名詞術語;
2.完全二叉樹與滿二叉樹的基本概念,二叉樹的基本性質及其應用;
3.二叉樹的順序存儲結構與二叉鏈表存儲結的基本原理;
4.二叉樹的前序遍歷、中序遍歷、後序遍歷和按層次遍歷,重點是二叉樹在以二叉鏈表作爲存儲結構基礎上各種遍歷算法(包括非遞歸算法)的設計與應用;
5.二叉排序樹的基本概念、建立(插入)、查找以及平均查找長度ASL的計算。

1、樹與二叉樹的基本概念,基本特徵,名詞術語

基本概念:

    樹的定義:結點的集合 + 節點之間關係的集合
    n >= 0個數據組成的結構及其之間的關係。n = 0 成爲空樹,只有一個根節點,除了根節點每個節點只有一個直接前驅,但是有多個直接後繼。

    任何一棵非空樹中,有一個特殊節點t屬於結點集合D,稱爲根節點,其餘節點被分爲m個子集 D1, D2, D3 ... 每個子集又是一棵樹,稱爲t的子樹。

基本特徵:

    1)、有且僅有一個節點沒有前驅結點,爲該樹的根節點;
    2)、除了根節點之外,每個節點有且僅有一個前驅結點;
    3)、包括根結點在內,每個節點可以有多個後繼節點;

    一對多的關係。
    
名詞術語:

    1)、結點的度:該節點擁有的子樹;
    2)、樹的度:樹中所有結點的度的最大值;
    3)、葉結點:度爲0的結點;
    4)、分支結點:度不爲0的結點;
    5)、層:根結點在第一層,其餘結點若在第i層,則其孩子結點在第i+1層;
    6)、樹的深度:結點所處的最大層數;
    7)、樹林(森林):m >= 0 棵不相交的子樹組成的樹的集合;
    8)、樹的有序性:若結點的相對位置不能隨意改變,有序樹,否則,無序樹;
    
二叉樹: 

定義:結點 + 結點的關係構成的集合。

    要麼是一棵空樹,要麼是一棵包含根結點,以及兩顆不相交的,分別稱爲左子樹,右子樹的二叉樹。
    
    
基本特徵:

    要麼是空樹,要麼只有根結點,要麼有一個左子樹,右子樹空,要麼一棵右子樹,左子樹空,要麼兩個非空左右子樹。


2、完全二叉樹與滿二叉樹的基本概念,二叉樹的基本性質及應用

滿二叉樹:要麼沒有,要麼有兩個孩子節點,且度爲0的節點都在最後一層。FULL 
完全二叉樹:爲了順序存儲的方便,最下面兩層可以度爲0,並且最後一層必須從左至右排列。
            如果排除最後一層,就是一棵滿二叉樹。

性質:
    1)、n個結點的非空二叉樹有n-1個分支;每個結點除了根結點外,都只有一條到直接前驅的分支,故分支總數就是n-1;
    2)、非空二叉樹i層最多有2^(i-1)個結點;
    3)、深度爲h的非空二叉樹最多有 2^h -1 個結點;
    4)、n0 = n2 + 1;  n = n1 + n2 + n0; B = n-1; B = n1 + 2n2; 
    5)、具有n個結點的非空完全二叉樹的深度h = [log2 n] + 1;  []取整
    6)、完全二叉樹的編號問題,從上到下,從左到有進行編號,則:
        ①、若i = 1,則i號結點爲根結點;
            若i > 1,則i號結點的雙親結點的編號爲[i/2];
        ②、若2i > n,則編號爲i的結點沒有左子樹;
            若2i <= n,則編號爲i的結點的左孩子編號爲2i;
        ③、若2i+1 > n,則編號爲i的結點沒有右子樹;
            若2i+1 <= n,則編號爲i的結點右孩子編號爲2i+1;
    

3、二叉樹的順序存儲結構與二叉鏈表存儲結構的基本原理

順序存儲結構
    1)、完全二叉樹的順序存儲結構
        按照編號依次存儲到一維數組[0..2^n-2]中,編號與數組下標一一對應
    2)、一般二叉樹的順序存儲結構
        構造不存在的虛結點,使其成爲一棵完全二叉樹,在用一維數組[0..2^n-2]存儲即可
        
二叉樹的鏈式存儲(二叉鏈表)
    鏈節點  lchild data rchild  data爲數據域,lchild爲左子樹指針,rchild爲右子樹指針
    
    typedef struct node{
        int data;
        struct node *lchild, *rchild;
    }BTNode, *BTree;
    
4、二叉樹的前序遍歷,中序遍歷,後序遍歷,按層遍歷,重點是二叉樹按二叉鏈表爲存儲結構的各種遍歷算法(包括非遞歸算法)的設計與應用

概念:按照一定的原則(順序)對二叉樹中的結點進行訪問(且僅訪問一次),得到一個二叉樹所有結點做成的序列,這個過程叫做二叉樹的遍歷

前序遍歷:
    原則:若二叉樹非空,訪問根節點;
          以前序遍歷原則遍歷根結點的左子樹;
          以前序遍歷原則遍歷根結點的右子樹;
          
    遞歸算法:
    
    void PreOrder(BTree t)
    {
        if(t != NULL)
        {
            visit(t);
            PreOrder(t->lchild);
            preOrder(t->rchild);
        }
    }
    
中序遍歷:
    原則:若被遍歷的二叉樹非空;
          以中序遍歷原則遍歷根結點的左子樹;
          訪問根結點;
          以中序遍歷原則遍歷根結點的右子樹;
          
    遞歸算法:
    
    void InOrder(BTree t)
    {
        if(t != NULL)
        {
            InOrder(t->lchild);
            visit(t);
            InOrder(t->rchild);
        }
    }
    
後序遍歷:
    原則:若被遍歷的二叉樹非空;
          以後序遍歷原則遍歷根結點的左子樹;
          以後序遍歷原則遍歷根結點的右子樹;
          訪問根結點;
          
    遞歸算法:
    
    void PostOrder(BTree t)
    {
        if(t != NULL)
        {
            PostOrder(t->lchild);
            PostOrder(t->rchild);
            visit(t);
        }
    }
    
按層次遍歷:
    
非遞歸算法的設計:
以中序遍歷爲例:

STACK[0..M-1] 保存遍歷過程中結點的地址;
top指針,棧頂指針,初始-1;
p 遍歷過程中指向結點的指針,初始指向根結點

描述:
1)、若p指向結點非空,則將p進棧,然後p指向左子樹根結點;
2)、若p指向爲空,則將棧頂元素退棧賦值給p,訪問該結點,然後將p指向右子樹的根;
3)、重複上述過程,直到p爲空,棧爲空。

算法:

void InOrder(BTree t)
{
    BTree Stack[M];
    int top = -1;
    BTree p = t;
    
    do
    {
        while(p != NULL)
        {
            Stack[++top] = p;
            p = p->lchild;
        }
        p = Stack[top--];
        visit(p);
        p = p->rchild;
    }while(p != NULL || top != -1)
}

4、二叉排序樹的基本概念,建立(插入),查找以及平均查找長度ASL的計算

基本概念:

定義:二叉排序樹或者是空樹,或者具有下列性質:
      若根結點左子樹不爲空,則左子樹上所有結點的值都小於根結點的值;
      若根結點右子樹不爲空,則右子樹上所有結點的值都大於或者等於根結點的值。
      

建立(插入)逐點插入:

    設K具有n個元素,沒取一個元素,按照下述原則進行插入:

    若二叉樹爲空,則將該元素作爲根結點;
    若不爲空,則與根結點進行比較,若小於根結點的值,則插入左子樹,若大於根結點,則插入右子樹,插入子樹的時候也遵循這一原則

    void InsertBST(BTree *t, int item)
    {
        BTree p, q;
        p = (BTree)malloc(sizeof(BTNode));

        p->data = item;
        p->lchild = NULL;
        p->rchild = NULL;
        
        if (*t == NULL)
            *t = p;
        else
        {
            q = *t;
            while(1)
            {
                if(item < q->data)
                {
                    if(q->lchild == NULL)
                    {
                        q->lchild = p;
                        break;
                    }else
                    {
                        q = q->lchild;
                    }
                }
                else
                {
                    if(q->rchild == NULL)
                    {
                        q->rchild = p;
                        break;
                    }
                    else
                    {
                        q = q->rchild;
                    }
                }
            }
        }
    }

查找 

過程:
    1)、若二叉樹爲空,則查找失敗,結束;
    2)、若二叉樹非空,將要查找的值與根結點的值進行比較,如果相等,則返回根結點的鏈地址,查找成功,結束;
    3)、若要查找的值小於根結點的值,則到根結點的左子樹中繼續上述查找;
    4)、若要查找的值大於根結點的值,則到根結點的右子樹中繼續上述查找;
    5)、知道查找成功或失敗。
    
    
    BTree SortSearch(BTree t, int data)
    {
        BTree p = t;
        while (p != NULL)
        {
            if (p->data == data)
                return p;
            else if (p->data > data)
                p = p->lchild;
            else
                p = p->rchild;
        }
        return  NULL;
    }
    
平均查找長度ASL

與二叉樹的形態有關;
平均查找長度ASL:確定一個元素在樹中的位置所需要進行比較次數的期望值
內路徑長度:從根結點到某節點所經過的分支數目叫做該結點的路徑,內路徑是所有結點的路徑之和 IPL Internal Path Length
外路徑長度:將二叉樹的葉結點進行補充,用方塊表示,得到的所有外部結點的路徑之和爲外路徑長度 EPL External Path Length 
            如果二叉樹有n個結點,則補充之後有n+1個外部結點
            EPL = IPL + 2n 
            
            比較次數是結點路徑 + 1
            ASL = (IPL + n)/n 
            查找不成功時,比較次數就是外路徑長度
            ASL = (EPL)/n = (IPL + 2n)/n 
            最後,成功與不成功的統一ASL
            (IPL + n + EPL)/(n + n + 1) = (2IPL + 3n) / (2n+1)
            
            最佳二叉排序樹,內路徑最小 O(log2N)
            最壞情況下,與順序相同 (n+1)/2,相當於一棵單支二叉樹

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