PAT程序设计考题——甲级1004 遍历树节点(计算树每层的叶子节点数目)

试题链接如下:点击打开链接

试题要求翻译如下:

程序输入:第一行输入为树总节点个数N(<100)、非叶子节点个数M,用空格分隔;随后输入M行,每行的格式如下:
ID K ID[1] ID[2]...ID[K]
第一个ID代表一个非叶子节点的两位数序号,不满两位用0填充,K代表该节点的子节点数目,随后的K个ID表示子节点的两位数序号。现定root根节点ID是01。
程序输出:算出树每层中叶子节点个数,从根节点所在层开始,逐渐向下层,用空格分隔。
例子:
input:
2 1
01 1 02
output:

0 1

代码设计如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct TreeNode 
{
	char				value;
	TreeNode**			childList;
	int					childCapacity;
	int					childNumber;

	TreeNode( char value )
	{
		childNumber = 0;
		childCapacity = 5;
		this->value = value;
		childList = (TreeNode**)malloc(childCapacity*sizeof(TreeNode*));
	}
	~TreeNode()
	{
		free(childList);
		childList = NULL;
	}
	void	SetNodeValue( char value )
	{
		this->value = value;
	}
	void	SetNodeList( TreeNode** list )
	{
		childList = list;
	}

	char	GetNodeValue()
	{
		return this->value;
	}
	TreeNode**	GetNodeList()
	{
		return childList;
	}
	TreeNode*	GetNodeListItem(int index)
	{
		return childList[index];
	}

	int		AddChild( TreeNode* node )
	{
		if ( childNumber == childCapacity )
		{
			TreeNode**	old = childList;
			childList = (TreeNode**)realloc( childList, 2*sizeof(TreeNode*)*childCapacity );
			if ( childList == NULL )
			{
				childList = old;
				return false;
			}
			childCapacity = 2*childCapacity;
		}
		childList[childNumber++] = node;
		return true;
	}
}TREE_NODE,*PTREE_NODE;

typedef struct LevelInfo 
{
	int* number;
	int  size;
	int  capacity;
	LevelInfo()
	{
		size = 0;
		capacity = 5;
		number = (int*)malloc(capacity*sizeof(int));
		for ( int i = 0; i < capacity; i++ )
		{
			number[i] = 0;
		}
	}
	~LevelInfo()
	{
		free(number);
	}
	void SetLevelCapacity( int count )
	{
		if ( capacity < count )
		{
			int* old = number;
			number = (int*)realloc( number, capacity*2 );
			if ( number == NULL )
			{
				number = old;
				return;
			}
			for ( int i = capacity; i < 2*capacity; i++ )
			{
				number[i] = 0;
			}
			capacity *= 2;
		}
	}
	void SetLevelSize( int level, int number )
	{
		this->number[level] = number;
		if ( level > size )		size = level;
	}
	int GetLevelSize( int level )
	{
		return number[level];
	}
	void ResetAnaly()
	{
		for ( int i = 0; i < capacity; i++ )
		{
			number[i] = 0;
		}
		size = 0;
	}
}LEVEL_INFO,*PLEVELINFO;

class CTreeLevelAnaly
{
public:
	CTreeLevelAnaly()
	{
		InitTree();
	}
	~CTreeLevelAnaly()
	{
		UninitTree(m_pTreeRoot);
		delete m_pTreeRoot;
	}
	int InitTree()
	{
		printf( "Please input the number of node and non-leaf node:\n");
		scanf( "%d %d", &m_iAllNodeCount, &m_iNonLeafNodeCount );

		TreeNode** tempList = (TreeNode**)malloc( m_iAllNodeCount*sizeof(TreeNode*) );
		for ( int i = 0; i < m_iAllNodeCount; i++ )
		{
			TreeNode* pNode = new TreeNode( (i+1) );
			tempList[i] = pNode;
		}
		printf( "Please input %d lines describe the parent and chidren\n", m_iNonLeafNodeCount );
		for ( int k = 0; k < m_iNonLeafNodeCount; k++ )
		{
			char* dot = NULL;
			char buffer[100] = {0};
			int* list = (int*)malloc( 100*sizeof(int) );
			int used = 0;

			printf( "the %d line:\n", k+1 );
			getchar();
			scanf( "%[^\n]", buffer );
			dot = strtok( buffer, " " );
			while ( dot != NULL )
			{
				list[used++] = atoi(dot);
				dot = strtok( NULL, " ");
			}
			list[used] = -1;

			for ( int j = 2; j < used; j++ )
			{
				int index = list[j];
				int pos = list[0];
				tempList[ pos - 1 ]->AddChild( tempList[ index - 1 ] );
			}
		}
		m_pTreeRoot = tempList[0];
		free(tempList);
		return 0;
	}
	void	UninitTree( TreeNode* node )
	{
		for (int i = 0; i < node->childNumber; i++ )
		{
			UninitTree( node->childList[i] );
			delete node->childList[i];
		}
	}
	TreeNode*	GetRootNode()
	{
		return m_pTreeRoot;
	}
	int PrintLevelAnaly()
	{
		int size = m_kLevelCount.size;
		for ( int i = 0; i <= size; i++ )
		{
			printf("Level %d has %d Leaf-Node\n", i, m_kLevelCount.number[i] );
		}
		return false;
	}
	// 深度优先,递归 
	int	dfsRecursiveLevelCount( TreeNode* node, int level )
	{
		printf("visiting: value:%c;level:%d\n", node->value, level );

		m_kLevelCount.SetLevelCapacity(level);

		// 筛选非叶子节点
		if ( node->childNumber == 0 )
		{
			int temp = m_kLevelCount.GetLevelSize( level );
			if ( temp == 0 )
			{
				temp = 1;
			}
			else
			{
				temp++;
			}
			m_kLevelCount.SetLevelSize( level, temp );
		}

		for (int i = 0; i < node->childNumber; i++ )
		{
			dfsRecursiveLevelCount( node->childList[i], level + 1 );
		}
		return 0;
	}
protected:
private:
	TreeNode*		m_pTreeRoot;
	LevelInfo		m_kLevelCount;
	int				m_iAllNodeCount;
	int				m_iNonLeafNodeCount;
};


int main()
{
	CTreeLevelAnaly* tree = new CTreeLevelAnaly;

	printf("-----------深度优先,递归------------\n");
	tree->dfsRecursiveLevelCount( tree->GetRootNode(), 0 );
	tree->PrintLevelAnaly();

	delete tree;
	printf("\n");
	return 0;
}






  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值