樹和二叉樹1——鏈式二叉樹基礎

本文代碼基於【數據結構】【嚴蔚敏】【清華大學】
包含了大多數二叉樹的基本操做ios

1.準備部分的代碼:
用c++其實就是用了個max()函數c++

#include <stdio.h>
#include <stdlib.h>//malloc和exit函數所需頭文件 
#include <iostream>
using namespace std;
#define MaxSize 100
typedef char ElemType;

固然也能夠改爲C,記得加上一個自定義max函數web

#include <stdio.h>
#include <stdlib.h>//malloc和exit函數所需頭文件 
#define MaxSize 100
typedef char ElemType;
int max(int a,int b)
{
	return a>b?a:b;
 }

2.構造二叉樹結點
包括數據域和左右孩子指針算法

typedef struct BiTNode {
    ElemType    data;
    struct BiTNode	*lchild, *rchild; 	// 左右孩子指針
} BiTNode, *BiTree;

3.先序輸入二叉樹中結點的值
一些必要的註解:
①TheBinaryTree爲結構體指針,指向結構體
BiTree TheBinaryTree=BiTNode *TheBinaryTree
②T爲TheBinaryTree的引用,是結構體指針
BiTree &T= BiTNode *&T
③BT是結構指針TheBinaryTree的指針,BT指向結構體指針
BiTNode **BT=BiTree *BT
全部有兩種 CreateBiTree寫法:數據結構

void CreateBiTree(BiTNode* &T)//BiTree &T== BiTNode* &T
{
    // 按先序次序輸入二叉樹中結點的值
    // 構造二叉鏈表表示的二叉樹T。
    ElemType	ch;

    static	int	i = 0;
    char	pch[] = "ABC$$DE$G$$F$$$";				    // 欲產生的 先序序列。圖6.8(b)
    ch = pch[i++];

    if(ch == '$') 										// 空樹
        T = NULL;
    else {
        T = (BiTree)malloc(sizeof(BiTNode));
        if(!T)											// 檢測是否申請結點成功
            exit(-1);
        T->data = ch; 									// 生成根結點
        CreateBiTree(T->lchild); 						// 構造左子樹
        CreateBiTree(T->rchild); 						// 構造右子樹
    }
}
void CreateBiTree_Pointer(BiTNode **BT)//BiTree *BT BT此時爲指針的指針, BiTNode* *BT==BiTree *BT 
{
    // 按先序次序輸入二叉樹中結點的值
    // 構造二叉鏈表表示的二叉樹BT。
    ElemType	ch;
    static	int	i = 0;
    char	pch[] = "AB D C ";								// 欲產生的二叉樹 先序序列
    ch = pch[i++];
    //scanf("%c",&ch);
    if(ch == ' ') 												// 空樹
        *BT = NULL;
    else {
        *BT = (BiTree)malloc(sizeof(BiTNode));
        if(!*BT)												// 檢測是否申請結點成功
            exit(-1);
        (*BT)->data = ch; 										// 生成根結點
        CreateBiTree_Pointer(&(*BT)->lchild); 						// 構造左子樹
        CreateBiTree_Pointer(&(*BT)->rchild); 						// 構造右子樹
    }
}

4.三種遍歷(遞歸)svg

// 中序遍歷
void InOrderTraversal(BiTree BT)
{
    if(BT) {
        InOrderTraversal(BT->lchild);
        printf("%c ", BT->data);
        InOrderTraversal(BT->rchild);
    }
}

//先序遍歷
void PreOrderTraversal(BiTree BT)
{
    if(BT) {
        printf("%c ", BT->data);
        PreOrderTraversal(BT->lchild);
        PreOrderTraversal(BT->rchild);
    }
}

// 後序遍歷
void PostOrderTraversal(BiTree BT)
{
    if(BT) {
        PostOrderTraversal(BT->lchild);
        PostOrderTraversal(BT->rchild);
        printf("%c ", BT->data);
    }
}

5.中序遍歷非遞歸遍歷算法(關於其餘遍歷算法以後還會寫文章提到)函數

// 中序遍歷非遞歸遍歷算法
//利用壓棧 
void InOrderTraversal_NoRecursion(BiTNode *T)
{
    BiTNode	*Stack[MaxSize];//BiTree Stack[MaxSize]
    int	top = -1;

    while(T || (top != -1)) {
        while(T) {												// 一直向左並將沿途結點壓入堆棧
            Stack[++top] = T;
            T = T->lchild;
        }

        if(top != -1) {
            T = Stack[top--]; 						// 結點彈出堆棧
            printf("%c ", T->data); 				//(訪問)打印結點
            T = T->rchild; 							// 轉向右子樹
        }
    }
}

6.輸出葉子結點值spa

// 輸出二叉樹中的葉子結點。
void PreOrderPrintLeaves(BiTree BT)
{
    if(BT) {
        if(BT->lchild == NULL && BT->rchild == NULL)
            printf("%c ", BT->data);
        PreOrderPrintLeaves(BT->lchild);
        PreOrderPrintLeaves(BT->rchild);
    }
}

7.輸出深度指針

// 求二叉樹的深度
int Binary_tree_Deepness(BiTNode *T)
{
    if(T == NULL)
        return 0;
    else
        if(T->lchild == NULL && T->rchild == NULL)
            return 1;
        else
            return 1 + max(Binary_tree_Deepness(T->lchild), Binary_tree_Deepness(T->rchild));
}
//表示形式2
int Binary_tree_Deepness_Post(BiTNode *T)
{
    int h1, h2;
    if(T == NULL)
        return 0;
    h1 = Binary_tree_Deepness_Post(T->lchild);
    h2 = Binary_tree_Deepness_Post(T->rchild);
    if(T->lchild == NULL && T->rchild == NULL)
        return 1;
    else
        return 1 + max(h1, h2);
}

8.求度爲 2 的結點數code

//求二叉樹的度爲 2 的結點數算法
int BT_CountDegree2(BiTNode *T)
{
    int n1, n2; 
    if (T == NULL)
        return 0;
    else {
        n1 = BT_CountDegree2(T->lchild);
        n2 = BT_CountDegree2(T->rchild);
        if (T->lchild != NULL && T->rchild != NULL)
            return 1 + n1 + n2;
        else
            return n1 + n2;
    }
}

9.構造和銷燬
PS:完整代碼中沒用到構造和銷燬,Init某種意義上無關緊要,destroy最好仍是加一下

Status InitBiTree(BiTree &T)
{
    // 操做結果: 構造空二叉樹T
    T = NULL;
    return OK;
}


void DestroyBiTree(BiTree &T)
{
    // 初始條件: 二叉樹T存在。操做結果: 銷燬二叉樹T
    if(T) {	// 非空樹
        if(T->lchild) 							// 有左孩子
            DestroyBiTree(T->lchild); 			// 銷燬左孩子子樹
        if(T->rchild) 							// 有右孩子
            DestroyBiTree(T->rchild); 			// 銷燬右孩子子樹
        free(T); 								// 釋放根結點
        T = NULL; 								// 空指針賦0
    }
}

10.主函數

int	main()
{
    BiTree	TheBinaryTree;//BiTNode *TheBinaryTree

    printf("\n創建二叉樹,請輸入結點值系列:\n");
    CreateBiTree(TheBinaryTree);//TheBinaryTree爲結構體指針 

    printf("\n先序遍歷序列:\n");
    PreOrderTraversal(TheBinaryTree);

    printf("\n中序遍歷序列:\n");
    InOrderTraversal(TheBinaryTree);
    printf("\n中序遍歷序列 - 中序遍歷非遞歸算法:\n");
    InOrderTraversal_NoRecursion(TheBinaryTree);

    printf("\n後序遍歷序列:\n");
    PostOrderTraversal(TheBinaryTree);

    printf("\n二叉樹的深度爲:\n");
    //printf("%d",Binary_tree_Deepness_Post(TheBinaryTree));
    printf("%d", Binary_tree_Deepness(TheBinaryTree));

    printf("\n葉子結點爲:\n");
    PreOrderPrintLeaves(TheBinaryTree);
    
    printf("\n度爲2的結點個數爲:\n");
    printf("%d", BT_CountDegree2(TheBinaryTree));

    return 1;
}

便於複製完整源代碼以下:

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

#define MaxSize 100
typedef char ElemType;

typedef struct BiTNode {
    ElemType    data;
    struct BiTNode	*lchild, *rchild; 				// 左右孩子指針
} BiTNode, *BiTree;

//TheBinaryTree爲結構體指針,指向結構體
//BiTree TheBinaryTree==BiTNode *TheBinaryTree
//BiTree &T== BiTNode* &T T爲TheBinaryTree的引用,是結構體指針
//BiTNode **BT==BiTree *BT BT是結構指針TheBinaryTree的指針, BT指向結構體指針 
void CreateBiTree(BiTNode* &T)//BiTree &T== BiTNode* &T
{
    // 按先序次序輸入二叉樹中結點的值
    // 構造二叉鏈表表示的二叉樹T。
    ElemType	ch;

    static	int	i = 0;
    char	pch[] = "ABC$$DE$G$$F$$$";				// 欲產生的 先序序列。圖6.8(b)
    ch = pch[i++];

    if(ch == '$') 										// 空樹
        T = NULL;
    else {
        T = (BiTree)malloc(sizeof(BiTNode));
        if(!T)											// 檢測是否申請結點成功
            exit(-1);
        T->data = ch; 									// 生成根結點
        CreateBiTree(T->lchild); 						// 構造左子樹
        CreateBiTree(T->rchild); 						// 構造右子樹
    }
}

void CreateBiTree_Pointer(BiTNode **BT)//BiTree *BT BT此時爲指針的指針, BiTNode* *BT==BiTree *BT 
{
    // 按先序次序輸入二叉樹中結點的值
    // 構造二叉鏈表表示的二叉樹BT。
    ElemType	ch;
    static	int	i = 0;
    char	pch[] = "AB D C ";								// 欲產生的二叉樹 先序序列
    ch = pch[i++];
    //scanf("%c",&ch);
    if(ch == ' ') 												// 空樹
        *BT = NULL;
    else {
        *BT = (BiTree)malloc(sizeof(BiTNode));
        if(!*BT)												// 檢測是否申請結點成功
            exit(-1);
        (*BT)->data = ch; 										// 生成根結點
        CreateBiTree_Pointer(&(*BT)->lchild); 						// 構造左子樹
        CreateBiTree_Pointer(&(*BT)->rchild); 						// 構造右子樹
    }
}

// 中序遍歷
void InOrderTraversal(BiTree BT)
{
    if(BT) {
        InOrderTraversal(BT->lchild);
        printf("%c ", BT->data);
        InOrderTraversal(BT->rchild);
    }
}

//先序遍歷
void PreOrderTraversal(BiTree BT)
{
    if(BT) {
        printf("%c ", BT->data);
        PreOrderTraversal(BT->lchild);
        PreOrderTraversal(BT->rchild);
    }
}

// 後序遍歷
void PostOrderTraversal(BiTree BT)
{
    if(BT) {
        PostOrderTraversal(BT->lchild);
        PostOrderTraversal(BT->rchild);
        printf("%c ", BT->data);
    }
}

// 中序遍歷非遞歸遍歷算法
//利用壓棧 
void InOrderTraversal_NoRecursion(BiTNode *T)
{
    BiTNode	*Stack[MaxSize];//BiTree Stack[MaxSize]
    int	top = -1;

    while(T || (top != -1)) {
        while(T) {												// 一直向左並將沿途結點壓入堆棧
            Stack[++top] = T;
            T = T->lchild;
        }

        if(top != -1) {
            T = Stack[top--]; 						// 結點彈出堆棧
            printf("%c ", T->data); 				//(訪問)打印結點
            T = T->rchild; 							// 轉向右子樹
        }
    }
}

// 輸出二叉樹中的葉子結點。
void PreOrderPrintLeaves(BiTree BT)
{
    if(BT) {
        if(BT->lchild == NULL && BT->rchild == NULL)
            printf("%c ", BT->data);
        PreOrderPrintLeaves(BT->lchild);
        PreOrderPrintLeaves(BT->rchild);
    }
}

// 求二叉樹的深度
int Binary_tree_Deepness(BiTNode *T)
{
    if(T == NULL)
        return 0;
    else
        if(T->lchild == NULL && T->rchild == NULL)
            return 1;
        else
            return 1 + max(Binary_tree_Deepness(T->lchild), Binary_tree_Deepness(T->rchild));
}

int Binary_tree_Deepness_Post(BiTNode *T)
{
    int h1, h2;

    if(T == NULL)
        return 0;

    h1 = Binary_tree_Deepness_Post(T->lchild);
    h2 = Binary_tree_Deepness_Post(T->rchild);
    if(T->lchild == NULL && T->rchild == NULL)
        return 1;
    else
        return 1 + max(h1, h2);
}

//求二叉樹的度爲 2 的結點數算法
int BT_CountDegree2(BiTNode *T)
{
    int n1, n2; 
    if (T == NULL)
        return 0;
    else {
        n1 = BT_CountDegree2(T->lchild);
        n2 = BT_CountDegree2(T->rchild);
        if (T->lchild != NULL && T->rchild != NULL)
            return 1 + n1 + n2;
        else
            return n1 + n2;
    }
}

int	main()
{
    BiTree	TheBinaryTree;//BiTNode *TheBinaryTree

    printf("\n創建二叉樹,請輸入結點值系列:\n");
    CreateBiTree(TheBinaryTree);//TheBinaryTree爲結構體指針 

    printf("\n先序遍歷序列:\n");
    PreOrderTraversal(TheBinaryTree);

    printf("\n中序遍歷序列:\n");
    InOrderTraversal(TheBinaryTree);
    printf("\n中序遍歷序列 - 中序遍歷非遞歸算法:\n");
    InOrderTraversal_NoRecursion(TheBinaryTree);

    printf("\n後序遍歷序列:\n");
    PostOrderTraversal(TheBinaryTree);

    printf("\n二叉樹的深度爲:\n");
    //printf("%d",Binary_tree_Deepness_Post(TheBinaryTree));
    printf("%d", Binary_tree_Deepness(TheBinaryTree));

    printf("\n葉子結點爲:\n");
    PreOrderPrintLeaves(TheBinaryTree);
    
    printf("\n度爲2的結點個數爲:\n");
    printf("%d", BT_CountDegree2(TheBinaryTree));

    return 1;
}
相關文章
相關標籤/搜索