数据结构——树与二叉树(二)

二叉树的基本操作和实现

顺序存储结构

顺序存储结构利用了满二叉树和完全二叉树的基本概念。

1.首先把要要存储的树补充为完全二叉树,然后对补充过的树中的每个结点按层次进行编号,

2.然后以各结点的编号作为该存储相应结点的数组下标,将各结点的值存储到一维数组中。

顺序存储的方式比较适合存储完全二叉树。经典例子:堆排序。


链式存储结构

二叉树的链式存储,通常分为两种:

1、二叉链表:每个结点中设置三个域,即数据域、左指针域和右指针域。

二叉树链表的结点结构可以描述为:

typedef struct node
{
	ElemType data;			/*数据域*/ 
	struct node *lchild;		/*指向左孩子结点的指针域*/
	struct node *rchild;		/*指向右孩子结点的指针域*/
}BstreeNode,*LinkBtree;

2、三叉链表:每个结点中设置四个域,即数据域、左指针域、右指针域和双亲指针域。

三叉树链表的结点结构可以描述为:

typedef struct node
{
	ElemType data;			/*数据域*/
	struct node *lchild;		/*指向左孩子结点的指针域*/ 
	struct node *rchild;		/*指向右孩子结点的指针域*/ 
	struct node *parent;		/*指向父亲结点的指针域*/ 
}BtreeNode,*LinkBtree;

二叉树的基本操作及代码实现:

#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <iostream>

using namespace std;

#define MaxSize 20
#define OK 1
#define Error -1
#define OverFlow -1
#define True 1
#define False 0
typedef char ElemType; 
typedef struct node
{
	ElemType data;				/*数据域*/ 
	struct node *lchild;			/*指向左孩子结点的指针域*/
	struct node *rchild;			/*指向右孩子结点的指针域*/
}BtreeNode,*LinkBtree;

/*建立二叉树*/
int Create_Btree(LinkBtree *Btree_pointer,int lo[],char ch[])
									/*lo数组中存储二叉树结点在完全二叉树的位置*/ \
									/*ch数组中存储二叉树的各个结点的数据*/
{
		int i,j;
		BtreeNode *newnode;
		LinkBtree p[MaxSize+1];		/*p数组为指针数组,辅助建立二叉树*/
		i = 1;
		while(lo[i] != 0 && ch[i] != '#'){			/*读取lo和ch数组中的值*/
			newnode = (BtreeNode *)malloc(sizeof(BtreeNode));		                /*申请结点空间*/
			if(newnode == NULL)
				return Error;	        /*申请失败*/
			newnode->data=ch[i];	        /*新结点赋值*/
			newnode->rchild=newnode->lchild = NULL;
			p[lo[i]] = newnode;		/*p数组记录新结点的指针*/ 
			if(lo[i] == 1)			/*若为树根*/
				*Btree_pointer = newnode;	/*为指向树根的指针赋值*/ 
			else{
				j = lo[i]/2;		/*寻找lo[i]的双亲结点的位置*/
				if(lo[i]%2 == 0)	/*插入结点的位置是偶数*/
					p[j]->lchild = newnode;	/*作为双亲的左孩子*/
				else
					p[j]->rchild = newnode;	/*作为双亲的右孩子*/
			}
			i++;					/*i++,处理下一个结点*/
		}
		return OK;
} 

/*前序遍历二叉树*/
void PreOrder(LinkBtree Bt_pointer)
{
	if(Bt_pointer != NULL){
		printf("%c",Bt_pointer->data);		/*访问根结点*/ 
		PreOrder(Bt_pointer->lchild);		/*前序遍历左子树*/
		PreOrder(Bt_pointer->rchild);		/*前序遍历右子树*/
	}	
} 

/*中序遍历二叉树*/
void InOrder(LinkBtree Bt_pointer)
{
	if(Bt_pointer != NULL){
		InOrder(Bt_pointer->lchild);		/*中序遍历左子树*/ 
		printf("%c",Bt_pointer->data);		/*访问根结点*/
		InOrder(Bt_pointer->rchild);		/*中序遍历右子树*/
	}	
}

/*后序遍历二叉树*/
void PostOrder(LinkBtree Bt_pointer)
{
	if(Bt_pointer != NULL){
		PostOrder(Bt_pointer->lchild);		/*后序遍历左子树*/ 
		PostOrder(Bt_pointer->rchild);		/*后序遍历右子树*/
		printf("%c",Bt_pointer->data);		/*访问根结点*/
	}	
} 

/*按层次遍历*/
void LevelOrder(BtreeNode *Bt)
{
	BtreeNode *q[MaxSize];					/*循环队列q中存放指针*/ 
	int Front = 0,Rear = 0;					/*定义队首位置和队尾位置,初始为空队*/
	BtreeNode *p;
	if(Bt != NULL){
		Rear = (Rear+1)%MaxSize;
		q[Rear] = Bt;					/*将树根的指针进队列*/
	}
	while(Front != Rear){					/*队列非空*/
		Front = (Front+1)%MaxSize;		/*使队首指针指向队首元素*/
		p=q[Front];					/*删除队首元素*/
		printf("%c",p->data);			/*输出队首元素所指结点的值*/
		if(p->lchild != NULL){		/*若存在左孩子,则左孩子结点指针进队*/ 
			Rear = (Rear+1)%MaxSize;
			q[Rear]  = p->lchild;
		} 
		if(p->rchild != NULL){		/*若存在右孩子,则右孩子结点指针进队*/
			Rear = (Rear+1)%MaxSize;
			q[Rear] = p->rchild;
		}
	}
}

/*在二叉树中查找值为x的结点*/
int LocaBtree(LinkBtree Bt_pointer,ElemType x)
{
		if(Bt_pointer != NULL){
			if(Bt_pointer->data == x)	/*根结点与所找元素相等*/ 			
				return True;			
			if(LocaBtree(Bt_pointer->lchild,x))	/*在左子树中查找*/
				return True;
			if(LocaBtree(Bt_pointer->rchild,x))	/*在右子树中查找*/
				return True; 			
		}
		else
			return False; 	
} 

/*输出树状二叉树*/
void ShowTree(LinkBtree Bt_pointer,int Layer)
{
	if(Bt_pointer != NULL){
		ShowTree(Bt_pointer->rchild,Layer+1);		/*输出树状左子树*/
		for(int i = 0; i < Layer; i++)			
			printf("	");
		printf("%c\n",Bt_pointer->data);		/*访问根结点*/
		ShowTree(Bt_pointer->lchild,Layer+1); 		/*输出树状右子树*/
	}	
} 

/*清空一颗二叉树*/ 
void ClearBtree(LinkBtree *Bt_pointer)
{
	LinkBtree p = *Bt_pointer;
	if(*Bt_pointer != NULL){
		ClearBtree(&(p->lchild));			/*删除左子树*/ 
		ClearBtree(&(p->rchild));			/*删除右子树*/
	        free(p);					/*释放根结点*/
		*Bt_pointer = NULL;				/*置根指针为空*/ 
	}	
} 

int main()
{
	LinkBtree Btree_p,p;
	int i;
	int lo[MaxSize]={9999,};
	char ch[MaxSize]={'!',};
	/*输入结点数据*/
	for(i=1;i<=MaxSize;i++){
		scanf("%d %c",&lo[i],&ch[i]);
		if(lo[i]==0 && ch[i]=='#')
			break;
	} 
	/*建立一颗二叉树*/
	if(Create_Btree(&Btree_p,lo,ch) == OK){
		printf("\n前序遍历结果是:");		
		PreOrder(Btree_p);				/*调用前序遍历算法*/
		printf("\n中序遍历结果是:");
		InOrder(Btree_p);				/*调用中序遍历算法*/
		printf("\n后序遍历结果是:");
		PostOrder(Btree_p);				/*调用后序遍历算法*/
		printf("\n层次遍历结果是:");
		LevelOrder(Btree_p);	 
		printf("\n-------------------------------");
		printf("\n树状二叉树为:\n");
		ShowTree(Btree_p,1);
		for(i = 0; i <= 9; i++){
			if(LocaBtree(Btree_p,'A'+i) == True)
				printf("\nFound!");
			else
				printf("\nNot found!");
		}
		ClearBtree(&Btree_p);
		if(Btree_p == NULL)
			printf("\nSucced Detele!"); 
	}
	return 0; 
}

 


发布了22 篇原创文章 · 获赞 14 · 访问量 1190

猜你喜欢

转载自blog.csdn.net/weixin_44157233/article/details/98584382