Hierarchical traversal of the UVA122 tree Trees on the level (two methods detailed)

Hierarchical traversal of the UVA122 tree on the level

Input:

(11,LL) (7,LLL) (8,R)
(5,) (4,L) (13,RL) (2,LLR) (1,RRR) (4,RR) ()
(3,L) (4,R) ()

Output:

5 4 8 11 13 4 7 2 1
not complete

//Both left and right subtrees have P/2 parent nodes;
The following is from Introduction to Algorithmic Competition Classic

1. Introduction to Algorithmic Competition Classic

Method 1: Structures + Pointer

struct Node{
 bool have_value;//Is it assigned or not? This is for the purpose of this question
 int v;//Node Value
 Node* left, *right;
 Node():have_value(false),left(NULL),right(NULL){}//Constructor
}*root;//Root Node of Binary Tree

Since a binary tree is defined recursively, its left and right subnode types are "pointers to node types".In other words, if the type of node is Node, the left and right child nodes are of Node *.

Each time a new Node is needed, the new operator is used to request memory and execute the constructor.The following encapsulates the request for a new node in the newnode function:

Node* newnode() { return new Node(); }

Also here, lrj mentions that each time root=newnode() is executed, the memory becomes inaccessible memory garbage, so it is best to write a recursive function specifically to clean up the memory.
Here's the code to clear memory, add a line before "root = newnode()"

"remove_tree(root)": 
void remove_tree(Node* u) {  
   if(u == NULL) return;//Better judgment in advance  
   remove_tree(u->left);//Recursively frees up space in the left subtree
   remove_tree(u->right);//Recursively frees up space in the right subtree 
   delete u;//Call the destructor of u and release the memory of the U node itself 
}

Method 2: Array + Subscript

Each node is numbered first, but not in the top-down, left-to-right order, but in the order in which nodes are generated.The counter cnt represents the maximum number of existing nodes, so the newnode function needs to be changed to this:

const int root = 1;    
void newtree() { 
   left[root] = right[root] = 0; 
   have_value[root] = false; 
   cnt = root;
}    
int newnode() { 
   int u = ++cnt; 
   left[u] = right[u] = 0; 
   have_value[root] = false; 
   return u; 
}

The newtree() above is used instead of the previous two statements, "remove_tree(root)" and "root = newnode()": since there is no dynamic memory request and release, just reset the node counter and the left and right subtrees of the root node.Next, change all Node types to int types, and then change member variables in the node structure to global arrays (for example, u->left and u->rightto left[u] and right[u], respectively), and the whole program has no pointers except char.

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ifstream in("input.txt");
ofstream out("output.txt");
#define debug(x) cerr<<#x<<" = "<<x<<endl
#define debugs(x,y) cerr<<#x<<" = "<<x<<"   "<<#y<<" = "<<y<<endl
const ll N=5e5+7;
const ll base=137;
const ll mod=2147483647;
template<typename T>inline T read(T &x)
{
    x=0;ll f=1;char c;
    while(!isdigit(c=getchar()))if(c=='-')f=-1;
    while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
    return x*f;
}
struct node
{
    ll v;//number
    bool have_value;
    node *left,*right;
    node():have_value(false),left(NULL),right(NULL){}
};
ll v;
bool flag;
char s[N];
node *root;
node* newnode(){return new node();}
inline void remove_tree(node *p)
{
    if(p==NULL)return ;
    remove_tree(p->left);
    remove_tree(p->right);
    delete p;
}
inline bool bfs(vector<ll>&ans)
{
    ans.clear();
    queue<node*>q;
    q.push(root);
    while(!q.empty())//Use queue FIFO for hierarchical traversal
    {
        node*u=q.front();
        q.pop();
        if(!u->have_value)
            return false;
        ans.push_back(u->v);
        if(u->left!=NULL)
            q.push(u->left);
        if(u->right!=NULL)
            q.push(u->right);
    }
    return true;
}
inline void add_node(ll v,char *s)
{
    int len=strlen(s);
    node*u=root;
    for(int i=0;i<len;++i)
    {
        if(s[i]=='L'){
            if(u->left==NULL)
                u->left=newnode();
            u=u->left;
        }
        if(s[i]=='R'){
            if(u->right==NULL)
                u->right=newnode();
            u=u->right;
        }
    }
    if(u->have_value){flag=true;}
    u->v=v;
    u->have_value=true;
}
inline bool read_input()
{
    flag=false;
    remove_tree(root);
    root=newnode();
    for( ;; )
    {
        if(scanf("%s", s) != 1) {
            return false;
        }
        if(strcmp(s,"()") == 0) {
            break;
        }
        sscanf(&s[1],"%d",&v);
        add_node(v,strchr(s,',')+1);
    }
    return true;
}
int main()
{
    vector<ll>ans;
    //freopen("input.txt","r",stdin);
    //freopen("output.txt","w",stdout);
    while(read_input())
    {

        if(flag||!bfs(ans)){
            printf("not complete");
        }
        else {
            for(vector<ll>::iterator it=ans.begin();it!=ans.end();it++){
                if(it!=ans.end()-1)
                    printf("%lld ",*it);
                else printf("%lld",*it);
            }
        }
        puts("");
    }
    return 0;
}

2. Using STL Ultra Short Codes

#include <iostream>
#include <string>
#include <map>
#include <queue>

using namespace std;

string OPT;
struct Node
{
    long long P, Num;
    Node(){}
    Node(long long X, long long Y) : P(X), Num(Y){}
    bool operator < (const Node &A) const
    {
        return P > A.P;//Numbering goes from small to large for the following reasons
    }
};
priority_queue <Node> Ans;//To store an existing point
priority_queue <Node> OutPut;//For output
map <long long, bool> Che;
//(long long long) used to convert the string representing the location to binary, bool indicating whether the location has ever occurred

inline void WorkOut()
{
    long long i(1), Num(0), P(1);
    for (; OPT[i] != ','; ++i)Num = (Num << 1) + (Num << 3) + (OPT[i] ^ 48);//string to int
    ++i;
    for (; OPT[i] != ')'; ++i)OPT[i] == 'L' ? P = P << 1 : P = P << 1 | 1;//Turn the LR representation into binary, similar to the segment tree LSon = Root << 1, RSon = Root << 1 | 1, so 1 is the root node
    Ans.push(Node(P, Num));
}

inline bool Check()
{
    Che[0] = 1;
    while (!Ans.empty())
    {
        if (!Che[Ans.top().P >> 1] || Che[Ans.top().P]) return 0;
        //If you don't have a Dad, the tree can't be output, the location has two values, and it can't be output
        Che[Ans.top().P] = 1;
        OutPut.push(Ans.top());
        Ans.pop();
    }
    return 1;
}

int main()
{
    while (cin >> OPT)
    {
        WorkOut();
        while (cin >> OPT && OPT.size() > 2)WorkOut();
        if (Check())
        {
            while (OutPut.size() > 1)//It looks like you want to card spaces, so take care of it specially
            {
                cout << OutPut.top().Num << ' ' ;
                OutPut.pop();
            }
            cout << OutPut.top().Num << endl ;
        }
        else cout << "not complete" << endl ;
        while (!OutPut.empty())OutPut.pop();//empty
        while (!Ans.empty())Ans.pop();//empty
        Che.clear();
    }
}

56 original articles published, 58 praised, 5659 visits
Private letter follow

Posted by fypstudent on Sat, 22 Feb 2020 18:11:02 -0800