树是一种非线性的数据结构。
结点的度:结点拥有子树个数或者分支的个数。
树的度:树中个结点度的最大值。
二叉树是对树加上两个限制条件
1.每个结点最多只有两颗子树,即二叉树中结点的度只能为0,1,2.
2.子树有左右顺序之分,不能颠倒
二叉树的两种存储结构
顺序存储结构
对于完全二叉树,从0开始编号
父结点位置为i;
左孩子结点位置为2i+1;
右孩子结点位置为2i+2;
链式存储结构
typedef struct BTnode
{
int data;
struct BTnode *lchild;
struct BTnode *rchild;
}BTnode;
二叉树的遍历
1.先序遍历,第一次来到某个结点时访问,所得序列为先序遍历序列
2.中序遍历,第二次来到某个结点时访问,所得序列为先序遍历序列
3.后序遍历,第三次来到某个结点时访问,所得序列为先序遍历序列
树的遍历只有先序遍历和后序遍历
如果将一棵树转变为二叉树,那么树的先序遍历等于二叉树的先序遍历,树的后序遍历等于二叉树的中序遍历
void preorder(BTnode *p)
{
if(*p!=NULL)
{
(1)//visit(p),先序遍历
preorder(p->lchild);
(2)//visit(p),中序遍历
preorder(p->rchild);
(3)//visit(p),后序遍历
}
}
二叉树的非递归遍历
先序遍历
void preorder(BTnode *bt)
{
if(bt!=NULL)
{
BTnode *stack[maxsize];
int top=-1;
BTnode *p=NULL;
stack[++top]=bt;
while(top!=-1)
{
p=stack[top--];
visit(p);
if(p->rchild!=NULL);
stack[++top]=p->rchild;
if(p->lchild!=NULL);
stack[++top]=p->lchild;
}
}
}
中序遍历
void inpreorder(BTnode *bt)
{
if(bt!=NULL)
{
BTnode *stack[maxsize];
int top=-1;
BTnode *p=NULL;
p=bt;
while(top!=-1||p!=NULL)
{
while(p!=NULL)
{
stack[++top]=p;
p=p->lchild;
}
if(top!=NULL)
{
p=stack[top--];
visit(p);
p=p->rchild;
}
}
}
}
后序遍历
void preorder(BTnode *bt)
{
if(bt!=NULL)
{
BTnode *stack[maxsize];
BTnode *stack2[maxsize];
int top1=-1;
int top2=-1;
BTnode *p=NULL;
stack[++top]=bt;
while(top1!=-1)
{
p=stack1[top1--];
stack2[++top]=p;
if(p->lchild!=NULL);
stack1[++top1]=p->lchild;
if(p->rchild!=NULL);
stack1[++top1]=p->rchild;
}
while(top2!=-1)
{
p=stack2[top2--];
visit(p);
}
}
}
二叉树的层次遍历
void level(BTnode *bt)
{
if(bt!=NULL)
{
int front,rear;
BTnode *que[maxsize];//定义一个循环队列
front=rear=0;
BTnode *p;
rear=(rear+1)%maxsize;
que[rear]=bt;//根节点入队
while(front!=rear)//当队列不空的时候进行循环
{
front=(front+1)%maxsize;
p=que[front];//队头结点出队
visit(p);//访问队头结点
if(p->lchild!=NULL)//如果左子树不空,则左子树的根节点入队
{
rear=(rear+1)%maxsize;
que[rear]=p->lchild;
}
if(p->rchild!=NULL)//如果右子树不空,则右子树的根节点入队
{
rear=(rear+1)%maxsize;
que[rear]=p->rchild;
}
}
}
}
树的考点
线索二叉树
结点定义
typedef struct TBTnode
{
int data;
int ltag,rlag;
struct TBTnode *lchild;
struct TBTnode *rchild;
}TBTnode;
前序线索二叉树
void prethread(TBTnode *p,TBTnode *&pre)
{
if(p!=NULL)
{
if(p->lchild==NULL)
{
p->lchild=pre;
p->ltag=1;
}
if(pre!=NULL&&pre->rchild=NULL)
{
pre->rchild=p;
pre->rtag=1;
}
pre=p;
if(p->ltag==0)
prethead(p->lchild,pre);
if(p->rtag==0)
prethead(p->rchild,pre);
}
}
对前序二叉树的遍历
void preorder(TBTnode *bt)
{
if(bt!=NULL)
{
TBTnode *p=bt;
while(p!=NULL)
{
while(p->ltag==0)
{
visit(p);
p=p->lchild;
}
visit(p);
p=p->rchild;
}
}
}
重点:中序线索二叉树
void prethread(TBTnode *p,TBTnode *&pre)
{
if(p!=NULL)
{
prethead(p->lchild,pre);
if(p->lchild==NULL)
{
p->lchild=pre;
p->ltag=1;
}
if(pre!=NULL&&pre->rchild=NULL)
{
pre->rchild=p;
pre->rtag=1;
}
pre=p;
prethead(p->rchild,pre);
}
}