目录
一、*遍历二叉树
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、LDR、LRD、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域指示结点的后继

 
 
例

增设头结点
 



















