遍历二叉树和线索二叉树

  • 遍历定义:顺着一条搜索路径巡防二叉树中的结点,使得每个结点均被访问一次,而且仅被访问一次
  • 遍历目的:得到树中所有结点的一个线性排序
  • 遍历用途:它是树结构插入,删除,修改,查找和排序运算的前提,是二叉树一切运算的基础和核心
  • 遍历方法:
先序遍历二叉树中序遍历二叉树后序遍历二叉树

若二叉树为空,则空操作;

否则:

1.访问根节点;

2.先序遍历左子树;

3.先序遍历右子树;

若二叉树为空,则空操作;

否则:

1.中序遍历左子树;

2.访问根节点

3.中序遍历右子树;

若二叉树为空,则空操作;

否则:

1.后序遍历左子树;

2.后序遍历右子树;

3.访问根节点。

 先序遍历二叉树的操作定义:

中序遍历二叉树的操作定义:

 后序遍历二叉树的操作定义:

遍历的算法实现-先序遍历:

Status PreOrderTraverse(BiTree T){
  if(T==NULL) return OK;
else{
   visit(T);//访问根节点
   PreOrderTraverse(T->lchild);//递归遍历左子树
   PreOrderTraverse(T->rchild);//递归遍历右子树
}
}

遍历的算法实现-中序遍历:

Status InOrderTraverse(BiTree T){
 if(T==NULL) return OK;//空二叉树
else{
 InOrderTraverse(T->lchild);//递归遍历左子树
visit(T);//访问根节点
InOrderTraverse(T->rchild);//递归遍历右子树
}
}

遍历的算法实现-后序遍历:

Status InOrderTraverse(BiTree T){
 if(T==NULL) return OK;//空二叉树
else{
 InOrderTraverse(T->lchild);//递归遍历左子树
InOrderTraverse(T->rchild);//递归遍历右子树
visit(T);//访问根节点
}
}

 遍历算法的分析:

  • 时间效率:n  //每个结点只访问一次
  • 空间效率: n  // 栈占用的最大辅助空间

 遍历二叉树的非递归算法:

中序遍历非递归算法:

  二叉树中序遍历的非递归算法的关键:在中序遍历过某结点的整个左子树后,如何找到该结点的根以及右子树

基本思想:

  1. 建立一个栈
  2. 根结点进栈,遍历左子树
  3. 根结点出栈,输出根节点,遍历右子树
Status InOrderTraverse(BiTree T){
BiTree p; InitStack(S); p=T;
while(p||StackEmpty(S)){
 if(p){
   Push(S,p);p=p->lchild;
}else{
   Pop(S,q); printf("%c",q->data);
   p=q->rchild;
}
}
return OK;
  
}

二叉树的层次遍历:

算法设计思路:使用一个队列

  • 将根结点进队;
  • 队不空时循环:从队列中出列一个结点*p,访问它;
  1.  若它有左孩子结点,将左孩子结点进队;
  2. 若他有右孩子结点,将右孩子进队。

 队列类型定义格式:

typedef struct{
 BTNode data[MaxSiize];//存放队中元素
 int front,rear;//队头和队尾指针
}SqQueue;//顺序循环队列的类型

二叉树层次遍历算法:

void LevelOrder(BTNode *b){
 BTNode *p; SqQueue *qu;
 InitQueue(qu);// 初始化队列
 enQueue(qu,b); // 根节点指针进入队列
 while(!QueueEmpty(qu)){//队不为空,则循环
  deWueue(qu,p)//出队结点p
  printf("%c",p->data);//访问结点p
  if(p->lchild!=NULL) enQueue(qu,p->lchild);// 有左孩子时将其进队
  if(p->rchild!=NULL) enQueue(qu,p->rchild);// 有右孩子时将其进队
  
}
}

 二叉树遍历算法的应用---复制二叉树:

 设计思路:

  • 如果是空树,递归结束
  • 否则,申请新结点空间,复制根节点
  1. 递归复制左子树
  2. 递归复制右子树

int Copy(BiTree T,BiTree &NewT){
 if(T==NULL){//如果是空树返回0
 NewT=NULL; return 0;
}else{
 NewT = new BiTNode;
 NewT->data=T->data;
 Copt(T-lChild, NewT->lchild);
 Copt(T-rChild, NewT->rchild);
}
}

二叉树遍历算法的应用---计算二叉树的深度:

算法思路:

  • 如果是空树,则深度为0;
  • 否则,递归计算左子树的深度记为m,递归计算右子树的深度记为n,二叉树的深度则为m与n的较大者加1
int Depth(BiTree T){
 if(T==NULL) return 0//如果是空树返回0
else{
  m=Depth(T->lChild);
  n=Depth(T->rChild);
if(m>n) return (m+1);
else return (n+1);
  } 
}

 二叉树遍历算法的应用---计算二叉树结点总数:

算法思路:

  • 如果是空树,则结点个数为0
  • 否则,结点个数为左子树的结点个数+右子树的结点个数+1
int NodeCount(BiTree T){
 if(T==NULL) return 0;
  else return NodeCount(T->lchild)+NodeCount(T->rchild)+1;
}

二叉树遍历算法的应用---计算二叉树叶子结点数(补充):

算法思路:

  • 如果是空树,则叶子结点个数为0;
  • 否则,为左子树的叶子结点个数+右子树的叶子结点个数;
int LeadCount(BiTree T){
if(T==NULL)//如果是空树返回0
 return 0;
if(T->lchild==NULL&&T->rchild==NULL)
  return 1;//如果是叶子结点返回1
else 
   return LeafCount(T->lchild)+LeafCount(T->rchild);
}

线索二叉树:

利用二叉链表中的空指针域:

  如果某个结点的左孩子为空,则将空的左孩子指针域改为指向其前驱;如果某结点的右孩子为空,则将空的右孩子指针域改为指向其后继——这种改变指向的指针成为线索

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值