使用C++实现二叉树及其常用接口(创建、遍历、搜索、插入、还原)

主要实现以下关于二叉树的操作:

1、二叉树结构体

2、创建树的新节点

3、二叉树的搜索

4、二叉树中新节点的插入

5、二叉树的创建

6、二叉树的前序、中序、后序遍历

7、二叉树的层序遍历

8、使用前序遍历序列和中序遍历序列还原一棵二叉树

9、使用后序遍历序列和中序遍历序列还原一棵二叉树

具体代码如下:

#include <iostream>
#include <queue>
using namespace std;

// 结点结构体
struct node {
    
    
    int data;       // 数据域
    int layer;      // 层次
    node* lchild;   // 指针域
    node* rchild;   // 指针域
};

// 创建新节点
node* newNode(int v) {
    
    
    node* Node = new node;
    Node->data = v;
    Node->lchild = Node->rchild = nullptr;
    return Node;
}

// 二叉树的搜索
void search(node* root, int& x, int& newData) {
    
    
    if (root == nullptr) return;
    if (root->data == x) root->data = newData;
    search(root->lchild, x, newData);
    search(root->rchild, x, newData);
}

// 二叉树结点的插入
void insert(node*& root, int x) {
    
    
    if (root == nullptr) {
    
    
        root = newNode(x);
        return;
    }

    if (x < root->data) {
    
     // 可自定义插入规则
        insert(root->lchild, x);
    } else {
    
    
        insert(root->rchild, x);
    }
}

// 二叉树的创建
node* Create(int data[], int n) {
    
    
    node* root = nullptr;
    for (int i = 0; i < n; ++i) {
    
    
        insert(root, data[i]);
    }
    return root;
}

// 前序遍历
void preOrder(node* root) {
    
    
    if (root == nullptr) return;
    cout << root->data << endl;
    preOrder(root->lchild);
    preOrder(root->rchild);
}

// 中序遍历
void inOrder(node* root) {
    
    
    if (root == nullptr) return;
    inOrder(root->lchild);
    cout << root->data << endl;
    inOrder(root->rchild);
}

// 后序遍历
void postOrder(node* root) {
    
    
    if (root == nullptr) return;
    postOrder(root->lchild);
    postOrder(root->rchild);
    cout << root->data << endl;
}

// 二叉树的层序遍历
void LayerOrder(node* root) {
    
    
    queue<node*> q;
    root->layer = 1;
    q.emplace(root);
    while (!q.empty()) {
    
    
        node* cur = q.front();
        q.pop();
        cout << cur->data << endl;
        if (cur->lchild != nullptr) {
    
       // 左节点入队
            cur->lchild->layer = cur->layer + 1;
            q.emplace(cur->lchild);
        }
        if (cur->rchild != nullptr) {
    
       // 右节点入队
            cur->rchild->layer = cur->layer + 1;
            q.emplace(cur->rchild);
        }
    }
}

vector<int> pre_order;   // 先序序列
vector<int> in_order;    // 中序序列
vector<int> post_order;  // 中序序列

// 根据先序遍历序列和中序遍历序列还原一棵二叉树
node* CreateTreeByPreAndInOrder(int preL, int preR, int inL, int inR) {
    
    
    if (preL > preR) return nullptr;

    // 先序序列的首节点就是根节点
    node* root = newNode(pre_order[preL]);

    int k, left_num;
    // 找到根节点在中序序列的位置
    for (k = inL; k <= inR; ++k) {
    
    
        if (in_order[k] == pre_order[preL]) {
    
    
            left_num = k - inL; // 左子树节点个数
            break;
        }
    }
    
    // 先序区间:  左子树 [preL + 1, preL + left_num], 右子树 [preL + left_num + 1, preR]
    // 中序区间: 左子树 [inL, k - 1], 右子树 [k + 1, inR]

    // 左节点 = 左子树的根节点
    root->lchild = CreateTreeByPreAndInOrder(preL + 1, preL + left_num, inL, k - 1);
    // 右节点 = 右子树的根节点
    root->rchild = CreateTreeByPreAndInOrder(preL + left_num + 1, preR, k + 1, inR);
}

// 根据后序遍历序列和中序遍历序列还原一棵二叉树
node* CreateTreeByPostAndInOrder(int postL, int postR, int inL, int inR) {
    
    
    if (postL > postR) return nullptr;

    // 后序序列的尾节点就是根节点
    node* root = newNode(post_order[postR]);

    int k, left_num;
    // 找到根节点在中序序列的位置
    for (k = inL; k <= inR; ++k) {
    
    
        if (in_order[k] == post_order[postR]) {
    
    
            left_num = k - inL; // 左子树节点个数
            break;
        }
    }

    // 后序区间:  左子树 [postL, postL + left_num - 1], 右子树 [postL + left_num, postR - 1]
    // 中序区间: 左子树 [inL, k - 1], 右子树 [k + 1, inR]

    // 左节点 = 左子树的根节点
    root->lchild = CreateTreeByPreAndInOrder(postL, postL + left_num - 1, inL, k - 1);
    // 右节点 = 右子树的根节点
    root->rchild = CreateTreeByPreAndInOrder(postL + left_num, postR - 1, k + 1, inR);
}

int main() {
    
    
    
    return 0;
}

在二叉树的操作中,处理基本的数据结构了解之外,还需要理解递归这一方法,因为对于树的操作,使用递归是很常见的方式。

谢谢阅读。

猜你喜欢

转载自blog.csdn.net/weixin_43869898/article/details/109962535