首页 > 其他分享 >树的基本操作

树的基本操作

时间:2023-03-21 23:11:18浏览次数:35  
标签:Node lchild return val res 基本操作 rchild

增删改查

#include<iostream>
#include<vector>
#include<cstdlib>
#include<ctime>
using namespace std;

struct Node {
    int data;
    Node *lchild, *rchild, *parent;

    Node(int val = 0, Node *p = NULL): data(val), lchild(NULL), rchild(NULL), parent(p) {}

    Node *insert(int val) {
        if (val < data) {
            if (lchild) return lchild->insert(val);
            else return lchild = new Node(val, this);
        } else if (val > data) {
            if (rchild) return rchild->insert(val);
            else return rchild = new Node(val, this);
        } else return this;
    }

    Node *search(int val) {
        if (data == val) return this;
        if (lchild) if(Node *res = lchild->search(val)) return res;
        if (rchild) if(Node *res = rchild->search(val)) return res;
        return NULL;
    }

    void inorder() {
        if (lchild) lchild->inorder();
        printf("%d ", data);
        if (rchild) rchild->inorder();
        if (!parent) cout << endl;
    }

    Node *next() {
        Node *res;
        //后继结点在右子树里
        if (rchild) {
            res = rchild;
            while (res->lchild) res = res->lchild;
            return res;
        }
        //后继结点在祖先里
        res = parent;
        Node *now = this;
        while (res) {
            if (res->lchild == now) return res;
            now = res;
            res = res->parent;
        }
        return NULL;
    }

    Node *prev() {
        Node *res;
        //前驱结点在左子树里
        if (lchild) {
            res = lchild;
            while (res->rchild) res = res->rchild;
            return res;
        }
        //前驱结点在祖先里
        res = parent;
        Node *now = this;
        while (res) {
            if (res->rchild == now) return res;
            now = res;
            res = res->parent;
        }
        return NULL;
    }
};

Node *erase(Node *root, int val) {
    Node *node = root->search(val);
    if (node == NULL) return root;
    if (node->rchild) {
        Node *succ = node->next();
        node->data = succ->data;
        //删除后继结点
        Node *p = succ->parent;
        (p->lchild == succ ? p->lchild : p->rchild) = succ->rchild;
        if (succ->rchild) succ->rchild->parent = p;
        delete succ;
    } else {
        if (node == root) {
            //删除根结点
            if (node->lchild) root = node->lchild, root->parent = NULL;
            else root = NULL;
            delete node;
        } else {
            //删除当前结点
            Node *p = node->parent;
            (p->lchild == node ? p->lchild : p->rchild) = node->lchild;
            if (node->lchild) node->lchild->parent = p;
            delete node;
        }
    }
    return root;
}

//转换为静态存储
void Trans(Node *node, vector<int> &tree, int ind = 1) {
    if (ind >= tree.size()) return;
    if (node) {
        tree[ind] = node->data;
        Trans(node->lchild, tree, ind * 2);
        Trans(node->rchild, tree, ind * 2 + 1);
    } else return;
}

void Print(int val, int n) {
    for (int i = 0; i < n - 1; i++) cout << " ";
    if (val == -1) cout << "  ";
    else cout << val;
    for (int i = 0; i < n - 1; i++) cout << " ";
}

//显示树结构
void Display(Node *node) {
    vector<int> tree(1 << 5); //最多5层
    for (auto &i : tree) i = -1;
    Trans(node, tree);
    int level = 1, n = tree.size();
    for (int i = 1; i < tree.size(); i++) {
        if (i == 1 << level) {
            level++; n /= 2; cout << endl;
        }
        Print(tree[i], n);
    }
    cout << endl;
}

int main() {
    Node *root = new Node(50);
    srand(time(0));
    for (int i = 0; i < 10; i++) {
        root->insert(10 + rand() % 90);
    }
    cout << "inorder: ";
    root->inorder();
    Display(root);

    int num, ret;
    cout << "erase: ";
    while (ret = ~scanf("%d", &num)) { //输入EOF(Ctrl+D)结束程序
        if (ret == -1) { getchar(); continue; }
        root = erase(root, num);
        if (root == NULL) break;
        cout << "inorder: ";
        root->inorder();
        Display(root);
        cout << "erase: ";
    }
    return 0;
}

树的删除展示


前中序构建&层次遍历

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

struct Node {
    int data;
    Node *lchild, *rchild, *parent;

    Node(int val = 0, Node *p = NULL): data(val), lchild(NULL), rchild(NULL), parent(p) {}

    Node *insert(int val) {
        if (val < data) {
            if (lchild) return lchild->insert(val);
            else return lchild = new Node(val, this);
        } else if (val > data) {
            if (rchild) return rchild->insert(val);
            else return rchild = new Node(val, this);
        } else return this;
    }

    Node *search(int val) {
        if (data == val) return this;
        if (lchild) if(Node *res = lchild->search(val)) return res;
        if (rchild) if(Node *res = rchild->search(val)) return res;
        return NULL;
    }

    void inorder() {
        if (lchild) lchild->inorder();
        printf("%d ", data);
        if (rchild) rchild->inorder();
        if (!parent) cout << endl;
    }

    void level_trav() {
        queue<Node *> que;
        que.push(this);
        while (!que.empty()) {
            Node *node = que.front();
            que.pop();
            printf("%d ", node->data);
            if (node->lchild) que.push(node->lchild);
            if (node->rchild) que.push(node->rchild);
        }
        cout << endl;
    }
};

Node *Create_pre(int *pre, int *in, int n, Node *p = NULL) {
    if (n == 0) return NULL;
    Node *root = new Node(pre[0], p);
    int n1 = 0;
    while (n1 < n) {
        if (in[n1] == pre[0]) break;
        else n1++;
    }
    root->lchild = Create_pre(pre + 1, in, n1, root);
    root->rchild = Create_pre(pre + n1 + 1, in + n1 + 1, n - n1 - 1, root);
    return root;
}

Node *Create_post(int *in, int *post, int n, Node *p = NULL) {
    if (n == 0) return NULL;
    Node *root = new Node(post[n - 1], p);
    int n1 = 0;
    while (n1 < n) {
        if (in[n1] == post[n - 1]) break;
        else n1++;
    }
    root->lchild = Create_post(in, post, n1, root);
    root->rchild = Create_post(in + n1 + 1, post + n1, n - n1 - 1, root);
    return root;
}

int main() {
    string str;
    getline(cin, str);
    vector<int> pre;
    for (int i = 0; ; i++) {
        pre.push_back(stoi(&str[i]));
        i = str.find(' ', i);
        if (i == -1) break;
    }
    int n = pre.size();
    int in[n], post[n];
    for (int i = 0; i < n; i++) cin >> in[i];
    for (int i = 0; i < n; i++) cin >> post[i];
    Node *root1 = Create_pre(&pre[0], in, n);
    Node *root2 = Create_post(in, post, n);
    root1->level_trav();
    root2->level_trav();
    return 0;
}
# 输入:
1 2 4 3 5
2 4 1 5 3
4 2 5 3 1
# 输出:
1 2 3 4 5
1 2 3 4 5

标签:Node,lchild,return,val,res,基本操作,rchild
From: https://www.cnblogs.com/Kelvin-Wu/p/17241999.html

相关文章

  • [数据结构]循环链表及其基本操作
    /**@Author:*@data:2019-12-0319:47:29*@LastModifiedby:*@LastModifiedtime:2019-12-0320:00:06*/#include<iostream>#include<cstdio>usingnamesp......
  • [数据结构]循环表及其基本操作
    /**@Author:*@data:2019-12-0213:46:20*@LastModifiedby:*@LastModifiedtime:2019-12-0320:18:30*/#include<iostream>#include<cstdio>usingnamespac......
  • [数据结构]双向循环链表及其基本操作
    #include<iostream>#include<cstdio>usingnamespacestd;typedefintElem;typedefintStatus;typedefstructDulList{/*data*/Elemdata;structDulList*pri......
  • [数据结构]双向链表及其基本操作
    #include<iostream>#include<cstdio>usingnamespacestd;typedefintElem;typedefintStatus;typedefstructDulList//我猜是doubolelist...{/*data*/Elemd......
  • [数据结构]单链表及其基本操作
    /**@Author:*@data:2019-12-0214:49:03*@LastModifiedby:*@LastModifiedtime:2019-12-0215:54:49*/#include<iostream>#include<cstdio>usingnamespa......
  • redis 操作集合基本操作
    Redis的Set是String类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据。集合对象的编码可以是intset或者hashtable。Redis中集合是通过哈......
  • Crystal Report 基本操作 (三)
    1.插入图操作: InsertChart->ChartExpert->Selecttype,Data->Confirm注意创建Group,图只能放在Footer位置,不能放在detail位置。  2.饼图样式修改:Chart......
  • 表的基本操作
    进入MySQL*看数据库showdatabases;创建数据库Blog:createdatabaseblog使用数据库useblog在数据库中查看表showtables创建数据库createtableessay修改表......
  • [java-Spring]-Spring Boot入门基本操作
    目录一、SpringBoot入门1、SpringBoot简介2、微服务3、环境准备1、MAVEN设置;2、IDEA设置4、SpringBootHelloWorld1、创建一个maven工程;(jar)2、导入springboot相关的......
  • 【WinForm】 自学笔记一:项目创建以及基本操作
    这两年C#客户端开发比较火,有很多WinForm以及WPF的开发需求。为了跟上时代发展的步伐,开始学习相关的知识。笔记内容以个人实际学习情况为主,记录基本情况,可能不够详细......