面试前你需要掌握的二叉树、二叉排序树的创建和四种遍历方式

二叉树的创建

普通二叉树的创建,这里以完全二叉树的创建为例,所谓完全二叉树,也就是从根节点开始,一层一层的往后接入节点,首先我们创建一个结构体,用来存储二叉树的节点,每一个节点除了存一个data,还有一个左孩子和一个右孩子。

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

struct BiTree{
    int data;
    BiTree *left;
    BiTree *right;
};

void createBiTree(BiTree* &T) {
    int data;
    scanf("%d", &data);
    if(data == -1)
        return;
    T = new BiTree();
    T->data = data;
    createBiTree(T->left);
    createBiTree(T->right);
}

int main() {
        BiTree *T;
        createBiTree(T);
        return 0;
}

如果我们想要创建一个下图所示的树,需要输入
3 6 -1 -1 7 -1 -1
因为首先3是根节点,然后是3这个节点的左孩子左孩子,输入了6,然后是6这个节点的左孩子,没有输入-1,然后是6这个节点的右孩子,也没有,输入-1,然后是3这个节点的右孩子,输入7,然后是7这个节点的左孩子,没有是-1,右孩子也没有,也是-1。
在这里插入图片描述

二叉排序树的创建

二叉排序树的创建核心是进行节点的插入,每个需要插入的节点都是从根节点开始比较,把小的节点放到左边,大的节点放到右边,其中中序遍历即是从小到大输出该树的所有节点,对于一颗完全二叉排序树,其查找速度是O(logn),但是不得不说一下极限,也就是当我们创建二叉排序树的时候,所有的孩子都在一侧,那么该树就成了线性结构,其查找的时间复杂度是O(n),为了解决这一问题,有一个叫做平衡二叉树的东西,比较有名气的一个算法是红黑树实现二叉树的自平衡,红黑树在JDK1.8,HashMap中就有用到,详细介绍可以看下HashMap底层

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

struct BiSortTree{
    int data;
    BiSortTree *left;
    BiSortTree *right;
};

void insertChild(BiSortTree* T,int data) {
        if (data < T->data) {
                if(T->left == NULL) {
                        T->left = new BiSortTree();
                        T->left->data = data;
                        //printf("left***if\n");
                } else {
                        //printf("left***else");
                        insertChild(T->left,data);
                }
        }
        else {
                if(T->right == NULL) {
                        T->right = new BiSortTree();
                        T->right->data = data;
                        //printf("right***if\n");
                } else {
                        //printf("right***else\n");
                        insertChild(T->right,data);
                }
        }
}


void createBiSortTree(BiSortTree* T) {
        int data;
        scanf("%d",&data);
        T->data = data;
        while(1) {
                scanf("%d", &data);
                if (data == -1)
                        break;
                insertChild(T,data);
        }
}

int main() {
        BiSortTree *T = new BiSortTree();
        createBiSortTree(T);
        return 0;
}

如果我们输入如下图的6个数字,那么,他会自动构造出如下图的一颗二叉排序树。
在这里插入图片描述

树的先序、中序、后续遍历

先序遍历是“根左右”,中序遍历是“左根右”,后序遍历是“左右根”。
二叉树的这三种遍历通过递归实现,对于先序遍历,以一个只有三个节点的满二叉树来说,第一次输出了根节点,然后遍历其左孩子,并把左孩子输出,然后遍历根节点的右孩子,并把右孩子输出。中序遍历和后序遍历跟先序遍历都差不多的思想,值得一提的是,对于二叉排序树,其中序遍历就是其从小到大(或从大到小)输出,因为中序遍历是左根右,而二叉排序树刚好就是左孩子都比根小,而根都比右孩子小。

void pre(BiTree* T)
{
    if(T!=NULL)
    {
        printf("%d ",T->data);
        pre(T->left);
        pre(T->right);
    }
}

void mid(BiTree* T)
{
    if(T!=NULL)
    {
        mid(T->left);
        printf("%d ",T->data);
        mid(T->right);
    }
}

void post(BiTree* T)
{
    if(T!=NULL)
    {
        post(T->left);
        post(T->right);
        printf("%d ",T->data);
    }
}

树的层次遍历

层次遍历是通过队列这个数据结构实现的,队列是先进先出,这里还是以一个只有三个节点的满二叉树进行描述,第一次是把根节点入队列,然后把根节点弹出,并输出根节点,然后判断该节点的左孩子是否为空,如果非空,那就入队列,然后判断右孩子是否为空,非空就入队列,这样也就是从左到右依次入队列的,所以,输出的时候,也是从左到右依次输出,即达到层次遍历的目的

void level(BiTree* T) {
        queue<BiTree*> que;
        if (T != NULL) {
                que.push(T);
        }
        BiTree* p;
        while(!que.empty()) {
                p = que.front();
                que.pop();
                printf("%d ",p->data);
                if(p->left != NULL)
                        que.push(p->left);
                if(p->right != NULL)
                        que.push(p->right);
        }
}
发布了464 篇原创文章 · 获赞 317 · 访问量 8万+

猜你喜欢

转载自blog.csdn.net/HeZhiYing_/article/details/105315570