二叉树的基本操作和实现
顺序存储结构
顺序存储结构利用了满二叉树和完全二叉树的基本概念。
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;
}