数据结构算法——1065. 树的相关操作

本文介绍了一种使用栈和队列实现树的前序、中序和后序遍历的方法,并提供了完整的C++代码示例。通过这些算法,可以有效地进行节点计数和高度计算。

题目

在这里插入图片描述
输入
1 -1
2 1
3 2
4 3
5 4
6 5
7 5
8 6
9 7
10 7
11 8
12 9
13 9
14 10
15 10
输出
在这里插入图片描述

思路

可以尝试一下编写前后层序遍历的迭代形式
前序:
①根进stack
②当stack不为空 [while(!s.empty())]
③.1 temp = stack.pop
③.2 判断 temp是否有右节点
③.2.1有:全部存放进去(由于stack的特性,从右向左入栈)
③.2.2 没有:啥也不做
④输出temp的数据data

层序:
可以用队列来进行操作
思路可以参考前序

后序:
后序的输出如果利用栈的话,还得构造一个pair来多储存一个布尔值来判断这个结点的儿子是否入栈过即可(由于懒还是用回了递归)

代码

#include<iostream>
#include<stack>
#include<deque>
using namespace std;

struct dot
{
    int data;
    dot* parent;
    dot* head_kid;
    dot* tail_kid;
    
    dot* prev;
    dot* next;

    int leaf_num;
    int dot_num;
    int tree_height;

    dot()
    {
        data = 0;
        parent = head_kid = tail_kid = NULL;
        prev = next = NULL;
        leaf_num = dot_num = tree_height = 0;
    }

    void pre_print()
    {
        
        stack<dot*> s;
        //先序遍历是根左右
        //对应栈就是先放根,然后pop根,push右,push左
        if(this)
            s.push(this);
        
        while(!s.empty())
        {
            
            dot* temp = s.top();
            s.pop();
            
            dot* store = temp->tail_kid;
            if(store)
            {
                while(store != temp->head_kid)
                {
                    s.push(store);
                    store = store->prev;
                }
                s.push(store);
            }
            cout << temp->data << (s.empty() ? "\n" : " ");
        }

    }
    void post_print()
    {
        if(this)
        {
            dot*record = this->head_kid;
            if(record)
            {
                while(record != this->tail_kid)
                {
                    record->post_print();
                    record = record->next;
                }
                record->post_print();
            }
            cout << this->data << " ";
        }
    }
    void layer_print()
    {
        deque<dot*> s1;
        deque<dot*> s2;
        if(this)
            s1.push_back(this);
        while(!s1.empty() || !s2.empty())
        {
            while(!s1.empty())
            {
                dot* temp = s1.front();
                s1.pop_front();
                
                dot* store = temp->head_kid;
                if(store)
                {
                    while(store != temp->tail_kid)
                    {
                        s2.push_back(store);
                        store = store->next;
                    }
                    s2.push_back(store);
                }
                cout << temp->data << ( (s1.empty() && s2.empty())? "\n" : " ");
            }
            while(!s2.empty())
            {
                dot* temp = s2.front();
                s2.pop_front();
                
                dot* store = temp->head_kid;
                if(store)
                {
                    while(store != temp->tail_kid)
                    {
                        s1.push_back(store);
                        store = store->next;
                    }
                    s1.push_back(store);
                }//
                cout << temp->data << ( (s1.empty() && s2.empty())? "\n" : " ");
            }
        }
    }
    void leaf_dot()
    {
        int num = 0;
        stack<dot*> s;
        if(this)
            s.push(this);
        while(!s.empty())
        {
            dot* temp = s.top();
            s.pop();
            if(!temp->head_kid)
            {
                num++;
                cout << temp->data << " ";
            }
            else
            {
                dot*record = temp->tail_kid;
                if(record)
                {
                    while(record != temp->head_kid)
                    {
                        s.push(record);
                        record = record->prev;
                    }
                    s.push(record);
                }
            }
        }
        this->dot_num = num;
        cout << endl;
    }
    int height(int n = 0)
    {
        dot* temp = this->head_kid;
        if(!temp)
            return n;

        int k = 0;
        while(temp)
        {
            int j = temp->height(n + 1);
            temp = temp->next;
            if(j > k)
                k = j;
        }
        
        if(k > n)
            n = k;
        return n;
    }
};

void print_tree(dot* tree, int n)
{
    for(int i = 1; i <= n; i++)
    {
        (cout << tree[i].data  << " 父亲节点数据 " << (tree[i].parent ? tree[i].parent->data : -1) << endl); 
        dot* record = tree[i].head_kid;
        cout << " 儿子节点数据 :";
        if(record)
        {
            while(record != tree[i].tail_kid)
            {
                cout << record->data << " ";
                record = record->next;
            }
            cout << record->data << endl;
        }cout << endl;
    }
}
int main()
{
    dot* tree = new dot[1000];
    for(int i = 0; i <1000; i++)
        tree[i].data = i;
    dot* root;

    int n = 0;
    int index;int parent; 
    while((cin >> index))
    {   
        n++;
        cin >> parent;
        if(parent == -1)
            root = tree + index;
        else
        {
            tree[index].parent = (tree + parent);
    
            if(tree[index].parent->head_kid == NULL)
            {
                tree[index].parent->head_kid = tree + index;
                tree[index].parent->tail_kid = tree + index;
            }
            else
            {
                tree[index].parent->tail_kid->next = tree + index;
                tree[index].parent->tail_kid->next->prev = tree[index].parent->tail_kid;
                tree[index].parent->tail_kid = tree[index].parent->tail_kid->next;
            }
        }
    }

    //print_tree(tree,n);
    
    for(int i = 0; i < n; i++)
        if(tree[i].parent == NULL)
            root = &tree[i];

    root->pre_print();
    root->post_print();cout << endl;
    root->layer_print();
    cout << n << endl;
    root->leaf_dot();
    cout << root->dot_num << endl;
    cout << root->height();
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值