1. 程式人生 > >資料結構-二叉樹的遍歷

資料結構-二叉樹的遍歷

二叉樹是每個結點最多有兩個子樹的樹結構。通常子樹被稱作“左子樹”(left subtree)和“右子樹”(right subtree)。二叉樹常被用於實現二叉查詢樹和二叉堆。 二叉樹的每個結點至多隻有二棵子樹(不存在度大於2的結點),二叉樹的子樹有左右之分,次序不能顛倒。二叉樹的第i層至多有2^{i-1}個結點;深度為k的二叉樹至多有2^k-1個結點;對任何一棵二叉樹T,如果其終端結點數為n_0,度為2的結點數為n_2,則n_0=n_2+1。

一棵深度為k,且有2^k-1個節點的二叉樹,稱為滿二叉樹。這種樹的特點是每一層上的節點數都是最大節點數。而在一棵二叉樹中,除最後一層外,若其餘層都是滿的,並且最後一層或者是滿的,或者是在右邊缺少連續若干節點,則此二叉樹為完全二叉樹。具有n個節點的完全二叉樹的深度為log2n+1。深度為k的完全二叉樹,至少有2^(k-1)個節點,至多有2^k-1個節點。

-摘自百科

二叉樹的其它的特性我就不多做介紹了,詳情請大家自行搜尋!

此處著重介紹二叉樹的遍歷,二叉樹的遍歷存在四種方式:

先序遍歷:訪問根節點->遍歷左子樹->遍歷右子樹

中序遍歷:遍歷左子樹->訪問根節點->遍歷右子樹

後序遍歷:遍歷左子樹->遍歷右子樹->訪問根節點

如上圖所示的二叉樹

採用先序遍歷的結果為:ABDHIEJCFKG

採用中序遍歷的結果為:HDIBEJAFKCG

採用後序遍歷的結果為:HIDJEBKFGCA

下面首先通過C語言簡單實現二叉樹的初始化建立和先序遍歷的方式輸出每個節點所在樹的層次:

//
// Created by Administrator on 2018/6/5.
//

#include "stdio.h"
#include "stdlib.h"

/**
 * 建立一棵二叉樹並輸出每個節點所在二叉樹的層次
 * 輸入方式:ABDH##I##E#J##CF#K##G##
 */

#define ElementType char
typedef struct {
    ElementType data;
    struct BitTreeNode *lchild, *rchild;
} BitTreeNode, *BitTree;

/**
 * 建立一棵二叉樹:先序遍歷的方式
 * @param tree
 * @return 二叉樹
 */
BitTree createBitTree(BitTree tree) {
    char c;
    scanf("%c", &c);
    if ('#' == c) {
        return 0;
    } else {
        tree = (BitTree) malloc(sizeof(BitTreeNode));
        tree->data = c;
        tree->lchild = createBitTree(tree->lchild);
        tree->rchild = createBitTree(tree->rchild);
    }
    return tree;
}

/**
 * 列印結果
 * @param data 節點元素
 * @param level 所在層數
 */
void printLevel(char data, int level) {
    printf("%c 在第 %d 層\n", data, level);
}


/**
 * 先序遍歷
 * @param tree
 * @param level
 */
void preOrder(BitTree tree, int level) {
    if (tree) {
        printLevel(tree->data, level);
        preOrder(tree->lchild, level + 1);
        preOrder(tree->rchild, level + 1);
    }
}


int main() {
    int level = 1;
    BitTree tree;
    tree = createBitTree(tree);
    printf("先序遍歷結果:\n");
    preOrder(tree, level);
    return 0;
}

接下來實現二叉樹的三種遍歷方式:

//
// Created by Administrator on 2018/6/5.
//
/**
 * 二叉樹的三種遍歷方式:先序遍歷、中序遍歷、後序遍歷
 */
#include "stdio.h"
#include "stdlib.h"

#define ElementType char
typedef struct {
    ElementType data;
    struct BitTreeNode *lchild, *rchild;
} BitTreeNode, *BitTree;

/**
 * 建立一棵二叉樹:通過先序遍歷的方式建立
 * @param tree
 * @return 二叉樹
 */
BitTree createBitTree(BitTree tree) {
    char c;
    scanf("%c", &c);
    if ('#' == c) {
        return 0;
    } else {
        tree = (BitTree) malloc(sizeof(BitTreeNode));
        tree->data = c;
        tree->lchild = createBitTree(tree->lchild);
        tree->rchild = createBitTree(tree->rchild);
    }
    return tree;
}

/**
 * 訪問節點
 * @param data 節點資料
 */
void visit(char data) {
    printf("%c", data);
}

/**
 * 先序遍歷
 * @param tree
 */
void preOrder(BitTree tree) {
    if (tree) {
        visit(tree->data);
        preOrder(tree->lchild);
        preOrder(tree->rchild);
    }
}

/**
 * 中序遍歷
 * @param tree
 */
void inOrder(BitTree tree) {
    if (tree) {
        inOrder(tree->lchild);
        visit(tree->data);
        inOrder(tree->rchild);
    }
}

/**
 * 後序遍歷
 * @param tree
 */
void postOrder(BitTree tree) {
    if (tree) {
        postOrder(tree->lchild);
        postOrder(tree->rchild);
        visit(tree->data);
    }
}

int main() {
    BitTree tree;
    tree = createBitTree(tree);
    printf("先序遍歷結果:");
    preOrder(tree);
    printf("\n");
    printf("中序遍歷結果:");
    inOrder(tree);
    printf("\n");
    printf("後序遍歷結果:");
    postOrder(tree);
    printf("\n");
    return 0;
}

好了,以上就是二叉樹的集中遍歷方式,如果有小夥伴有疑問的可以關注公眾號,我們在群裡面一起探討交流哦!