PTA 5-7-6 List Leaves (27分)

问题描述:

给出N,表示N个结点。以0~N-1作为结点的数据(编号),随后按照顺序输入各个结点的左右子结点的编号,‘-’表示无子结点。
要求:
按照从上到下,从左到右的顺序输出叶子结点的编号。

问题分析:

  • 首先需要从结点数据中找到根节点,从而才可进行遍历。
  • 按照题目的输出要求,可判断为层序遍历输出叶子结点。

解决方法:

  • 结构:
    Node node[MAXSIZE]; //树的结点数组
    bool root[MAXSIZE]; //根节点
typedef struct{
	int data,lchild,rchild;
}Node;
typedef struct{
	
	Node *base;
	int front;
	int rear;
	
}queue;
  • 数据输入时,空结点则lchild,rchild为-1,非空则为输入的编号;

  • 通过根节点不会是某个结点的子节点,从而用 一个bool root[MAX],对应结点的下标。初始化为true,输入数据的同时将出现的子节点的对应下标改为false,即可找到根节点。

  • 层序遍历采用队列的数据结构,首先将树的根节点入队,用temp保存队头,并将队头出队,将temp的左右子结点入队。从而保证每个元素都按顺序成为队头,子节点按顺序入队。

  • 入队过程判断lchild与rchild是否为-1,是则入result队。

具体代码:

#include <iostream>
using namespace std;
#define MAXSIZE 10
typedef struct{
	int data,lchild,rchild;
}Node;
typedef struct{
	
	Node *base;
	int front;
	int rear;
	
}queue;
bool root[MAXSIZE];   //根节点 
Node node[MAXSIZE];   //树的结点数组 
void InitQueue(queue &q)
//初始化队列
{
	q.base = new Node[MAXSIZE];
	q.rear = q.front = 0;
}
void input(Node node[],int n)
//输入结点数据 
{

	char left,right;
	for(int i=0; i<n; i++)
	{
		root[i] = true;
	}
	for(int i=0; i<n; i++)
	{
		node[i].data = i;
		cin >> left >> right;
		if (isdigit(left))  //判断是否为十进制数字
		{
			node[i].lchild = left-'0';
			root[left-'0'] = false;
//			cout << root[left-'0'] << " ";
		}
        else
        	node[i].lchild = -1;
       	if (isdigit(right))
       	{
       		node[i].rchild = right-'0';
       		root[right-'0'] = false;
		}
        else
        	node[i].rchild = -1;		
	}	
}
int rootnode(bool root[],int n)
//寻找根节点 
{
	int i;
	for(i=0; i<n; i++)
	{
		if(root[i] == true)
		{
			return i;
		}
	}
	
}
void push(queue &Q,Node root)
//根节点入队 
{
	Q.base[Q.rear] = root;
	Q.rear++; 
	
}
void pop(queue &Q)
{
	Q.front++;	
} 
queue leaves(Node node[],Node rootNode)
//根据根节点,将所有节点进行入队,出队,从而获得result(层序遍历所得的叶子结点队列)
{
	queue Q;
	queue result;
	InitQueue(Q);
	InitQueue(result);
	push(Q,rootNode);
	Node temp;
	while(Q.rear != Q.front)
	{
		temp = Q.base[Q.front];
//		cout << temp << "..";
		pop(Q);
		if(temp.lchild!=-1)
		{
			push(Q,node[temp.lchild]);

		}
		if(temp.rchild!=-1)
		{
			push(Q,node[temp.rchild]);
		}
		if(temp.lchild ==-1 && temp.rchild == -1)
		{
			push(result,temp);  //叶子节点入队
		}
				
	}
	return result;
}
void output(queue &Q)
//输出队列
{
	cout << Q.base[Q.front].data;
    Q.front++;
	while(Q.rear!= Q.front)
	{
		cout << " "   << Q.base[Q.front].data;
		Q.front++;
	}
	
	
}
int main()
{
	int n;
	cin >> n;
	input(node,n);
	int rootNode;
	rootNode = rootnode(root,n);
	queue leavenode;
	InitQueue(leavenode);
	leavenode = leaves(node,node[rootNode]);
	output(leavenode);
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值