Vijos数据结构基础C++实验整理(九)——二叉树操作

这篇博客详细介绍了如何实现二叉树的各种遍历方法(前序、中序、后序、层次遍历)以及计算节点数和高度。此外,还探讨了根据前序和中序序列重建二叉树并输出后序序列的算法。内容涵盖了数据结构和算法的基础知识,适用于计算机科学的学习者。
摘要由CSDN通过智能技术生成

实验内容:
(一)创建二叉树类。二叉树的存储结构使用链表。提供操作:前序遍历、中序遍历、后序遍历、层次遍历、计算二叉树结点数目、计算二叉树高度。
第一行为一个数字n (10<=n<=100000),表示有这棵树有n个节点,编号为1~n。
之后n行每行两个数字,第 i 行的两个数字a、b表示编号为 i 的节点的左孩子节点为 a,右孩子节点为 b,-1表示该位置没有节点。
保证数据有效,根节点为1。
第一行,n个数字,表示该树的层次遍历。
第二行,n个数字,第i个数字表示以 i 节点为根的子树的节点数目。
第三行,n个数字,第i个数字表示以 i 节点为根的子树的高度
(二)接收二叉树前序序列和中序序列(各元素各不相同),输出该二叉树的后序序列。
输入有三行:
第一行为数字n。
第二行有n个数字,表示二叉树的前序遍历。
第三行有n个数字,表示二叉树的中序遍历。
输出一行,表示该二叉树的后序遍历序列。

样例:
(一)
输入:
5
2 3
4 5
-1 -1
-1 -1
-1 -1
输出:
1 2 3 4 5
5 3 1 1 1
3 2 1 1 1
(二)
输入:
5
1 2 4 5 3
4 2 5 1 3
输出:
4 5 2 3 1

代码实现(从上到下分别为题目一、题目二的C++代码):

#include <iostream>
#include <sstream>

using namespace std;

template<class T>
class binaryTree
{
public:
    virtual ~binaryTree() {}
    virtual bool empty() const = 0;
    virtual int size() const = 0;
    virtual void preOrder(void (*) (T*)) = 0;
    virtual void inOrder(void (*) (T*)) = 0;
    virtual void postOrder(void (*) (T*)) = 0;
    virtual void levelOrder(void (*) (T*)) = 0;
};

template<class T>
class queue
{
public:
    virtual ~queue() {}
    virtual bool empty() const = 0;
    virtual int size() const = 0;
    virtual T& front() = 0;
    virtual T& back() = 0;
    virtual void pop() = 0;
    virtual void push(const T& theElement) = 0;
};
template<class T>

class arrayQueue : public queue<T>
{
public:
    arrayQueue(int initialCapacity = 10);
    ~arrayQueue() { delete[] queue; }
    bool empty() const { return theFront == theBack; }
    int size() const
    {
        return (theBack - theFront + arrayLength) % arrayLength;
    }
    T& front()
    {
        return queue[(theFront + 1) % arrayLength];
    }
    T& back()
    {
        return queue[theBack];
    }
    void pop()
    {
        theFront = (theFront + 1) % arrayLength;
        queue[theFront].~T();
    }
    void push(const T& theElement);
private:
    int theFront;      
    int theBack;       
    int arrayLength;   
    T* queue;          
};

template<class T>
arrayQueue<T>::arrayQueue(int initialCapacity)
{
    arrayLength = initialCapacity;
    queue = new T[arrayLength];
    theFront = 0;
    theBack = 0;
}

template<class T>
void arrayQueue<T>::push(const T& theElement)
{
    if ((theBack + 1) % arrayLength == theFront)
    {
        T* newQueue = new T[2 * arrayLength];

        int start = (theFront + 1) % arrayLength;
        if (start < 2)
          
            copy(queue + start, queue + start + arrayLength - 1, newQueue);
        else
        {  
            copy(queue + start, queue + arrayLength, newQueue);
            copy(queue, queue + theBack + 1, newQueue + arrayLength - start);
        }

        theFront = 2 * arrayLength - 1;
        theBack = arrayLength - 2;   
        arrayLength *= 2;
        queue = newQueue;
    }

    theBack = (theBack + 1) % arrayLength;
    queue[theBack] = theElement;
}
template <class T>

struct binaryTreeNode
{
    T element;
    binaryTreeNode<T>* leftChild,   
        * rightChild; 

    binaryTreeNode() { leftChild = rightChild = NULL; }
    binaryTreeNode(const T& theElement) :element(theElement)
    {
        leftChild = rightChild = NULL;
    }
    binaryTreeNode(const T& theElement,
        binaryTreeNode* theLeftChild,
        binaryTreeNode* theRightChild)
        :element(theElement)
    {
        leftChild = theLeftChild;
        rightChild = theRightChild;
    }
};

struct booster
{
    int degradeToLeaf,      
        degradeFromParent;     
    bool boosterHere;            

    void output(ostream& out) const
    {
        out << boosterHere << ' ' << degradeToLeaf << ' '
            << degradeFromParent << ' ';
    }
};

ostream& operator<<(ostream& out, booster x)
{
    x.output(out); return out;
}

template<class E>
class linkedBinaryTree : public binaryTree<binaryTreeNode<E> >
{
public:
    linkedBinaryTree() { root = NULL; treeSize = 0; }
    ~linkedBinaryTree() { erase(); };
    bool empty() const { return treeSize == 0; }
    int size() const { return treeSize; }
    E* rootElement() const;
    void makeTree(const E& element,
        linkedBinaryTree<E>&, linkedBinaryTree<E>&);
    linkedBinaryTree<E>& removeLeftSubtree();
    linkedBinaryTree<E>& removeRightSubtree();
    void preOrder(void(*theVisit)(binaryTreeNode<E>*))
    {
        visit = theVisit; preOrder(root);
    }
    void inOrder(void(*theVisit)(binaryTreeNode<E>*))
    {
        visit = theVisit; inOrder(root);
    }
    void postOrder(void(*theVisit)(binaryTreeNode<E>*))
    {
        visit = theVisit; postOrder(root);
    }
    void levelOrder(void(*theVisit)(binaryTreeNode<E>*));
    void preOrderOutput() { preOrder(output); cout << endl; }
    void inOrderOutput() { inOrder(output); cout << endl; }
    void postOrderOutput() { postOrder(output); cout << endl; }
    void levelOrderOutput() { levelOrder(output); cout << endl; }
    void erase()
    {
        postOrder(dispose);
        root = NULL;
        treeSize = 0;
    }
    int height() const { return height(root); }
protected:
    binaryTreeNode<E>* root;              
    int treeSize;                           
    static void (*visit)(binaryTreeNode<E>*);      
    static int count;       
    static void preOrder(binaryTreeNode<E>* t);
    static void inOrder(binaryTreeNode<E>* t);
    static void postOrder(binaryTreeNode<E>* t);
    static void countNodes(binaryTreeNode<E>* t)
    {
        visit = addToCount;
        count = 0;
        preOrder(t);
    }
    static void dispose(binaryTreeNode<E>* t) { delete t; }
    static void output(binaryTreeNode<E>* t)
    {
        if(t!=NULL)
        cout << t->element << ' ';
    }
    static void addToCount(binaryTreeNode<E>* t)
    {
        count++;
    }
    static int height(binaryTreeNode<E>* t);
};

template<class T>
void (*linkedBinaryTree<T>::visit)(binaryTreeNode<T>*);///

template<class E>
E* linkedBinaryTree<E>::rootElement() const
{
    if (treeSize == 0)
        return NULL;  // no root
    else
        return &root->element;
}

template<class E>
void linkedBinaryTree<E>::makeTree(const E& element,
    linkedBinaryTree<E>& left, linkedBinaryTree<E>& right)
{
    root = new binaryTreeNode<E>(element, left.root, right.root);
    treeSize = left.treeSize + right.treeSize + 1;

    left.root = right.root = NULL;
    left.treeSize = right.treeSize = 0;
}

template<class E>
linkedBinaryTree<E>& linkedBinaryTree<E>::removeLeftSubtree()
{
    
    linkedBinaryTree<E> leftSubtree;
    leftSubtree.root = root->leftChild;
    count = 0;
    leftSubtree.treeSize = countNodes(leftSubtree.root);
    root->leftChild = NULL;
    treeSize -= leftSubtree.treeSize;

    return leftSubtree;
}

template<class E>
linkedBinaryTree<E>& linkedBinaryTree<E>::removeRightSubtree()
{
   
    linkedBinaryTree<E> rightSubtree;
    rightSubtree.root = root->rightChild;
    count = 0;
    rightSubtree.treeSize = countNodes(rightSubtree.root);
    root->rightChild = NULL;
    treeSize -= rightSubtree.treeSize;

    return rightSubtree;
}

template<class E>
void linkedBinaryTree<E>::preOrder(binaryTreeNode<E>* t)
{
    if (t != NULL)
    {
        linkedBinaryTree<E>::visit(t);
        preOrder(t->leftChild);
        preOrder(t->rightChild);
    }
}

template<class E>
void linkedBinaryTree<E>::inOrder(binaryTreeNode<E>* t)
{
    if (t != NULL)
    {
        inOrder(t->leftChild);
        linkedBinaryTree<E>::visit(t);
        inOrder(t->rightChild);
    }
}

template<class E>
void linkedBinaryTree<E>::postOrder(binaryTreeNode<E>* t)
{
    if (t != NULL)
    {
        postOrder(t->leftChild);
        postOrder(t->rightChild);
        linkedBinaryTree<E>::visit(t);
    }
}

template <class E>
void linkedBinaryTree<E>::levelOrder(void(*theVisit)(binaryTreeNode<E>*))
{
    arrayQueue<binaryTreeNode<E>*> q;
    binaryTreeNode<E>* t = root;
    while (t != NULL)
    {
        theVisit(t);  
        if (t->leftChild != NULL)
            q.push(t->leftChild);
        if (t->rightChild != NULL)
            q.push(t->rightChild);

        
        if (q.empty()) {
            return;
        }
        else {
            t = q.front();
            q.pop();
        }
    }
}

template <class E>
int linkedBinaryTree<E>::height(binaryTreeNode<E>* t)
{
    if (t == NULL)
        return 0;                  
    int hl = height(t->leftChild); 
    int hr = height(t->rightChild); 
    if (hl > hr)
        return ++hl;
    else
        return ++hr;
}

struct st {
    int left;
    int right;
};

int main()
{
    linkedBinaryTree<int> a;

    
    int n;
    cin >> n;
    linkedBinaryTree<int> t[100001];
    struct st s[100001];
    int height[100001];
    int size[100001];
    for (int i = 1; i <= n; i++) {
        int L, R;
        cin >> L >> R;
        s[i].left = L;
        s[i].right = R;
    }
    

    for (int i = n; i >= 1; i--) {
        if (s[i].left != -1 && s[i].right != -1) {
            t[i].makeTree(i, t[s[i].left], t[s[i].right]);
        }
        if (s[i].left != -1 && s[i].right == -1) {
            t[i].makeTree(i, t[s[i].left], a);
        }
        if (s[i].left == -1 && s[i].right != -1) {
            t[i].makeTree(i, a, t[s[i].right]);
        }
        if (s[i].left == -1 && s[i].right == -1) {
            t[i].makeTree(i, a, a);
        }

        height[i]=t[i].height();
        size[i] = t[i].size();
    }
   
    t[1].levelOrderOutput();

    for (int i = 1; i <= n; i++) {
        cout << size[i] << " ";
    }
    cout << endl;

    for (int i = 1; i <= n; i++) {
        cout << height[i] << " ";
    }
}


#include<iostream>
using namespace std;

int preOrder[100000];
int inOrder[100000];

void postOrder(int pre, int post, int n)
{
    if (n == 1)
    {
        cout << preOrder[pre]<<" ";
        return;
    }
    if (n == 0) return;

    int i = 0;
    for (; preOrder[pre] != inOrder[post + i]; i++);

    postOrder(pre + 1, post, i);
    postOrder(pre + i + 1, post + i + 1, n - i - 1);

    cout << preOrder[pre]<<" ";
}

int main() {
    int n;
    cin >> n;
    for (int i = 0; i < n; i++) {
        cin >> preOrder[i];
    }
    for (int i = 0; i < n; i++) {
        cin >> inOrder[i];
    }
    postOrder(0, 0, n);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值