c實現鏈式存儲二叉樹和二叉樹遍歷

#1二叉樹

    (1) 二叉樹是一種樹型結構

    (2) 二叉樹的特點:每個結點至多隻有兩棵子樹,並且有左右子樹之分。

可以使用順序存儲或鏈式存儲二叉樹

#1.1順序存儲二叉樹

#define MAX_BINARYTREE_SIZE 100 //最多結點
typedef TElemType SqBiTree[MAX_BINARYTREE_SIZE]; //SqBiTree[0]爲根結點
SqBiTree bt;

用第編號i表示指定結點,若i=1即爲根結點SqBiTree[i-1]即SqBiTree[0]存儲

指定i結點,i > 1,則parent(i) = [i/2]  ,即i/2後向下取整。

                               lchild(i) = 2*i    

                               rchild(i) = 2*i +1

所以我們以SqBiTree[i-1]存儲第i個結點

               以SqBiTree[2*i - 1]存儲第i個結點的左子結點

               以SqBiTree[2*i]存儲第i個結點的右子結點

分析如圖 1所示。

#1.2鏈式存儲二叉樹

這裏用c實現鏈式存儲二叉樹,即二叉鏈表

二叉樹的結點由一個數據元素和分別指向其左右子樹的兩個分支構成。

實現代碼如下:

/*
 ============================================================================
 Name        : BinaryTreeC.c
 Author      : lingo
 Version     :
 Copyright   : Your copyright notice
 Description : Hello World in C, Ansi-style
 ============================================================================
 */

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
/**
 * 結構體寫法  左邊其實等於右邊可以看出BiTNode,BiTree爲後聲明的名稱,
 * 所以定義結構時不能使用 BiTNode和BiTree ,但結構體前typedef則可使用
 *
	 typedef struct tNode{           struct tNode{
		TElemType data;					TElemType data;
		struct tNode* lchird;			struct tNode* lchird;
		struct tNode* rchird;			struct tNode* rchird;
	 }BiTNode,*BiTree;				 };
									 typedef struct tNode BiTNode;
									 typedef struct tNode* BiTree;

 */
/**
 *  結構體寫法2
	typedef struct tNode BiTNode;
	typedef struct tNode* BiTree;
	struct tNode{
	TElemType data;
	BiTNode* lchird;
	BiTNode* rchird;
	};

 */
typedef int Status;//函數結果狀態
typedef int TElemType;
typedef struct tNode{
	TElemType data;
	struct tNode *lchird,*rchird;
}BiTNode,*BiTree;
//創建一個結點,並返回一個指向該結點的指針
BiTNode * newBiTNode(int data){
	BiTNode *btnode = (BiTNode *)malloc(sizeof(BiTNode));
	btnode->data = data;
	btnode->lchird = NULL;
	btnode->rchird = NULL;
	return btnode;
}

void printBiTree(BiTree T){
	if(T){
		printf("%d\n",T->data);
	}
	if(T->lchird){
		printf("%d,his lchird: ",T->data);
		printBiTree(T->lchird);
	}
	if(T->rchird){
		printf("%d,his rchird: ",T->data);
		printBiTree(T->rchird);
	}
}

void DestoryBiTree(BiTree &T){
	if(T != NULL){
		DestoryBiTree(T->lchird);
		DestoryBiTree(T->rchird);
		free(T);
	}
}



初始化如下二叉樹:

mian函數:

int main(int arg,char *argv[]) {
	BiTree btroot = NULL;
	btroot = newBiTNode(1);  //根結點
	btroot->lchird = newBiTNode(2); 
	btroot->rchird = newBiTNode(3);
	btroot->lchird->lchird = newBiTNode(4);
	btroot->lchird->rchird = newBiTNode(5);
	btroot->rchird->lchird = newBiTNode(6);

	printBiTree(btroot);

	DestoryBiTree(btroot);
	return 0;
}

結果:

1
1,his lchird: 2
2,his lchird: 4
2,his rchird: 5
1,his rchird: 3
3,his lchird: 6

若一顆二叉樹如下所示:

在二叉樹的遍歷中有,

1. 先(根)序遍歷,結果爲: 1 245 36

2.中(根)序遍歷 ,結果爲: 425 1  63

3.後(根)序遍歷 ,結果爲: 452 63  1

遍歷實現如下:

Status Visit(TElemType e){
	printf("%d",e);
	return OK;
}
// 先序遍歷
Status PreOrderTraverse(BiTree T,Status (* Visit)(TElemType)){
	if(T){
		Visit(T->data);
		PreOrderTraverse(T->lchird,Visit);
		PreOrderTraverse(T->rchird,Visit);
	}
	return OK;
}
Status InOrderTraverse(BiTree T,Status (* Visit)(TElemType)){
	if(T){
			InOrderTraverse(T->lchird,Visit);
			Visit(T->data);
			InOrderTraverse(T->rchird,Visit);
		}
	return OK;
}
Status PostOrderTraverse(BiTree T,Status (* Visit)(TElemType)){
	if(T){
			PostOrderTraverse(T->lchird,Visit);
			PostOrderTraverse(T->rchird,Visit);
			Visit(T->data);
		}
	return OK;
}

 測試代碼:

int main(int arg,char *argv[]) {
	BiTree btroot = NULL;
	btroot = newBiTNode(1);
	btroot->lchird = newBiTNode(2);
	btroot->rchird = newBiTNode(3);
	btroot->lchird->lchird = newBiTNode(4);
	btroot->lchird->rchird = newBiTNode(5);
	btroot->rchird->lchird = newBiTNode(6);
	printf("先序遍歷:");
	PreOrderTraverse(btroot,*Visit);
	printf("\n中序遍歷:");
	InOrderTraverse(btroot,*Visit);
	printf("\n後序遍歷:");
	PostOrderTraverse(btroot,*Visit);
	DestoryBiTree(btroot);
	return 0;
}

 

層次遍歷:非葉子結點左或右結點爲空輸出NULL

層次遍歷結果:1 2 3 4 5 6 

若結點4刪除,則遍歷結果:1 2 3 5 6 

Status LevelOrderTraverse(BiTree T){
	SqQueueP sq;
	InitQueue(sq);
	EnQueue(sq, T);
	while(!QueueEmpty(sq)){
		BiTNode* temp = DeQueue(sq);
		if(temp) {
			printf(" %d ",temp->data);
			if(!temp->lchird&&!temp->rchird){ //若爲葉子結點不存儲左右子結點
				continue;
			}else{
				EnQueue(sq, temp->lchird);
				EnQueue(sq, temp->rchird);
			}
		}
	}
	return OK;
}

若是左或右子結點爲空以NULL並輸出存在則修改遍歷算法中指針判斷如下:

if(temp) {
	printf(" %d ",temp->data);
        EnQueue(sq, temp->lchird);
	EnQueue(sq, temp->rchird);
}
else printf(" NULL ");

層次遍歷結果如下:

層次遍歷結果:1 2 3 4 5 6 NULL

層次遍歷結果:1  2  3  NULL  NULL  6  NULL  NULL  NULL 

 

 

                              圖1 順序存儲二叉樹思路

 

 

 

 

 

 

 

 

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