數據結構_一般二叉樹(C語言)

(一)二叉樹圖文解析

本文章對遞歸的理解要求較高(反正我是說不清楚的=,=)

一般二叉樹採用的是鏈式存儲結構,也就是單鏈表的結構,但二叉樹的結點包括倆個指針域,一個指向左結點,一個指右結點,即二叉,就像樹木一樣分叉成倆根樹枝,直到樹木分叉到最後不再分叉,最後不再分叉的結點也就是樹木的葉子。
在這裏插入圖片描述

(二) 二叉樹代碼解析

(1)二叉樹的基本操作

1.1 二叉樹的存儲結構

typedef struct BiTNode
{
	char data;//結點數據域
	struct BiTNode *Lchild,*Rchild;//左指針和右指針
}BiTNode,*BiTree;

1.2 先序遍歷創建二叉樹

void CreatBiTree(BiTree &T)
{
	char ch;
	scanf("%c",&ch);//輸入結點數據
	if(ch=='#')//輸入爲#代表結點爲空,不再創建新結點
		T=NULL;
	else
	{
		T=(BiTNode*)malloc(sizeof(BiTNode));//爲結點分配空間
		T->data=ch;//結點數據域爲ch
		CreatBiTree(T->Lchild);//遞歸創建左結點
		CreatBiTree(T->Rchild);//遞歸創建右結點
	}
}

1.3 二叉樹的先序遍歷

void PreOrderTraverse(BiTree T)
{
	if(T)
	{
		printf("%c ",T->data);//先輸出當前結點的數據
		PreOrderTraverse(T->Lchild);//然後遞歸遍歷左結點,輸出結點數據		
		PreOrderTraverse(T->Rchild);//再遞歸遍歷右結點,輸出結點數據
	}
}

遍歷順序要根據函數內遞歸順序來:(強行解說遞歸,意會、意會…)
1、首先輸出當前結點數據,然後遞歸遍歷左結點,遞歸完左結點後再遞歸右結點;
2、遞歸左結點的過程中,依舊是先輸出當前結點數據,直到左結點爲空後結束遞歸
3、在遞歸完左結點後再遞歸完右結點,仍然是先輸出當前結點數據,直到有結點爲空後結束遞歸

在這裏插入圖片描述

1.4 二叉樹的中序遍歷

void InOrderTraverse(BiTree T)
{
	if(T)
	{
		InOrderTraverse(T->Lchild);//先遞歸遍歷左結點,直到遞歸結束
		printf("%c ",T->data);//在輸出數據
		InOrderTraverse(T->Rchild);//然後遞歸遍歷右結點
	}//先遍歷到最後一個左結點,再輸出數據,然後遍歷右結點
}

1.5 二叉樹的後序遍歷

void PostOrderTraverse(BiTree T)
{
	if(T)
	{
		PostOrderTraverse(T->Lchild);//先遞歸遍歷左結點,直到結束
		PostOrderTraverse(T->Rchild);//再遞歸遍歷右結點,直到結束
		printf("%c ",T->data);//最後輸出數據
	}//先遍歷到最後一個左結點,再遍歷到最後一個左結點的最後一個右結點,最後輸出數據
}

1.6 二叉樹的深度

int Depth(BiTree T)
{
	if(T==NULL)
		return 0;
	else
	{
		int m=Depth(T->Lchild);//遞歸計算左子樹的深度
		int n=Depth(T->Rchild);//遞歸計算右子樹的深度
		if(m>n)//返回最大深度值
			return m+1;
		else
			return n+1;
	}
}

1.7 二叉樹的結點數

int NodeCount(BiTree T)
{
	if(T==NULL)//結點爲空,遞歸結束
		return 0;
	else//返回左結點+右結點+1,[+1]相當於計數結點的數量
		return NodeCount(T->Lchild)+NodeCount(T->Rchild)+1;
}

1.8 二叉樹的葉子數

int LeafCount(BiTree T)
{
	if(T==NULL)
		return 0;
	else 
		if(!T->Lchild&&!T->Rchild)//單個結點沒有子結點,葉子數爲一
			return 1;
		else//遞歸計算左葉子數和右葉子數的總數
			return LeafCount(T->Lchild)+LeafCount(T->Rchild);
}

(2) 二叉樹源代碼及測試

2.1 源代碼:

#include<stdio.h>
#include<malloc.h>
typedef struct BiTNode
{
	char data;
	struct BiTNode *Lchild,*Rchild;
}BiTNode,*BiTree;

void CreatBiTree(BiTree &T)
{
	char ch;
	scanf("%c",&ch);
	if(ch=='#')
	{
		T=NULL;
	}
	else
	{
		T=(BiTNode*)malloc(sizeof(BiTNode));
		T->data=ch;
		CreatBiTree(T->Lchild);
		CreatBiTree(T->Rchild);
	}
}
void PreOrderTraverse(BiTree T)
{
	if(T)
	{
		printf("%c ",T->data);
		PreOrderTraverse(T->Lchild);		
		PreOrderTraverse(T->Rchild);
	}
}
void InOrderTraverse(BiTree T)
{
	if(T)
	{
		InOrderTraverse(T->Lchild);
		printf("%c ",T->data);
		InOrderTraverse(T->Rchild);
	}
}

void PostOrderTraverse(BiTree T)
{
	if(T)
	{
		PostOrderTraverse(T->Lchild);
		PostOrderTraverse(T->Rchild);
		printf("%c ",T->data);
	}
}

int Depth(BiTree T)
{
	if(T==NULL)
		return 0;
	else
	{
		int m=Depth(T->Lchild);
		int n=Depth(T->Rchild);
		if(m>n)
			return m+1;
		else
			return n+1;
	}
}

int NodeCount(BiTree T)
{
	if(T==NULL)
		return 0;
	else
		return NodeCount(T->Lchild)+NodeCount(T->Rchild)+1;
}
int LeafCount(BiTree T)
{
	if(T==NULL)
		return 0;
	else 
		if(!T->Lchild&&!T->Rchild)
			return 1;
		else
			return LeafCount(T->Lchild)+LeafCount(T->Rchild);
}

int main()
{
	BiTree T;
	printf("先序遍歷創建二叉樹\n輸入結點數據('#'結束):");
	CreatBiTree(T);

	printf("先序遍歷輸出:");
	PreOrderTraverse(T);
	printf("\n");

	printf("中序遍歷輸出:");
	InOrderTraverse(T);
	printf("\n");

	printf("後序遍歷輸出:");
	PostOrderTraverse(T);
	printf("\n");

	printf("二叉樹深度:%d\n",Depth(T));

	printf("二叉樹結點數:%d\n",NodeCount(T));

	printf("二叉樹葉子數:%d\n",LeafCount(T));
	
	return 0;
}

2.2 測試結果:

測試環境 : Windows 10
編譯軟件 : Visual C++ 6.0

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章