系列文章传送门:
数据结构与算法之树和二叉树(一):二叉树基本操作的实现及应用
数据结构与算法之线性表(二):链式表的实现和应用
数据结构与算法之线性表(三):顺序栈的实现和应用
数据结构与算法之线性表(四):链式栈的实现和应用
数据结构与算法之线性表(五):链式队列的实现和应用
数据结构与算法之线性表(六):顺序队列及循环队列的实现和应用
一.二叉树的基本操作实现
1.二叉树存储结构
二叉树可以用顺序表(完全二叉树比较适合)存储,也可以用链式结构(二叉链表)存储,其数据结构表示如下:
抽象出来就是这样:
2.二叉树遍历
二叉树遍历根据结点间遍历顺序可分为先序、中序、后序三种方式,
遍历有递归和非递归两种写法;如图为先序遍历的二叉树及其抽象树状图:
3.完全二叉树定义及其实现
以下为完全二叉树和其他二叉树的直观对比:
4.代码实现(所有代码均在Embarcadero DevC++6.0和VSCode 2021上编译运行通过):
#define ElementType char
#define Status int
#include<stdio.h>
#include<stdlib.h>
enum {TRUE=1, FALSE=0, ERROR=0, INFEASIBLE=-1, OVERFLOW=-2, OK=1};
typedef struct BiTNode{
ElementType data;
struct BiTNode *lchild;
struct BiTNode *rchild;
}BiTNode, *BiTree;
// InitTree(&T); CreateTree(&T,definition);
// ClearTree(&T); TreeEmpty(T);
// TreeDepth(T); Root(T);
// Value(T,cur_e); Assign(T, &cur_e, value);
// Parent(T, cur_e);
// LeftChild(T,cur_e);
// RightSibling(T,cur_e);
// InsertChild(&T,&p,i,c); DeleteChild(&T,&p,i);
// TraverseTree(T,visit());
// DestroyTree(&T)
BiTree count_k(BiTree &T, int &k) //前序遍历计数结点个数,返回该结点指针
{
if(!T || k<=0)
return NULL;
k--;
if(k==0)
return T;
//分别数左右孩子
if (count_k(T->lchild, k))
return count_k(T->lchild, k);
else
return count_k(T->rchild, k);
}
Status ValueLocate(BiTree T,int k, ElementType &e) //根据给定的值找对应的结点
{
BiTree p;
p = count_k(p,k);
if(p)
{
e = p->data;
return OK;
}
else
return ERROR;
}
int TreeDepth(BiTree T)
{
int depth1,depth2;
if(!T)
return FALSE;
depth1 = TreeDepth(T->lchild);
depth2 = TreeDepth(T->rchild);
return(depth1>depth2? depth1:depth2)+1;
}
Status TreeEmpty(BiTree T)
{
if (T==NULL)
return TRUE;
else
return FALSE;
}
Status InitTree(BiTree &T)
{
T = (BiTree)malloc(sizeof(BiTNode));
return OK;
}
Status delsubtree(BiTree T) //删除二叉树中所有以e为值的结点为根的子树
{
if(T)
{
delsubtree(T->lchild);
delsubtree(T->rchild);
free(T); //此删除仅仅释放空间
}
return OK;
}
Status DelTree(BiTree &T, ElementType e)
{
if(T)
{
if(T->data==e) //找到该删除的结点,把T及其子树空间释放
{
delsubtree(T);
T = NULL;
}
else
{
DelTree(T->lchild,e);
DelTree(T->rchild,e);
}
}
return OK;
}
Status DestroyTree(BiTree &T)
{
if(T)
{
delsubtree(T);
T = NULL;
DelTree(T->lchild,T->lchild->data);
DelTree(T->rchild,T->rchild->data);
}
return OK;
}
Status PreorderTraverse(BiTree T, Status (*visit)(ElementType)) //前序遍历二叉树
{
if(T)
{
if(visit(T->data))
if(PreorderTraverse(T->lchild, visit))
if(PreorderTraverse(T->rchild, visit))
return OK;
return ERROR;
}
else
return OK;
}
Status print(ElementType e)
{
printf("%c->",e);
return OK;
}
Status CreateTree(BiTree &T)
{
ElementType e;
scanf("%c",&e); //先序创建一棵二叉树,由指针T指向其根结点
if (e=='@')
T = NULL;
else
{
if(!(T= (BiTree)malloc(sizeof(BiTNode))))
exit(OVERFLOW);
T->data = e;
CreateTree(T->lchild);
CreateTree(T->rchild);
}
return OK;
}//CreateTree
int main()
{
//输入:ABD@@EF@H@@G@@C@@ (@表示空树),深度为5
BiTree T;
ElementType e;
InitTree(T);
CreateTree(T);
PreorderTraverse(T,print);
int depth = TreeDepth(T);
printf("二叉树深度:%d",depth);
if(!T)
printf("错误.\n");
ValueLocate(T,3,e);
printf("第3个结点的结果是:%c",e);
return 0;
}