1. 程式人生 > >二叉樹--順序結構

二叉樹--順序結構

#include "stdio.h"
#include "stdlib.h"
#include "math.h"

#define MAXSIZE 100
#define MAX_TREE_SIZE  100

typedef int Status;
typedef int TElemType;
typedef TElemType SqBiTree[MAX_TREE_SIZE];

typedef struct {
	int level,order;
	//結點的層,本層序號
}Position;

TElemType Nil=0;  

Status Visit(TElemType c)
{
	printf("%d ",c);
	return 1;
}

//構造空二叉樹
Status InitBiTree(SqBiTree T)
{
	int i;
	for (i=0;i<MAX_TREE_SIZE;i++){
		T[i]=Nil;
	}

	return 1;
}

//按照層次順序輸入結點的值
//構造順序儲存的二叉樹
Status CreateBiTree(SqBiTree T)
{
	int i=0;
	printf("請按層序輸入結點的值,節點數<=%d\n",MAX_TREE_SIZE);
	while (i<10){
		T[i]=i+1;

		if (i!=0&&T[(i+1)/2-1]==Nil&&T[i]!=Nil){
			printf("出現非根結點、無雙親、非空");
			exit(0);
		}
		i++;
	}

	while (i<MAX_TREE_SIZE){
		T[i]=Nil;
		i++;
	}

	return 1;
}
/* 在順序儲存結構中,兩函式完全一樣 */

Status BiTreeEmpty(SqBiTree T)
{
	if (T[0]==Nil){
		return 1;
	}
	else	
		return 0;
}

int BiTreeDepth(SqBiTree T)
{
	int i,j=-1;
	for (i=MAX_TREE_SIZE-1;i>=0;i--){
		if (T[i]!=Nil){
			break;
		}
	}//找到最後一個結點

	i++;
	do 
	{
		j++;
	} while (i>=powl(2,j));/* 計算2的j次冪。 */
	
	return j;
}

Status Root(SqBiTree T,TElemType *e)
{
	if (BiTreeEmpty(T)){
		return 0;
	}
	else
	{
		*e=T[0];
		return 1;
	}
}

TElemType Value(SqBiTree T,Position e)
{
	return T[(int)powl(2,e.level-1)+e.order-2];
}

Status Assign(SqBiTree T,Position e,TElemType value)
/* 操作結果: 給處於位置e(層,本層序號)的結點賦新值value */
{
	int i=(int)powl(2,e.level-1)+e.order-2;
	if (value!=Nil&&T[(i+1)/2-1]==Nil){
		exit(1);
	}
	else
	{
		if (value==Nil&&(T[2*i+1]==Nil||T[2*i+2]==Nil)){
			return 0;
		}
	}

	T[i]=value;
	return 1;
}

TElemType Parent(SqBiTree T,TElemType e)
{
	int i;
	if (T[0]==Nil){
		return Nil;
	}
	for (i=0;i<=MAX_TREE_SIZE-1;i++){
		if (T[i]==e){
			return T[(i+1)/2-1];
			printf("\n");
		}
	}

	return Nil;
}

TElemType LeftChild(SqBiTree T,TElemType e)
{
	int i;
	if (T[0]=Nil){
		return Nil;
	}

	for (i=0;i<MAX_TREE_SIZE;i++){
		if (T[i]==e){
			return T[2*i+1];
		}
	}
	return Nil;
}

TElemType RightChild(SqBiTree T,TElemType e)
{
	int i;
	if (T[0]=Nil){
		return Nil;
	}
	
	for (i=0;i<MAX_TREE_SIZE;i++){
		if (T[i]==e){
			return T[2*i+2];
		}
	}
	return Nil;
}

TElemType LeftSibling(SqBiTree T,TElemType e)
{
	int i;
	if (T[0]==Nil){
		return Nil;
	}

	for (i=0;i<=MAX_TREE_SIZE-1;i++){
		if (T[i]==e	 &&	i%2==0){
			return	T[i-1];
		}
	}

	return Nil;
}

TElemType RightSibling(SqBiTree T,TElemType e)
{
	int i;
	if (T[0]==Nil){
		return Nil;
	}
	
	for (i=0;i<=MAX_TREE_SIZE-1;i++){
		if (T[i]==e	 &&	i%2){
			return	T[i+1];
		}
	}
	
	return Nil;
}

//前序遍歷

void PreTraverse(SqBiTree T,int e)
{
	Visit(T[e]);
	if (T[2*e+1]!=Nil)
		PreTraverse(T,2*e+1);
	if (T[2*e+2]!=Nil)
		PreTraverse(T,2*e+2);
}

Status PreOrderTraverse(SqBiTree T)
{
	if (!BiTreeEmpty(T))
		PreTraverse(T,0);
	printf("\n");

	return 1;
}

//中序遍歷
void InTraverse(SqBiTree T, int e)
{
	if (T[2*e+1]!=Nil)
		InTraverse(T,2*e+1);

	Visit(T[e]);

	if (T[2*e+2]!=Nil)
		InTraverse(T,2*e+2);
}

Status InOrderTraverse(SqBiTree T)
{
	if (!BiTreeEmpty(T)){
		InTraverse(T,0);
	}
	printf("\n");
	return 1;
}

//後序遍歷
void PostTraverse(SqBiTree T,int e)
{
	if (T[2*e+1]!=Nil)
		PostTraverse(T,2*e+1);
	if (T[2*e+2]!=Nil)
		PostTraverse(T,2*e+2);
	Visit(T[e]);
}

Status PostOrderTraverse(SqBiTree T)
{
	if (!BiTreeEmpty(T)){
		PostTraverse(T,0);
	}
	printf("\n");
	return 1;
}

void LevelOrderTraverse(SqBiTree T)
{
	int i=MAX_TREE_SIZE-1,j;
	while (T[i]==Nil){
		i--;
	}

	for (j=0;j<=i;j++){
		if (T[j]!=Nil)
			Visit(T[j]);
	}

	printf("\n");
}

//逐層,按本層序號輸出二叉樹
void Print(SqBiTree T)
{
	int j,k;
	Position p;
	TElemType e;

	for (j=1;j<=BiTreeEmpty(T);j++){
		printf("第%d層: ",j);
		for (k=1;k<=powl(2,j-1);k++){
			p.level=j;
			p.order=k;
			e=Value(T,p);
			if (e!=Nil){
				printf("%d:%d  ",k,e);
			}
		}
		printf("\n");
	}

}

int main()
{
	Status i;
	Position p;
	TElemType e;
	SqBiTree T;
	InitBiTree(T);
	CreateBiTree(T);
	i=Root(T,&e);

	if (i){
		printf("根:",e);
	}

	else
		printf("樹空,無根\n");
	
	printf("層序遍歷\n");
	LevelOrderTraverse(T);
	printf("前序遍歷\n");
	PreOrderTraverse(T);

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

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

	printf("修改結點層號3,本層序號2:");
	p.level=3;
	p.order=2;

	e=Value(T,p);
	printf("原來%d,輸入新值50",e);
	e=50;
	Assign(T,p,e);

	printf("前序遍歷\n");
	PreOrderTraverse(T);

	return 0;
}