遍历二叉树和线索二叉树

目录

一、*遍历二叉树

1.1遍历定义

1.2遍历目的

1.3遍历用途

1.4遍历方法

1.4.1先序遍历(DLR)

1.4.2中序遍历(LDR)

1.4.3后序遍历(LRD)

1.5根据遍历序列确定二叉树

1.6遍历算法的实现

1.6.1先序遍历算法的实现

1.6.2中序遍历算法的实现

1.6.3后序遍历算法的实现

1.6.4中序遍历的非递归算法

1.6.5二叉树的层次遍历

1.7二叉树遍历算法的应用

1.7.1按先序遍历建立二叉树的二叉链表

1.7.2复制二叉树

 1.7.3计算二叉树深度

1.7.4计算二叉树结点总数

1.7.5计算二叉树叶子数

二、线索二叉树

2.1线索

2.2线索二叉树的存储结构


一、*遍历二叉树

1.1遍历定义

顺着某一条搜索路径巡防二叉树中的结点,使得每个结点均被访问一次,而且仅被访问一次(周游)

1.2遍历目的

得到树中所有结点的一个线性排列

1.3遍历用途

是树结构插入、删除、修改、查找和排序运算的前提

1.4遍历方法

依次遍历二叉树中的根结点、左子树和右子树,共有6种方案:

DLR、DRL、LDRLRD、RDL、RLD

若规定先左后右,则DLR(先序遍历)、LDR(中序遍历)、LRD(后序遍历)

1.4.1先序遍历(DLR)

 

1.4.2中序遍历(LDR)

1.4.3后序遍历(LRD)

 

练习 ①

 练习②

1.5根据遍历序列确定二叉树

由二叉树的先序序列和中序序列、后序序列和中序序列可以确定唯一一棵二叉树

①先序和中序例:

 ②后序和中序例:

1.6遍历算法的实现

1.6.1先序遍历算法的实现
Status PreOrderTraverse(BiTree T){
  if(T==NULL) return OK;  //空二叉树
  else{
     visit(T);            //访问根结点
     PreOrderTraverse(T->lchild);  //递归遍历左子树
     PreOrderTraverse(T->rchild);  //递归遍历右子树
  }
}
     
1.6.2中序遍历算法的实现
Status InOrderTraverse(BiTree T){
  if(T==NULL) return OK;  //空二叉树
  else{
     InOrderTraverse(T->lchild); //递归遍历左子树
     visit(T);            //访问根结点
     InOrderTraverse(T->rchild); //递归遍历右子树
  }
}
1.6.3后序遍历算法的实现
Status PostOrderTraverse(BiTree T){
  if(T==NULL) return OK; //空二叉树
  else{
     PostOrserTraverse(T->lchild); //递归遍历左子树
     PostOrderTraversr(T->rchild); //递归遍历右子树
     visit(T); //访问根结点
  }
}

时间和空间复杂度均为O(n)

1.6.4中序遍历的非递归算法

(用栈来实现:后进先出)

基本思想:①建立一个栈;②根结点进栈,遍历左子树;③根结点出栈,输出根结点,遍历右子树

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;}
    };//while
  return OK;
}
  
1.6.5二叉树的层次遍历

对于一棵二叉树,从根结点开始,按从上到下、从左到右的顺序访问每一个结点,每一个结点仅访问一次。

(用队列来实现)

基本思想:①将根结点进队;②队不空时循环:从队列中出列一个结点*p,访问它:若它有左孩子结点,将左孩子结点进队;若它有右孩子结点,将右孩子结点进队。

void LevelOrder(BTNode *b){
     BTNode *p;  SqQueue *qu;
     InitQueue(qu);   //初始化队列
     enQueue(qu,b);   //根结点指针进入队列
     while(!QueueEmpty(qu)) { //队不为空,循环
       deQueue(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.7二叉树遍历算法的应用

1.7.1按先序遍历建立二叉树的二叉链表

 

1.7.2复制二叉树

 

 1.7.3计算二叉树深度

 

1.7.4计算二叉树结点总数

1.7.5计算二叉树叶子数

二、线索二叉树

2.1线索

改变指向的指针:若某个结点的左孩子为空,则将空的左孩子指针域改为指向其前驱;若某结点的右孩子为空,则将空的右孩子指针域改为指向其后继

2.2线索二叉树的存储结构

 Ltag=0 ——>lchild域指示结点的左孩子

 Ltag=1 ——>lchild域指示结点的前驱

 Rtag=0 ——>rchild域指示结点的右孩子

 Rtag=1 ——>rchild域指示结点的后继

 

 

增设头结点

 

  • 17
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值