层次遍历树

本文介绍了一种算法,用于将树的先根顺序存储序列转换为层次遍历序列,并提供了两种实现方式:一种是通过建立树结构,另一种是使用链表。这两种方法都能有效地解决层次遍历的问题。

层次遍历树


Time Limit:

1000MS

 
Memory Limit:

10000K

Description

给出树的先根顺序存储序列(参看书上P211的公式6.3),其中“)”表示子树的结束,结点值均为大写英文字母。

层次化输出,即先输出根结点,然后是根结点的第一个孩子、根结点的第二个孩子,一层一层,从左到右地输出。

例:先根顺序存储序列RAC)D)E))BF))),对应树:

层次输出序列为:RABCDEF。

Input

首先输入整数t (1 ≤ t ≤ 10),表示t种测试情况。

接下来是每种测试情况的输入数据。

每种测试情况有一行,即树的先根顺序存储序列。

Output

种测试情况对应一行输出,即对应树的层次输出序列。

Sample Input

2

RAC)D)E))BF)))

XPC)Q)RV)M))))

Sample Output

RABCDEF

XPCQRVM

Hint

No hint.

Source


解题代码:
建立树:

#include<iostream>
#include<cstring>
#include<queue>
using namespace std;
class GTNode
{
public:
	char data;
    GTNode *leftmost_child;
    GTNode *right_sibling;

  GTNode(char a)
  {
	  data=a;
	  this->leftmost_child=NULL;
	  this->right_sibling=NULL;
  }

  void insert_first(GTNode *n)
  {leftmost_child=n;}
  void insert_next(GTNode *n)
  {right_sibling=n;}
  
};


GTNode* Translate(string a)
{
 if(a.length()==0)
	 return NULL;
 if(a[0]==')')
	 return NULL;
 GTNode* subroot=new GTNode(a[0]);
 int count=0;
 int pos=1;
 //找出最左子树
 while(count>=0&&count<= a.length())
 {
	 if(a[pos]==')' )
		 count--;
	 else 
		 count++;
	 pos++;
 }

 subroot->insert_first(Translate(a.substr(1,pos-1)));
 subroot->insert_next(Translate(a.substr(pos,a.length()-pos)));
 return subroot;
};

void Print(GTNode* subroot)
{
 queue<GTNode*> a;
 if(subroot!=NULL)
 {
  a.push(subroot);
  while(!a.empty())
  {
	  GTNode *temp;
	  temp=a.front();
	  a.pop();
	  while(temp!=NULL)
	  {
		  if(temp->leftmost_child !=NULL)
			  a.push(temp->leftmost_child);
		  cout<<temp->data;
		  temp=temp->right_sibling;
	  }
  }
 }
};

int main()
{
	char c[1000];
	int n=0;
	cin>>n;
	GTNode *subroot;
	for(int i=0;i<n;i++)
	{
		cin>>c;
		string s=(string) c;
		subroot=Translate(s);
		Print(subroot);
		cout<<endl;
	}
}

不建立树,运用链表:

#include <iostream>
using namespace std;
struct List
{
	int t;
	char ch;
	List *next;
	List(int d,char c,List *n)
	{
		t=d;
		ch=c;
		next=n;
	}
};

int main() 
{
	int n;
	cin>>n;
	while(n>0)
	{
		List *head=NULL;
		List *a=NULL;
		char ch[80];
		cin>>ch;
		string s=(string)ch;
		int flag=1;
		int j=0;
		head=new List(++j,s[0],NULL);
		a=head;
		for(int i=1;i<s.size();i++)
		{   
			
			if(s[i]!=')'&&s[i-1]==')')
			{
				a->next=new List(j,s[i],NULL);
				a=a->next;
			}
			else if(s[i]!=')'&&s[i-1]!=')')
				{
				  a->next=new List(++j,s[i],NULL);
				  a=a->next;
			    }

			if(s[i]==')'&&s[i-1]==')')
			{
				if(flag<j)
					flag=j;
				--j;
			}
		}
		
		for(int i=1;i<=flag;i++)
		{
			a=head;
			while(a!=NULL)
			{
				if(a->t==i)
					cout<<a->ch;
				a=a->next;
			}							
		}
		cout<<endl;
		n--;
	}
}


评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值