4.1~4.3樹和二叉樹

4.1什麼是樹&二叉樹

該樹的每個結點至多隻有兩顆子樹

特殊的二叉樹

1.滿二叉樹

2.完全二叉樹

注:判斷二叉樹是否爲完全二叉樹https://blog.csdn.net/lin1094201572/article/details/86083106

4.2二叉樹的存儲

1.順序存儲結構

2.鏈式存儲機構

4.3.1二叉樹的遍歷

根節點的訪問順序是先還是中還是後決定先,中,後序訪問

1.先序遍歷(PreOrder):

void preOrder(BinaryTree T){
    if(T!=NULL){
		visit(T);
		preOrder(T->lchild);
		preOrder(T->rchild);
	}
}

2.中序遍歷(InOrder)

遞歸算法:

void inOrder(BinaryTree T){
    if(T!=NULL){
        inOrder(T->lchild);
        visit(T);
        inOrder(T->rchild);
    }
}

非遞歸算法:

1.利用棧

void inOrder_no_recursion(BinaryTree T){
    initStack(S);BinaryTree p=T;
    while(p||!isEmpty(S)){
        if(p){
        	Put(S,p);
        	p=p->lchild;
        }else{
            Pop(S,p);
            p=p->rchild;
        }
    }
}

3.後序遍歷(PostOrder)

void postOrder(BinaryTree T){
    if(T!=NULL){
        postOrder(T->lchild);
        postOrder(T-rchild);
        visit(T);
    }
}

已知(先或後)+中序可唯一確定一棵二叉樹。

時間複雜度分析和空間複雜度

1.三種遍歷都訪問每個結點故遍歷時間複雜度爲O(n)

2.遞歸所需最多的棧個數由二叉樹的深度h決定,最壞情況爲全爲度爲1的單支結點深度爲n則空間複雜度爲O(n).

4.層次遍歷(LevelOrder)

A
B
C
E
F

1.利用隊列

1)隊列中首先加入根結點, 隊中A

2)隊列出隊得得隊首元素,訪問出隊元素

3)將出隊元素的左右子結點加入隊列,

循環2)3)

隊中:A–null–BC–CEF–EF–F--null

void levelOrder(BinaryTree T){
    initQueue(Q);
    BinaryTree p=T;EnQueue(S,p);
    while(p){
        DeQueue(S,p);visit(p);
        if(p->lchild!=NULL) EnQueue(S,p->lchild);
        if(p->rchild!=NULL) EnQueue(S,p->rchild);
    }
}

4.3.2 線索二叉樹

將鏈式存儲的二叉樹的空指針利用,一個結點添加兩個個標籤域。分別爲ltag,rtag.

將空白指針指向前驅或後繼,左空指向前驅,有空指向後繼,稱爲線索

前驅,後繼由當前線索數的順序(先,中,後序)決定。

將二叉樹以某種次序線索化後得到線索二叉樹

ltag爲0指向左兒子結點,爲1指向該前驅。

rtag爲0指向右兒子結點,爲1指向該後繼。

該線索二叉樹結構體如下:

typedef struct struct_ThreadNode{
    ElemType elem;
    struct struct_ThreadNode *lchild,*rchild;
    int ltag,rtag;
}ThreadNode ,*ThreadTree;

Demo of the algorithm of InOrder-ThreadTree :

void in_Thread(ThreadTree &p,ThreadTree &pre){//p,pre需修改結點故引用,引用爲c++中添加特性
    if(p!=NULL){
        //遞歸線索化左子樹
        //將當前結點的左右若空線索化,左空前驅(中序前驅爲pre),右空後繼(中序,後繼爲根結點p)。
        pre = p;//線索化後前驅結點變換爲當前根結點。
        //遞歸線索化右子樹
    }   
}

The code of sort InOrder-ThreadTree by InOrder:

void inorder_ThreadTree(ThreadTree T){
	for(ThradNode *p=FirstNode(T);p!=NULL;p=NextNode(T)) visit(p);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章