1. 程式人生 > >二叉樹的基本操作實現(建立、先序、中序、後序、層序)

二叉樹的基本操作實現(建立、先序、中序、後序、層序)

[問題描述]

建立一棵二叉樹,試程式設計實現二叉樹的如下基本操作: 1. 按先序序列構造一棵二叉連結串列表示的二叉樹T; 2. 對這棵二叉樹進行遍歷:先序、中序、後序以及層次遍歷,分別輸出結點的遍歷序列;

 [基本要求]

從鍵盤接受輸入(先序),以二叉連結串列作為儲存結構,建立二叉樹(以先序來建立),

[測試資料]

如輸入:ABC##DE#G##F###(其中#表示空格字元)則輸出結果為:

先序:ABCDEGF

中序:CBEGDFA

後序:CGEFDBA

層序:ABCDEFG

----------------------------------------------------------------我是分割線--------------------------------------------------------------------------------

【二叉樹定義】

二叉樹是n(n>=0)個結點所構成的集合,n=0時為空樹,n>0為非空樹。對於非空樹T:

1.有且僅有一個稱為 根 的結點;

2.除根節點外其餘結點分為兩個互不相交的子集T1,T2,分別稱為T的左子樹,右子樹

二叉樹與樹一樣具有遞迴性質,二叉樹每個結點至多兩顆子樹,子樹有左右之分,次序不可顛倒。

【儲存結構】

1.順序儲存結構

#define MAXSIZE 100
typedef TElemType SqBiTree[MAXSIZE];//0號單元儲存根節點,TElemType可換成自己需要的型別如char
SqBiTree bt;

2.鏈式儲存結構

typedef struct BiTNode
{
	char data;//結點資料域
	BiTNode *lchild, *rchild;//左右孩子指標
}BiTNode,*BiTree;

順序儲存結構只適用完全二叉樹,一般採用鏈式。

【先序建立二叉連結串列】

void CreateBiTree(BiTree&T)//先序遍歷的順序建立二叉表
{
	char ch;
	cin >> ch;//輸入的字串會進入緩衝區,
	if (ch == '#')//ch為字元型,(ch=="#")錯誤
		T = NULL;//遞迴結束,建立空樹
	else//遞迴建立二叉樹
	{
		T = new BiTNode;//生成根節點
		T->data = ch;//將ch賦值給資料域
		CreateBiTree(T->lchild);//遞迴建立左子樹
		CreateBiTree(T->rchild);//遞迴建立右子樹
	}
}

 【先序遍歷】

void PreOrderTraverse(BiTree T)//先序遍歷
{
	if (T)//若二叉樹非空
	{
		cout << T->data;//訪問根節點
		PreOrderTraverse(T->lchild);//先序遍歷左子樹
		PreOrderTraverse(T->rchild);//先序遍歷右子樹
	}
	
}

先中後序類似,先序是根左右,中序左根右,後序左右根,只要改變訪問根節點順序就行,具體程式碼在下面。

【層序遍歷】

void SeqOrderTraverse(BiTree T)//層序遍歷
{
	SqQueue q;
	InitQueue(q);
	EnQueue(q, T);
	while (q.rear!=q.front)
	{
		BiTree root = OutQueue(q);
		cout << root->data << " ";
		if (root->lchild)
			EnQueue(q, root->lchild);
		if (root->rchild)
			EnQueue(q, root->rchild);
	}
	cout << endl;
}

層序遍歷順序:ABCDEFG

每個結點遍歷都是 根--右 的順序,

A入隊後出隊,出隊時其左右孩子入隊,判斷左右孩子是否為空,如果非空,則入隊。其他結點類似。

-------------------------------------------------------------------我是分割線----------------------------------------------------------------------------------

【程式碼】

#include<iostream>
#define MAXSIZE 100
using namespace std;
typedef struct BiTNode
{
	char data;
	BiTNode *lchild, *rchild;
}BiTNode,*BiTree;
typedef struct SqQueue
{
	BiTree*base;//儲存空間的基地址
	int front;
	int rear;
};
void InitQueue(SqQueue&q)//構造空佇列
{
	q.base = new BiTree[MAXSIZE];
	if (!q.base) exit(OVERFLOW);
	q.front = q.rear = 0;
}
void EnQueue(SqQueue&q,BiTree&T)//入隊
{
	q.base[q.rear] = T;
	q.rear++;
}
BiTree OutQueue(SqQueue&q)
{
	BiTree T;
	T = q.base[q.front];
	q.front++;
	return T;
}
void CreateBiTree(BiTree&T)//先序遍歷的順序建立二叉表
{
	char ch;
	cin >> ch;//輸入的字串會進入緩衝區,
	if (ch == '#')//ch為字元型,(ch=="#")錯誤
		T = NULL;//遞迴結束,建立空樹
	else//遞迴建立二叉樹
	{
		T = new BiTNode;//生成根節點
		T->data = ch;//將ch賦值給資料域
		CreateBiTree(T->lchild);//遞迴建立左子樹
		CreateBiTree(T->rchild);//遞迴建立右子樹
	}
}
void PreOrderTraverse(BiTree T)//先序遍歷
{
	if (T)//若二叉樹非空
	{
		cout << T->data << " ";//訪問根節點
		PreOrderTraverse(T->lchild);//先序遍歷左子樹
		PreOrderTraverse(T->rchild);//先序遍歷右子樹
	}
	
}
void InOrderTraverse(BiTree T)//中序遍歷
{
	if (T)
	{
		InOrderTraverse(T->lchild);
		cout << T->data << " ";
		InOrderTraverse(T->rchild);
	}

}
void PostOrderTraverse(BiTree T)//後序遍歷
{
	if (T)
	{
		PostOrderTraverse(T->lchild);
		PostOrderTraverse(T->rchild);
		cout << T->data << " ";
	}

}
void SeqOrderTraverse(BiTree T)//層序遍歷
{
	SqQueue q;
	InitQueue(q);
	EnQueue(q, T);
	while (q.rear!=q.front)
	{
		BiTree root = OutQueue(q);
		cout << root->data << " ";
		if (root->lchild)
			EnQueue(q, root->lchild);
		if (root->rchild)
			EnQueue(q, root->rchild);
	}
	cout << endl;
}
int main()
{
	BiTree T;
	cout << "請輸入字串,#表空樹" << endl;
	CreateBiTree(T);
	cout << "先序輸出:";
	PreOrderTraverse(T);
	cout << endl;
	cout << "中序輸出:";
	InOrderTraverse(T);
	cout << endl;
	cout << "後序輸出:" ;
	PostOrderTraverse(T);
	cout << endl;
	cout << "層序輸出:";
	SeqOrderTraverse(T);
    return 0;
}

【執行結果】