Skip to content

11039: 【原1039】顺序存储二叉树

题目

题目描述

author: 原OJ链接:https://acm.sjtu.edu.cn/OnlineJudge-old/problem/1039

Description

用顺序存储实现二叉树。读入一棵二叉树,输出后序遍历的结果。

Input Format

第一行,一个整数 n,表示这棵树有 n 个节点。这 n 个节点编号为 1 到 n。

接下来 n 行,描述每个节点的左右儿子情况。每行包含三个整数 x y z,表示编号为 x 的节点的左儿子编号为 y,右儿子编号为 z。若 y=-1 或 z=-1,表示 x 没有左子树或右子树。

编号为 1 的节点为树的根节点。

Output Format

第一行:输出 n 个整数,第 i 个整数为编号 i 的节点在顺序存储的数组中的下标。输出的数之间用一个空格隔开。

第二行:输出这个树的后序遍历的结果,输出的数之间用空格隔开。

Hint

N<=30000,树的高度保证不超过15。

输入中,除了根节点外,每个节点的描述总在它的父节点的描述出现之后给出。

Sample Input

5
1 2 4
4 5 -1
5 -1 -1
2 -1 3
3 -1 -1

Sample Output

1 2 5 3 6
3 2 5 4 1

FineArtz's solution

/* 顺序存储二叉树 */
#include <iostream>
using namespace std;

class Node{
public:
    int l = 0, r = 0, pos = 0, ind = 0;
};

Node a[100005];
int n, root = 0, b[100005], c[100005];

void encode(int root){
    int q[200005], front = 0, rear = 0, cnt = 0, r = 0;
    q[rear++]= root;
    r = rear;
    a[root].pos = ++cnt;
    while (front != r){
        int now = q[front++];
        ++cnt;
        if (now != -1){
            if (a[now].l != -1){
                q[rear++] = b[a[now].l];
                a[b[a[now].l]].pos = cnt;
                r = rear;
            }
            else
                q[rear++] = -1;
        }
        else{
            q[rear++] = -1;
        }
        ++cnt;
        if (now != -1){
            if (a[now].r != -1){
                q[rear++] = b[a[now].r];
                a[b[a[now].r]].pos = cnt;
                r = rear;
            }
            else
                q[rear++] = -1;
        }
        else{
            q[rear++] = -1;
        }
    }
    for (int i = 1; i <= n; ++i){
        c[a[i].ind] = a[i].pos;
    }
    for (int i = 1; i <= n; ++i)
        cout << c[i] << ' ';
    cout << endl;
}

void sufTrans(int x){
    if (a[x].l != -1)
        sufTrans(b[a[x].l]);
    if (a[x].r != -1)
        sufTrans(b[a[x].r]);
    cout << a[x].ind << ' ';
}

int main(){
    cin >> n;
    for (int i = 1; i <= n; ++i){
        cin >> a[i].ind >> a[i].l >> a[i].r;
        if (a[i].ind == 1)
            root = i;
    }
    for (int i = 1; i <= n; ++i){
        b[a[i].ind] = i;
    }
    encode(root);
    sufTrans(root);
    cout << endl;
    return 0;
}

ligongzzz's solution

#include "iostream"
#include "cstdio"
#include "cmath"
#include "cstring"
using namespace std;


int fuck_data[30009] = { 0 };
template <class T>
class mQueue {
    class node {
    public:
        T data;
        node* next = nullptr;
    };
    node* head = nullptr,
        * rear = nullptr;
    size_t _size = 0;

public:
    //构造函数
    mQueue() {
        head = new node;
        rear = head;
    }
    //判断是否为空
    bool empty() {
        return head->next == nullptr;
    }
    //增加
    void push(const T& val) {
        rear->next = new node;
        rear = rear->next;
        rear->data = val;
        ++_size;
    }
    //删除
    void pop() {
        //安全措施
        if (head->next == nullptr)
            return;
        auto temp = head->next;
        delete head;
        head = temp;
        --_size;
    }
    //大小
    size_t size() {
        return _size;
    }
    //最前
    T& front() {
        //安全措施
        return head->next->data;
    }
    //最后
    T& back() {
        //安全措施
        return rear->data;
    }
};

template <class T>
class mVector {
    T** vector_data = nullptr;
    unsigned int size = 0;
    unsigned int capacity = 0;

public:
    //构造函数
    mVector() = default;
    mVector(unsigned int _size) :size(_size) {
        capacity = _size * 2;
        vector_data = new T * [capacity] {nullptr};
    }
    mVector(unsigned int _size, const T& val) :size(_size) {
        capacity = _size * 2;
        vector_data = new T * [capacity] {nullptr};
        for (unsigned int i = 0; i < _size; ++i)
            vector_data[i] = new T(val);
    }
    mVector(const mVector<T> & _vector) :size(_vector.size), capacity(_vector.capacity) {
        vector_data = new T * [capacity] {nullptr};
        for (int i = 0; i < size; ++i)
            vector_data[i] = new T(*_vector.vector_data[i]);
    }
    //析构函数
    ~mVector() {
        for (unsigned int i = 0; i < size; ++i)
            delete vector_data[i];
        delete[] vector_data;
    }

    //迭代器
    class iterator {
        T** pos = nullptr;
        friend iterator mVector<T>::begin();
        friend iterator mVector<T>::end();
        friend void mVector<T>::erase(const iterator& val);
    public:
        iterator() = default;
        iterator(const iterator& other) {
            pos = other.pos;
        }
        iterator& operator++() {
            ++pos;
            return *this;
        }
        iterator operator++(int) {
            iterator temp(*this);
            ++pos;
            return temp;
        }
        iterator& operator--() {
            --pos;
            return *this;
        }
        iterator operator--(int) {
            iterator temp(*this);
            --pos;
            return temp;
        }
        bool operator==(const iterator& other) const {
            return pos == other.pos;
        }
        bool operator!=(const iterator& other) const {
            return pos != other.pos;
        }
        iterator& operator=(const iterator& other) {
            pos = other.pos;
            return *this;
        }
        T& operator*() const {
            return **pos;
        }
    };

    //增加元素
    void push_back(const T & val) {
        if (size < capacity)
            vector_data[size++] = new T(val);
        else {
            T** temp_data = new T * [(capacity + 1) * 2]{ nullptr };
            for (unsigned int i = 0; i < size; ++i)
                temp_data[i] = vector_data[i];
            temp_data[size++] = new T(val);
            capacity = (capacity + 1) * 2;
            delete[] vector_data;
            vector_data = temp_data;
        }
    }

    //删除末尾
    void pop_back() {
        delete vector_data[size];
        vector_data[size--] = nullptr;
    }

    //清空
    void clear() {
        for (unsigned int i = 0; i < size; ++i) {
            delete vector_data[i];
            vector_data[i] = nullptr;
        }
        size = 0;
    }

    //删除
    void erase(const iterator & val) {
        delete* val.pos;
        for (auto p = val.pos; p != vector_data + size - 1; ++p)
            * p = *(p + 1);
        --size;
        vector_data[size] = nullptr;
    }

    //重载运算符
    T & operator[](const unsigned int& pos) {
        return *vector_data[pos];
    }

    iterator begin() {
        iterator temp;
        temp.pos = vector_data;
        return temp;
    }

    iterator end() {
        iterator temp;
        temp.pos = vector_data + size;
        return temp;
    }

};

//二叉树类
template <class T>
class myBinaryTree {
public:
    class node {
    public:
        T data;
        node* lchild = nullptr, * rchild = nullptr, * parent = nullptr;
    };
    node* root = nullptr;
    node** nodeList = nullptr;
    long long sizeOfTree = 0;

    //创建树
    void createTree(int num) {
        nodeList = new node * [num + 1]{ nullptr };
        sizeOfTree = num;
    }

    void creadNode(int nodeNum, int lchild, int rchild, int data) {
        if (nodeList[nodeNum] == nullptr)
            nodeList[nodeNum] = new node;

        nodeList[nodeNum]->data = data;

        if (lchild != -1) {
            if (nodeList[lchild] == nullptr)
                nodeList[lchild] = new node;
            nodeList[lchild]->parent = nodeList[nodeNum];
            nodeList[nodeNum]->lchild = nodeList[lchild];
        }

        if (rchild != -1) {
            if (nodeList[rchild] == nullptr)
                nodeList[rchild] = new node;
            nodeList[rchild]->parent = nodeList[nodeNum];
            nodeList[nodeNum]->rchild = nodeList[rchild];
        }
    }

    void checkRoot() {
        root = nodeList[1];
        fuck_data[1] = 1;
        get_fuck(1);
    }

    //清空
    void clear() {
        clear(root);
    }

    void clear(node * p) {
        if (p == nullptr)
            return;
        clear(p->lchild);
        clear(p->rchild);
        delete p;
        p = nullptr;
    }

    //构造
    myBinaryTree() {}

    //析构
    ~myBinaryTree() {
        clear(root);
    }

    //判断是否非空
    bool empty() {
        return root == nullptr;
    }

    //判断是否为完全二叉树
    bool isCBT() {
        if (empty())
            return false;
        //层次遍历
        mQueue<node*> treeQueue;
        bool flag = false;
        //先入队
        treeQueue.push(root);

        //反复
        while (!treeQueue.empty()) {
            //先出队一个
            node* temp = treeQueue.front();
            treeQueue.pop();

            //右孩子有左孩子没有
            if (temp->lchild == nullptr && temp->rchild != nullptr)
                return false;

            if (!flag) {
                //左孩子有右孩子没有
                if (temp->lchild != nullptr && temp->rchild == nullptr) {
                    flag = true;
                    //左孩子入队
                    treeQueue.push(temp->lchild);
                }
                //左右孩子都没有
                else if (temp->lchild == nullptr && temp->rchild == nullptr) {
                    flag = true;
                }
                //左右都有孩子
                else {
                    treeQueue.push(temp->lchild);
                    treeQueue.push(temp->rchild);
                }
            }
            else {
                //判断是否为叶子
                if (temp->lchild != nullptr || temp->rchild != nullptr)
                    return false;
            }
        }

        return true;
    }

    //返回大小
    long long size() {
        return sizeOfTree;
    }

    void get_fuck(int pos) {
        if (nodeList[pos]->lchild) {
            fuck_data[nodeList[pos]->lchild->data] = fuck_data[pos] * 2;
            get_fuck(nodeList[pos]->lchild->data);
        }
        if (nodeList[pos]->rchild) {
            fuck_data[nodeList[pos]->rchild->data] = fuck_data[pos] * 2 + 1;
            get_fuck(nodeList[pos]->rchild->data);
        }
    }

    //层次遍历
    mVector<T> levelTraversal() {
        if (sizeOfTree == 0)
            return *new mVector<T>;

        mVector<T> result;
        mQueue<node*> treeQueue;

        //根结点入队
        treeQueue.push(root);

        //层次遍历
        while (!treeQueue.empty()) {
            //出队
            node* temp = treeQueue.front();
            treeQueue.pop();

            //入队
            if (temp->lchild != nullptr)
                treeQueue.push(temp->lchild);
            if (temp->rchild != nullptr)
                treeQueue.push(temp->rchild);

            //写入
            result.push_back(temp->data);
        }

        //返回
        return result;
    }

    //后序遍历
    mVector<T> lostorderTraversal() {
        mVector<T> result;
        lostorderTraversal(root, result);
        return result;
    }

    void lostorderTraversal(node * treeRoot, mVector<T> & result) {
        if (treeRoot->lchild != nullptr)
            lostorderTraversal(treeRoot->lchild, result);
        if (treeRoot->rchild != nullptr)
            lostorderTraversal(treeRoot->rchild, result);
        //显示当前
        result.push_back(treeRoot->data);
    }
};



int main() {
    int num;
    myBinaryTree<int> bTree;
    cin >> num;
    bTree.createTree(num + 1);

    for (int i = 1; i <= num; i++) {
        int code, lchild, rchild;
        scanf("%d %d %d", &code, &lchild, &rchild);
        bTree.creadNode(code, lchild, rchild, code);
        fuck_data[code] = i;
    }

    bTree.checkRoot();
    cout << fuck_data[1];
    for (int i = 2; i <= num; ++i)
        cout << " " << fuck_data[i];
    cout << endl;
    auto ans = bTree.lostorderTraversal();
    for (auto p : ans)
        cout << p << " ";

    return 0;
}

WashSwang's solution

#include <iostream>
using namespace std;
int n,root,postn,seq[30001],post[30001],ls[30001],rs[30001],x,y,z;
void dfs(int x)
{
    if (ls[x]!=-1) {
        seq[ls[x]]=2*seq[x];
        dfs(ls[x]);
    }
    if (rs[x]!=-1){
        seq[rs[x]]=2*seq[x]+1;
        dfs(rs[x]);
    }
    post[++postn]=x;
}
int main() {
    cin>>n;
    for (int i=0;i<n;++i){
        cin>>x>>y>>z;
        if (i==0) root=x;
        ls[x]=y;
        rs[x]=z;
    }
    seq[root]=1;
    dfs(root);
    for (int i=1;i<=n;++i)
        cout<<seq[i]<<" ";
    cout<<endl;
    for (int i=1;i<=n;++i)
        cout<<post[i]<<" ";
    return 0;
}

yyong119's solution

#include <iostream>
using namespace std;
const int MAX_N = 30010;
struct node {
    int lson = -1, rson = -1;
}a[MAX_N];
int num[MAX_N];

void findnum(int node, int nodenum) {

    if (a[node].lson != -1) findnum(a[node].lson, nodenum << 1);
    if (a[node].rson != -1) findnum(a[node].rson, nodenum << 1 | 1);
    num[node] = nodenum;
}

void output(int node) {

    if (a[node].lson != -1) output(a[node].lson);
    if (a[node].rson != -1) output(a[node].rson);
    cout << node << " ";
}
int main() {

    ios::sync_with_stdio(false);
    int n; cin >> n;
    for (int i = 1; i <= n; ++i) {
        int temp, l, r;
        cin >> temp >> l >> r;
        a[temp].lson = l; a[temp].rson = r;
    }
    num[1] = 1;
    findnum(1, 1);
    for (int i = 1; i <= n; ++i) cout << num[i] << " ";
    cout << endl;
    output(1);
    return 0;
}