1. 程式人生 > >PAT程式設計考題——甲級1004 遍歷樹節點(計算樹每層的葉子節點數目)

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;
}