二叉树的存储结构
顺序存储:使用数组存储二叉树,根据下标依次确定每个结点数值
最适合完全二叉树,一般二叉树会浪费大量空间
链式存储:
trpedef struct BTNode
{
char data;
struct BTNode *lchilde;
struct BTNode *rchild;
}
二叉树的遍历算法
先序遍历
void preorder(BTNode *p)
{
if(p!=NULL)
{
Visit(p); // 访问p结点的函数,比如打印p对应数值
preorder(p->lchild); // 先序遍历左子树
preorder(p->rchild); // 先序遍历右子树
}
}
中序遍历
void inorder(BTNode *p)
{
if(p!=NULL)
{
inorder(p->lchild);
Visit(p);
inorder(p->rchild);
}
}
后序遍历
void postorder(BTNode *p)
{
if(p!=NULL)
{
postorder(p->lchild);
postorder(p->rchild);
Visit(p);
}
}
二叉树的深度
int getDepth(BTNode *p)
{
int LD,RD; // 左子树深度,右子树深度
if(p==NULL)
return 0;
else
{
LD=getDepth(p->lchild);
RD=getDepth(p->rchild);
return (LD>RD?LD:RD) + 1; // 取较高的子树并加1
}
}
查找结点
查找data域值等于key的结点是否存在,若存在,将q指向该结点,否则q赋值NULL
// 先序遍历,假设二叉树已存在且p指向其根节点
void search(BTNode *p, BTNode *&q, int key) // 将q定义为引用型指针,因为q要改变
{
if(p!=NULL)
{
if(p->data==key)
q=p;
else
{
search(p->lchild, q, key);
search(p->rchild, q, key);
}
}
}
改进: 若在左子树找到满足条件结点,无须继续查找右子树,直接退出本层递归
void search(BTNode *p, BTNode *&q, int key)
{
if(p!=NULL)
{
if(p->data==key)
q=p;
else
{
search(p->lchild, q, key);
if(q==NULL)
search(p->rchild, q, key);
}
}
}
输出先序遍历序列中第k个结点的值
int n=0; // 计结点数
void trave(BTNode *p, int k)
{
if(p!=NULL)
{
++n;
if(k==n)
{
cout<<p->data<<endl; // c++ 输出p->data这个变量加换行,同 printf("%s\n",p->data);
return;
}
trave(p->lchild, k);
trave(p->rchild, k);
}
}
层次遍历
思想:应用循环队列,先将头节点入队,然后出队,访问该结点并将左右子树根节点入队,反复直到队列为空为止
void level(BTNode *p)
{
int front,rear;// 循环队列首位结点
BTNode *que[maxsize];// 定义循环队列
front=rear=0; // 初始化队列
BTNode *q; // 定义q结点用来访问出队结点
if(p!=NULL)
{
rear=(rear+1)%maxsize;
que[rear]=p; // 头指针入队
while(front!=rear) // 循环条件:队列不为空
{
front=(front+1)%maxsize;
q=que[front]; // 队列头节点出队
Visit(q);
if(q->lchild!=NULL) // 若出队结点有左孩子,则入队
{
rear=(rear+1)%maxsize;
que[rear]=q->lchild;
}
if(q->rchild!=NULL) // 若出队结点有右孩子,则入队
{
rear=(rear+1)%maxsize;
que[rear]=q->rchild;
}
}
}
}
求二叉树宽度
具有结点数最多的那一层的结点数
typedef struct{
BTNode *p;
int lno;
}St;
int maxNode(BTNode *b)
{
st que[maxsize]; // 定义一个队列
int front,rear; // 首位指针
int Lno=0,i,j,max=0; // Lno结点所在层数
front=rear=0; // 初始化队列
BTNode *q; // 定义结点q,用来读取出队结点的左右孩子
if(b!=NULL)
{
++rear; // 根节点入队
que[rear].p=b;
que[rear].lno=1;
while(front!=rear) // 层次遍历循环条件
{
++front;
q=que[front].p;
lno=que[front].lno; // 头节点出队
if(q->lchild!=NULL) // 左孩子入队
{
++rear;
que[rear].p=q->lchild;
que[rear].lno=Lno+1; // 根据根节点确定孩子结点所在层数
}
if(q->rchild!=NULL) // 右孩子入队
{
++rear;
que[rear].p=q->rchild;
que[rear].lno=Lno+1;
}
} // 循环结束,Lno保存二叉树的最大层数
max=0; // 寻找最多元素层的元素个数
for(i=1;i<=Lno;++i) //Lno层
{
n=0;
for(j=;j<rear;++j) // 遍历第i层元素在队列中的个数
if(que[j].lno==i)
++n;
if(max<n)
max=n;
}
return max;
}
else return 0;
}