數據結構學習(十一)——二叉樹的操做

關於樹的定義,從書上摘抄點過來。node

樹是n(>=0)個結點的有限集,在這個結點集合中,存在一下關係:code

  • 樹中存在惟一的一個結點無前趨,這個結點稱爲樹根
  • 除了除根結點外,其餘每一個結點都有且僅有一個直接前趨
  • 樹中每一個結點均可以有多個後繼,無後繼的結點成爲樹葉
二叉樹的定義
  • 有一個特定的稱爲根的結點
  • 根結點之外的其他結點分別由兩棵互不相交的稱爲左子樹和右子樹的二叉樹組成。
滿二叉樹:
深度爲k且含有2的K次方-1個結點的二叉樹稱爲滿二叉樹。除了最後一層爲葉結點外,全部其餘結點都有左右兩個子女。

徹底二叉樹:
深度爲k,含有那個結點的二叉樹,當且盡當每一個結點的編號與相應滿二叉樹結點順序號1~n對應時,稱此二叉樹爲徹底二叉樹。
對二叉樹的操做主要有遍歷,分爲先序/中序/後序遍歷。下面的代碼實現了二叉樹的遍歷操做。遍歷的核心是遞歸。

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

#define MAXSIZE 50

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

BTNode *BTNode_Create(char *str);	//建立一個二叉樹
void BTNode_Show(BTNode *p);		//輸出顯示一個二叉樹
void BTNode_PreOrder(BTNode *p);	//先序遍歷
void BTNode_MidOrder(BTNode *p);	//中序遍歷
void BTNode_PostOrder(BTNode *p);	//後序遍歷

int main(void)
{
	char *str = NULL;
	BTNode *p = NULL;
	int choice;

	str = (char*)malloc(MAXSIZE);

	printf("二叉樹操做練習\n");
	printf("輸入一個二叉樹(嵌套括號表示法):\n");
	gets(str);
	p = BTNode_Create(str);
	printf("輸出生成的二叉樹\n");
	BTNode_Show(p);
	printf("\n");

	while(1)
	{
		printf("二叉樹遍歷練習\n");
		printf("1.先序遍歷\n");
		printf("2.中序遍歷\n");
		printf("3.後序遍歷\n");
		printf("4.退出程序\n");
		printf("作出選擇:\n");
		scanf("%d", &choice);

		switch(choice)
		{
		case 1:
			BTNode_PreOrder(p);
			printf("\n");
			break;
		case 2:
            BTNode_MidOrder(p);
			printf("\n");
			break;
		case 3:
			BTNode_PostOrder(p);
			printf("\n");
			break;
		case 4:
			return 1;
			break;
		default:
			break;
		}
	}
	return 0;
}

//嵌套括號法建立二叉樹
BTNode *BTNode_Create(char *str)
{
	BTNode *s[MAXSIZE], *p, *B = NULL;
	int i = 0, top = -1, flag;
	char ch;

	ch = str[0];
	while(ch != '\0')
	{
		switch(ch)
		{
		case '(':				//上個結點爲根結點.根結點入棧,下個結點爲左孩子
			top++;
			s[top] = p;
			flag = 1;
			break;
		case ')':				//左右孩子處理完畢,根結點出棧
			top--;
			break;
		case ',':				//表示下個結點爲右孩子
			flag = 2;
			break;
		default:
			p = (BTNode*)malloc(sizeof(BTNode));
			p->data = ch;
			p->lchild = NULL;
			p->rchild = NULL;
			if(B == NULL)		//B爲空,表示當前輸入的爲根結點
				B = p;
			else
				if(flag == 1)	//左孩子
					s[top]->lchild = p;
				else if(flag == 2)	//右孩子
					s[top]->rchild = p;
			break;
		}
		i++;
		ch = str[i];
	}
	return B;
}

//輸出顯示二叉樹
void BTNode_Show(BTNode *p)
{
	if(p != NULL)
	{
		printf("%c", p->data);
		if(p->lchild != NULL || p->rchild != NULL)
		{
			printf("(");
			BTNode_Show(p->lchild);		//遞歸處理
			if(p->rchild != NULL)
			{
				printf(",");
				BTNode_Show(p->rchild);
			}
			printf(")");
		}
	}
}

//先序遍歷
void BTNode_PreOrder(BTNode *p)
{
	if(p != NULL)
	{
		putchar(p->data);
		BTNode_PreOrder(p->lchild);		//遞歸處理
		BTNode_PreOrder(p->rchild);
	}
}

//中序遍歷
void BTNode_MidOrder(BTNode *p)
{
	if(p != NULL)
	{
		BTNode_MidOrder(p->lchild);		//遞歸處理
		putchar(p->data);
		BTNode_MidOrder(p->rchild);
	}
}

//後序遍歷
void BTNode_PostOrder(BTNode *p)
{
	if(p != NULL)
	{
		BTNode_PostOrder(p->lchild);	//遞歸處理
		BTNode_PostOrder(p->rchild);
		putchar(p->data);
	}
}
相關文章
相關標籤/搜索