1. 程式人生 > >求二叉樹的寬度C語言版

求二叉樹的寬度C語言版

/*層次遍歷二叉樹,每一層遍歷完成以後都重新插入特定的指標
(比如本例使用的特殊指標是資料元素為#,左右兒子為空的指標),
這樣在每次訪問到所指向資料為#的佇列中的結點指標是就知道該指標是這層的末尾,需要統計,
但是又有個問題是,最後隊中所剩下的節點指標起資料一定是#,因此會陷入無限迴圈,解決的方法是,
在發現當前結點指標所指向的結點的資料是#的時候,在檢視佇列中是否還有元素(節點指標),
如果沒有,則說明是最後一層的最後一個結點指標,所以應該跳出迴圈*/
#include <stdio.h>
#include <malloc.h>
#define M 100

typedef struct BTNode
{
	char data;
	struct BTNode *lchild;
	struct BTNode *rchild;
}BTNode;

typedef struct Queue
{
	BTNode *data[M];
	int f;
	int r;
}Queue;

//建立二叉樹(先序方式)
void createTree(BTNode* *T)
{
	char ch = getchar();
	if(ch=='#') 
	{
		*T=NULL;
		return;
	}
	(*T) = (BTNode*)malloc(sizeof(BTNode));
	(*T)->data = ch;
	createTree(&(*T)->lchild);
	createTree(&(*T)->rchild);	
}
 
void preOrder(BTNode *T)//先序遍歷
{
	if(T==NULL) return;
	printf("%c\t", T->data);
	if(T->lchild!=NULL)
		preOrder(T->lchild);
	if(T->rchild != NULL)
		preOrder(T->rchild);
}

//求二叉樹的寬度
int width(BTNode *T)
{
	if(T==NULL) return 0;
	int num = 0;
	int max = 0;
	Queue Q;
	Q.r = 0;
	Q.f = 0;//initialize Queue
	memset(Q.data,NULL,M);
	Q.data[Q.r++] = T;

	BTNode *t = (BTNode*)malloc(sizeof(BTNode));
	t->data = '#';
	t->lchild = NULL;
	t->rchild = NULL;
	Q.data[Q.r++] = t;//enter Queue
	while(Q.r!=Q.f)
	{
		t = Q.data[Q.f++];
		if(t->data=='#')
		{
			if(max<num)
			{
				max = num;
				num = 0;
			}
			if(Q.data[Q.f]!=NULL)
			{
				t = (BTNode*)malloc(sizeof(BTNode));
				t->data = '#';
				t->lchild = NULL;
				t->rchild = NULL;
				Q.data[Q.r++] = t;
			}
			
		}
		else
		{
			++num;
			if(t->lchild) Q.data[Q.r++] = t->lchild;
			if(t->rchild) Q.data[Q.r++] = t->rchild;
		}
	}
	return max;
}

int main(int argc, char const *argv[])
{
	BTNode *T;
	createTree(&T);
	puts("PreOrder visit:");
	preOrder(T);
	putchar('\n');

	printf("the width of BTree is %d\n",width(T) );
	return 0;
}