美文网首页
树的简单操作

树的简单操作

作者: 浪淘沙008 | 来源:发表于2020-05-11 16:02 被阅读0次
#include <iostream>
#include <stack>
#include <queue>
#include <map>
#include <vector>

using namespace std;


typedef struct Node {
    int data;
    Node * left;
    Node * right;
    Node (int data) {
        this->data = data;
    }
}Node;

class MyTree{
public:
    Node * root;
    Node * insertNode(Node * root, int data);
    void preOrderRead(Node * root);
    void inOrderRead(Node *root); 
    void postOrderRead(Node *root);
    void cengOrderRead(Node *root);
    void shenduOrderRead(Node *root);
    int getMaxDepth(Node *root);
    int getMinDepth(Node *root);
    int getMaxWidth(Node *root);
    void deleteNode(int val, Node * root);
};

Node * MyTree::insertNode(Node * root, int data) {
    if (root == NULL) {
        this->root = new Node(data);
        return this->root;
    }
    if (data <= root->data) {
        if (root->left != NULL) {
            insertNode(root->left, data);
        }else {
            root->left = new Node(data);
        }
    }
    if (data > root->data) {
        if (root->right != NULL) {
            insertNode(root->right, data);
        }else {
            root->right = new Node(data);
        }
    }
    return this->root;
}

void MyTree::preOrderRead(Node *root) {
    if (root == NULL) return;
    
    cout << root->data << endl;
    preOrderRead(root->left);
    preOrderRead(root->right);
    
}
void MyTree::inOrderRead(Node *root) {
    if (root == NULL) return;
    inOrderRead(root->left);
    cout << root->data << endl;
    inOrderRead(root->right);
}


void MyTree::postOrderRead(Node *root) {
    if (root == NULL) return;
    postOrderRead(root->left);
    postOrderRead(root->right);
    cout << root->data << endl;
}

// 层序遍历(广度优先遍历)
// 整体思路: 按照层级先将根节点存入队列中,再通过当前节点查找该节点的子节点并存入队列中,层层递进地实现层序遍历
void MyTree::cengOrderRead(Node *root) {
    queue<Node *>queue;
    vector<Node *>list;
    queue.push(root);
    
    while (queue.size() > 0) {
        Node *node = queue.front(); //获取队列的第一个节点
        queue.pop();    //将第一个节点pop出
        list.push_back(node);   // 将获取的节点直接存储入数组中
        
        vector<Node *>childrens;
        // 将队列第一个元素的子元素存入子数组
        if (node->left != NULL) {
            childrens.push_back(node->left);
        }
        if (node->right != NULL) {
            childrens.push_back(node->right);
        }
        // 将子节点按照顺序存入队列
        for (Node *childNode : childrens) {
            queue.push(childNode);
        }
    }
    for (int i = 0; i < list.size(); i++) {
        cout << list[i]->data << endl;
    }
}

// 深度遍历(深度优先遍历)
// 思路:该遍历方式通过栈来存储右、左节点,每次循环的时候只将栈顶的节点抛出输出并将其右、左子节点加入栈顶
void MyTree::shenduOrderRead(Node *root) {
    vector<Node *>list;
    if (root == NULL) return;
    
    stack<Node *>stack;
    stack.push(root);
    while (stack.size() != 0) {
        Node * node = stack.top();  // 获取栈顶的节点
        stack.pop();    //将栈顶的节点推出
        list.push_back(node);
        if (node->right != NULL) {
            stack.push(node->right);
        }
        if (node->left != NULL) {
            stack.push(node->left);
        }
    }
    for (int i = 0; i < list.size(); i++) {
        cout << list[i]->data << endl;
    }
}
// 获取最大深度
int MyTree::getMaxDepth(Node *root)
{
    if (root == NULL) return 0;
    int left = getMaxDepth(root->left);
    int right = getMaxDepth(root->right);
    return 1 + max(left, right);
}
// 获取最小深度
int MyTree::getMinDepth(Node *root)
{
    if (root == NULL) return 0;
    int left = getMaxDepth(root->left);
    int right = getMaxDepth(root->right);
    return 1 + min(left, right);
}

// 获取树的最大宽度
int MyTree::getMaxWidth(Node *root)
{
    if (root==NULL) return 0;
    queue<Node *>queue;
    int maxWidth = 1;
    queue.push(root);
    while (true) {
        int len = (int)queue.size();
        if (len == 0) break;
        while (len > 0) {
            Node * t = queue.front();
            queue.pop();
            len--;
            if (t->left != NULL) {
                queue.push(t->left);
            }
            if (t->right != NULL) {
                queue.push(t->right);
            }
        }
        maxWidth = max(maxWidth, (int)queue.size());
    }
    return maxWidth;
}

// 删除树中值为data的节点
void MyTree::deleteNode(int data, Node * root) {

    Node * p = root;    // p指向要删除的节点,初始化指向根节点
    Node * pp = NULL;   // pp记录的是p的父节点
    while (p != NULL && p->data != data) {
        pp = p;
        if (data > p->data) {
            p = p->right;
        }else {
            p = p->left;
        }
    }
    if (p == NULL) return;  // 未找到要删除的值
    // 要删除的节点有两个子节点
    if (p->left != NULL && p->right != NULL) { // 查找右子树中最小节点
        Node *minP = p->right;
        Node *minPP = p;    // minPP表示minP的父节点
        while (minP->left != NULL) {
            minPP = minP;
            minP = minP->left;
        }
        p->data = minP->data;   // 将minP的数据替换到p中
        p = minP;   // 下面就变成了删除minP了
        pp = minPP;
    }
    
    // 删除节点是叶子节点或者仅有一个子节点
    Node * child;   // p的子节点
    if (p->left != NULL) {
        child = p->left;
    }else if(p->right != NULL) {
        child = p->right;
    }else  {
        child = NULL;
    }
    
    if (pp == NULL) {
        root = child;   // 删除的是根节点
    }else if(pp->left == p) {
        pp->left = child;   // 删除的是左孩子
    }else {
        pp->right = child;  // 删除的是右孩子
    }

}




int main(int argc, char *argv[]){
  
    MyTree tree = MyTree();
    tree.insertNode(tree.root, 5);
    tree.insertNode(tree.root, 7);
    tree.insertNode(tree.root, 6);
    tree.insertNode(tree.root, 8);
    tree.insertNode(tree.root, 3);
    tree.insertNode(tree.root, 1);
    tree.insertNode(tree.root, 4);
    tree.insertNode(tree.root, 2);
    
    tree.preOrderRead(tree.root);
    cout << "中序遍历---" << endl;
    tree.inOrderRead(tree.root);
    cout << "---" << endl;
    tree.postOrderRead(tree.root);
    cout << "---" << endl;
    tree.cengOrderRead(tree.root);
    cout << "---" << endl;
    tree.shenduOrderRead(tree.root);
    cout << "---" << endl;
    cout << "树的最大深度:" << tree.getMaxDepth(tree.root) << endl;
    cout << "---" << endl;
    cout << "树的最小深度:" << tree.getMinDepth(tree.root) << endl;
    cout << "---" << endl;
    cout << "树的最大宽度:" << tree.getMaxWidth(tree.root) << endl;
    cout << "---" << endl;
    tree.deleteNode(1, tree.root);
    cout << "删除后的中序遍历:" << endl;
    tree.inOrderRead(tree.root);
    
    
    return 0;
}

相关文章

  • 树的简单操作

  • 二叉树

    一些关于二叉树的简单操作 创建节点 简单操作

  • 节点树简单操作

    1. 内容描述:对表格内容进行增、删、改、查。 2. 主要方法:利用节点树,JS-DOM中的库函数,并且会画节点树...

  • 平衡二叉树的基本操作

    平衡二叉树定义及操作原理 C++简单实现 涉及练习题目:平衡二叉树的基本操作

  • 拿下红黑树

    红黑树 红黑树、2-3树的简单定义: 实现红黑树的基本结构以及添加操作(维护定义,左旋、右旋、颜色反转) 红黑树与...

  • 决策树的建立

    构建一个简单的决策树 先导入库 读取数据 运行结果为: 画图操作 运行结果为: 构建决策树

  • 算法模板(七) 线段树

    线段树单点操作 线段树区间操作

  • 数据结构(三)简单树操作

    数据结构…本系列旨在对基础算法进行记录和学习,为了之后的面试一个弥补~~本系列不是科普文,是为了找工作快速拾遗系列...

  • 算法导论之红黑树&区间树

    实验要求 实验代码 区间树的很多操作是红黑树进行一点简单的修改,区间树中加入的max域 注意在插入和旋转的时候进行...

  • 68_二叉树的比较与相加

    关键词:二叉树的克隆操作、二叉树比较操作、二叉树的相加操作 0. 二叉树的克隆操作 SharedPointer< ...

网友评论

      本文标题:树的简单操作

      本文链接:https://www.haomeiwen.com/subject/rmwunhtx.html