樹形結構

線性結構、樹型結構、圖狀結構和純集合結構做爲數據的四種結構,樹型結構是一類重要的非線性結構。node

以二叉樹爲例瞭解一下樹型結構的基本性質及用法:ios

二叉樹數組

每一個節點至多有兩棵子樹,左子樹和右子樹,次序不可顛倒post

非空二叉樹的第n層至多有2^(n-1)個結點spa

深度爲h的二叉樹至多有2^h - 1 個結點.net

完美二叉樹(滿二叉樹)的結點個數爲2^h - 1 code

徹底二叉樹的第h層的結點都集中在左邊blog

完美二叉樹自己也是徹底二叉樹遞歸

對於徹底二叉樹,設一個結點(非根結點)編號爲 i ,則其父親結點編號爲 i / 2 , 其左子結點編號爲 2 * i , 右子結點編號爲 2 * i + 1ci

葉子結點的個數等於度爲2的結點個數 + 1 

同理:

m叉樹的葉子結點個數n0,有一個兒子的結點個數n1,有兩個兒子的結點個數n2,有三個兒子的結點個數n3……有m個兒子的結點個nm之間存在什麼關係?

n0 + n1 + n2 + …… nm - 1 = 0 * n0 + 1 * n1 + 2 * n2 + 3 * n3 + 4 * n4 + …… m * nm

因此: n0 - 1 = n2 + 2 * n3 + 3 * n4 + …… + (m-1) * nm 

存儲結構:

  順序存儲:

  徹底二叉樹能夠用數組來實現,通常二叉樹若是採用這種存儲方式,空間代價較高

  數組實現二叉樹的順序存儲代碼:

  

typedef struct Node {
    int data ;
    int lchild , rchild ;
    int father ;
}Node ;

Node btree[1000] ;

  

  鏈式存儲:

typedef struct Node {
    int data ;
    struct Node * lchild ;
    struct Node * rchild ;
}Node ;

Node *new_Node() {
    Node * newnode = new Node ;
    newnode->data = 0 ;
    newnode->lchild = NULL ;
    newnode->rchild = NULL ;
    return newnode ;
}

二叉樹的遍歷:

遍歷即二叉樹的全部結點訪問一遍,根據訪問根結點的順序分爲:先序遍歷、中序遍歷和後續遍歷:

先序遍歷: 根結點 -> 左子樹 -> 右子樹

中序遍歷: 左子樹 -> 根結點 -> 右子樹

後序遍歷: 左子樹 -> 右子樹 -> 根結點

先序遍歷:1 -> 2 -> 4 -> 5 -> 7 -> 3 -> 6 -> 8

中序遍歷:4 -> 2 -> 5 -> 7 -> 1 -> 3 -> 8 -> 6 

後序遍歷:4 -> 7 -> 5 -> 2 -> 8 -> 6 -> 3 -> 1

遍歷的遞歸實現:

#include<iostream>
#include<stdio.h>

using namespace std ;

typedef struct Node {
    int data ;
    struct Node * lchild ;
    struct Node * rchild ;
}Node ;

Node *new_Node() {
    Node * newnode = new Node ;
    newnode->data = 0 ;
    newnode->lchild = NULL ;
    newnode->rchild = NULL ;
    return newnode ;
}

typedef Node *node ;

Node *CreatebinTree()    {
    int a ;
    Node *T ;
    cin >> a ;
    if(a == 0)
        return NULL ;
    else    {
        T = new_Node() ;
        T->data = a ;
        T->lchild = CreatebinTree() ;
        T->rchild = CreatebinTree() ;
    }
    return T ;
}

void preorder(node T)    {
    if(T)    {
        if(T->data != 0)
            cout << T->data << " " ;
        preorder(T->lchild) ;
        preorder(T->rchild) ; 
    }
}

int main()    {
    freopen("in.txt","r",stdin) ;
    Node * root = CreatebinTree() ;
    preorder(root) ;
    return 0 ;
}

//  輸入數據:
//  1 2 4 0 0 5 0 7 0 0 3 0 6 8 0 0 0

 

非遞歸遍歷:

#include<iostream>
#include<stdio.h>
using namespace std ;

typedef struct Node    {
    int data ;
    struct Node *lchild ;
    struct Node *rchild ;
}Node;

Node *New_Node()    {
    Node *T = new Node ;
    T->data = 0 ;
    T->lchild = NULL ;
    T->rchild = NULL ;
    return T ;
}

Node *CreateBinTree()    {
    Node *T ;
    int a ;
    cin >> a ;
    if(a == 0)    
        return NULL ;
    else    {
        T = New_Node()    ;
        T->data = a ;
        T->lchild = CreateBinTree() ;
        T->rchild = CreateBinTree() ;
    }
    return T ;
}

/*void preorder(Node *T)    {
    if(T != NULL)    {
        cout << T->data << " " ;
        preorder(T->lchild) ;
        preorder(T->rchild) ;
    }
}
*/

typedef struct stackk    {
    Node *node[1000] ;
    int top ;
}stackk;

void push(stackk &s , Node *n)    {
    if(s.top == 999)
        printf("stack is full\n") ;
    else    {
        s.node[++(s.top)] = n ;
    }
}

Node* pop(stackk &s)    {
    if(s.top == -1)    
        return NULL ;
    else    
        return s.node[(s.top)--] ; 
}

void preorder(Node *root)    {
    stackk s ;
    s.top = -1 ;
    if(root == NULL)    
        printf("tree is empty\n") ;
    else    {
        while(root != NULL || s.top != -1)    {
            while(root != NULL)    {
                printf("%d ",root->data) ;
                push(s,root) ;
                root = root->lchild ;
            }
            root = pop(s) ;
            root = root->rchild ;
        }
    }
}


int main()    {
    freopen("in.txt","r",stdin) ;
    Node *root ;
    root = CreateBinTree() ;
    preorder(root) ;
    return 0 ;
}

 

 非遞歸實現後續遍歷:

#include<iostream>
#include<stdio.h>
using namespace std ;

typedef struct Node    {
    int data ;
    struct Node *lchild ;
    struct Node *rchild ;
}Node;

Node *New_Node()    {
    Node *T = new Node ;
    T->data = 0 ;
    T->lchild = NULL ;
    T->rchild = NULL ;
    return T ;
}

Node *CreateBinTree()    {
    Node *T ;
    int a ;
    cin >> a ;
    if(a == 0)    
        return NULL ;
    else    {
        T = New_Node()    ;
        T->data = a ;
        T->lchild = CreateBinTree() ;
        T->rchild = CreateBinTree() ;
    }
    return T ;
}

/*void preorder(Node *T)    {
    if(T != NULL)    {
        cout << T->data << " " ;
        preorder(T->lchild) ;
        preorder(T->rchild) ;
    }
}
*/

typedef struct stackk    {
    Node *node[1000] ;
    int top ;
    int flag[1000] ;
}stackk;

void push(stackk &s , Node *n)    {
    if(s.top == 999)
        printf("stack is full\n") ;
    else    {
        s.node[++(s.top)] = n ;
    }
}

Node* pop(stackk &s)    {
    if(s.top == -1)    
        return NULL ;
    else    
        return s.node[(s.top)--] ; 
}
void postorder(Node *root)    {
    stackk s ;
    s.top = -1 ;
    if(root == NULL)    
        printf("tree is empty\n") ;
    else    {
        while(root != NULL || s.top != -1)    {
            while(root != NULL)    {
                push(s,root) ;
                s.flag[s.top] = 0 ;
                root = root->lchild ;
            }
            if(s.flag[s.top] == 0)    {
                s.flag[s.top] = 1 ;
                root = s.node[s.top] ;
                root = root->rchild ;
            }
            else    {
                while(s.flag[s.top] == 1)    {
                    root = pop(s) ;
                    printf("%d ",root->data) ;
                    root = NULL ;
                }
                
            }
        }
    }
}


int main()    {
    freopen("in.txt","r",stdin) ;
    Node *root ;
    root = CreateBinTree() ;
    preorder(root) ;
    return 0 ;
}

 層次遍歷:

#include<iostream>
#include<stdio.h>
using namespace std ;

typedef struct Node    {
    int data ;
    struct Node *lchild ;
    struct Node *rchild ;
}Node;

Node *New_Node()    {
    Node *T = new Node ;
    T->data = 0 ;
    T->lchild = NULL ;
    T->rchild = NULL ;
    return T ;
}

Node *CreateBinTree()    {
    Node *T ;
    int a ;
    cin >> a ;
    if(a == 0)    
        return NULL ;
    else    {
        T = New_Node()    ;
        T->data = a ;
        T->lchild = CreateBinTree() ;
        T->rchild = CreateBinTree() ;
    }
    return T ;
}

/*void preorder(Node *T)    {
    if(T != NULL)    {
        cout << T->data << " " ;
        preorder(T->lchild) ;
        preorder(T->rchild) ;
    }
}
*/

typedef struct queuee    {
    Node *node[1000] ;
    int front ;
    int rear ;
}queuee;

void push(queuee &q , Node *T)    {
    if(q.rear == 999)
        printf("queue is full\n") ;
    else    
        q.node[(q.rear)++] = T ;
}

Node *pop(queuee &q)    {
    if(q.front == q.rear)
        return NULL ;
    else
        return q.node[q.front++] ;
}

void ccbl(Node *root)    {
    queuee q ;
    q.front = q.rear = 0 ;
    if(root != NULL)
        push(q,root) ;
    while(q.front < q.rear)    {
        Node *T = pop(q) ;
        cout << T->data << " " ;
        if(T->lchild != NULL)    
            push(q,T->lchild) ;
        if(T->rchild != NULL)    
            push(q,T->rchild) ;
    }
}


int main()    {
    freopen("in.txt","r",stdin) ;
    Node *root ;
    root = CreateBinTree() ;
    ccbl(root) ;
    return 0 ;
}

 二叉樹查找:

#include<iostream>
#include<stdio.h>
using namespace std ;

typedef struct Node    {
    int data ;
    struct Node *lchild ;
    struct Node *rchild ;
}Node;

Node *New_Node()    {
    Node *T = new Node ;
    T->data = 0 ;
    T->lchild = NULL ;
    T->rchild = NULL ;
    return T ;
}

Node *CreateBinTree()    {
    Node *T ;
    int a ;
    cin >> a ;
    if(a == 0)    
        return NULL ;
    else    {
        T = New_Node()    ;
        T->data = a ;
        T->lchild = CreateBinTree() ;
        T->rchild = CreateBinTree() ;
    }
    return T ;
}

/*void preorder(Node *T)    {
    if(T != NULL)    {
        cout << T->data << " " ;
        preorder(T->lchild) ;
        preorder(T->rchild) ;
    }
}
*/

Node *search(Node *T , int x)    {
    if(T == NULL)
        return NULL ;
    if(T->data == x)    {
        return T ;
    }
    if(search(T->lchild,x) != NULL)
        return search(T->lchild,x) ;
    else
        return search(T->rchild,x) ;
}


int main()    {
    freopen("in.txt","r",stdin) ;
    Node *root ;
    root = CreateBinTree() ;
    root = search(root,5) ;
    cout << root->rchild->data << endl ;
    return 0 ;
}

 遞歸太強大啦

相關文章
相關標籤/搜索