8--二叉树遍历

1.先(根)序遍历的 递归算法定义:
若二叉树非空,则依次执行如下操作:
⑴ 访问根结点;
⑵ 遍历左子树;
⑶ 遍历右子树。
2.中(根)序遍历的递归算法定义:
若二叉树非空,则依次执行如下操作:
⑴遍历左子树;
⑵访问根结点;
⑶遍历右子树。
3.后(根)序遍历得递归算法定义:
若二叉树非空,则依次执行如下操作:
⑴遍历左子树;
⑵遍历右子树;
⑶访问根结点。

<span style="font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: rgb(255, 255, 255);">
</span>

typedef struct node{
   int  data; 
   struct node *lchild,*rchild;
} NODE;
NODE *root; 

先序遍历:

DLR(NODE *root )
{  
    if (root) //非空二叉树
    {
        printf(“%d”,root->data); //访问D
        DLR(root->lchild); //递归遍历左子树
        DLR(root->rchild); //递归遍历右子树
    }
}

中序遍历:

LDR(NODE *root)
{ 
  if(root !=NULL)
  {  
      LDR(root->lchild);
      printf(“%d”,root->data);
      LDR(root->rchild); 
  }
}
 
后序遍历:

LRD (NODE *root)
{
   if(root !=NULL) 
   {
     LRD(root->lchild);
     LRD(root->rchild);
     printf(“%d”,root->data); 
   } 
}

通过中序遍历和先序遍历可以确定一个树

通过中序遍历和后续遍历可以确定一个

通过先序遍历和后序遍历确定不了一个数。

利用先序遍历来建树(结点值陆续从键盘输入,用DLR为宜)

Bintree createBTpre( )
{      Bintree T; char ch;
        scanf(“%c”,&ch);
        if(ch==’#’) T=NULL; 
        else
        {   T=( Bintree )malloc(sizeof(BinTNode));
            T->data=ch;
            T->lchild=createBTpre(); 
            T->rchild=createBTpre();
        }        
        return T;
}

中序遍历非递归算法

分析1:什么时候访问根、什么时候访问左子树、什么访问右子树

       当左子树为空或者左子树已经访问完毕以后,再访问根

       访问完毕根以后,再访问右子树。

分析2:为什么是栈,而不是其他队列。

        先走到的后访问、后走到的先访问,显然是栈结构

分析3:结点所有路径情况

步骤1:结点的所有路径情况

如果结点有左子树,该结点入栈;

如果结点没有左子树,访问该结点;

分析3:路径所有情况

如果结点有右子树,重复步骤1

如果结点没有右子树(结点访问完毕),回退,让栈顶元素出栈,访问栈顶元素,并访问右子树,重复步骤1

如果栈为空,表示遍历结束。

注意:入栈的结点表示,本身没有被访问过,同时右子树也没有被访问过。

分析4:有一个一直往左走入栈的操作

#include "iostream"
#include "stack"
using namespace std;
//二叉链表
typedef struct BiTNode
{
 int data;
 struct BiTNode *lchild, *rchild; //左孩子 右孩子
}BiTNode,*BiTree;
/*
      1
 2     3
  4      5
 */
BiTNode *GoFarLeft(BiTNode *T, stack<BiTNode *> &s)
{
 if (T == NULL)
 {
  return NULL;
 }
 //如果T有左孩子 入栈
 while (T->lchild)
 {
  s.push(T);
  T= T->lchild;//一直往左走
 }
 return T; //找到一个没有左孩子的节点,就是中序遍历的起点
}
void InOrder2(BiTNode *T)
{
 stack<BiTNode *>s;
 BiTNode *t = GoFarLeft(T, s); //中序遍历的起点
 while(t)
 {
  printf("%d ", t->data);
  if (t->rchild) //如果有右孩子 重复12步骤
  {
    t = GoFarLeft(T->rchild, s);
  }
  else if (!s.empty())  //如果没有右孩子,说明该节点的树放完毕,需要返回。
  {
   t  = s.top(); //非空就从栈顶拿元素
   s.pop();
  }
  else //如果没有右孩子,并且栈为空 t = NULL;
  {
   t = NULL;
  }
 }
}
void main()
{
 BiTNode b1, b2, b3, b4, b5;
 BiTNode *pNewTree = NULL;
 memset(&b1, 0, sizeof(BiTNode));
 memset(&b2, 0, sizeof(BiTNode));
 memset(&b3, 0, sizeof(BiTNode));
 memset(&b4, 0, sizeof(BiTNode));
 memset(&b5, 0, sizeof(BiTNode));
 b1.data = 1;
 b2.data = 2;
 b3.data = 3;
 b4.data = 4;
 b5.data = 5;
 //构建树关系
 b1.lchild = &b2;
 b1.rchild = &b3;
 b2.lchild = &b4;
 b3.lchild = &b5;
 InOrder2(&b1);
 system("pause");
}
 二叉树编程:
#include "stdlib.h"
#include "stdio.h"
#include "string.h"
//二叉链表
typedef struct BiTNode
{
 int data;
 struct BiTNode *lchild, *rchild; //左孩子 右孩子
}BiTNode, *BiTree;
//三叉链表
typedef struct TriTNode
{
 int data;
 //左右孩子指针
 struct TriTNode *lchild, *rchild;
 struct TriTNode *parent;
}TriTNode, *TriTree;
//双亲链表
#define MAX_TREE_SIZE 100
typedef struct BPTNode
{
 int data;
 int *parent; //指向双亲的指针
 char LRTag; //左右孩子标志域
}BPTNode;
typedef struct BPTree
{
 BPTNode nodes[MAX_TREE_SIZE]; //因为节点之间是分散的,需要把节点存储到数组中
 int num_node;  //节点数目
 int root; //根结点的位置 //注意此域存储的是父亲节点在数组的下标
}BPTree;
void PreOrder(BiTNode *T)
{
 if (T != NULL)
 {
  printf("%d ", T->data);
  PreOrder(T->lchild);
  PreOrder(T->rchild);
 }
}
void InOrder(BiTNode *T)
{
 if (T != NULL)
 {
  InOrder(T->lchild);
  printf("%d ", T->data);
  InOrder(T->rchild);
 }
}
void PostOrder(BiTNode *T)
{
 if (T != NULL)
 {
  PostOrder(T->lchild);
  PostOrder(T->rchild);
  printf("%d ", T->data);
 }
}
/*
1
2     3
4      5
*/
//1 遍历算法 3种
//2
int g_count = 0;
void CountLeaf(BiTNode *T) //先根
{
 if (T != NULL)
 {
  CountLeaf(T->lchild);
  CountLeaf(T->rchild);
  if (T->lchild == NULL && T->rchild == NULL)
  {
   g_count++;
  }
 }
}
void CountLeaf2(BiTNode *T, int *ncount) //先根
{
 if (T != NULL)
 {
  CountLeaf2(T->lchild, ncount);
  CountLeaf2(T->rchild, ncount);
  if (T->lchild == NULL && T->rchild == NULL)
  {
   (*ncount)++;
  }
 }
}
//求树的深度
int depth(BiTNode *node){
 int depthval = 0, depthL = 0, depthR = 0;
 if (node == NULL){
  depthval = 0;
  return depthval;
 }
 depthL = depth(node->lchild);
 depthR = depth(node->rchild);
 depthval = 1 + ((depthL > depthR) ? depthL:depthR);
 return depthval;
}
//拷贝树
BiTNode* copyTree(BiTNode *t){
 if (t == NULL){
  return NULL;
 }
 BiTNode *newNode = NULL, *newLptr=NULL,*newRptr=NULL;
 if (t->lchild != NULL){
  newLptr = copyTree(t->lchild);
 }
 if (t->rchild != NULL){
  newRptr = copyTree(t->rchild);
 }
 newNode = (BiTNode *)malloc(sizeof(BiTNode));
 newNode->lchild = newLptr;
 newNode->rchild = newRptr;
 newNode->data = t->data;
}
void main()
{
 BiTNode b1, b2, b3, b4, b5;
 memset(&b1, 0, sizeof(BiTNode));
 memset(&b2, 0, sizeof(BiTNode));
 memset(&b3, 0, sizeof(BiTNode));
 memset(&b4, 0, sizeof(BiTNode));
 memset(&b5, 0, sizeof(BiTNode));
 b1.data = 1;
 b2.data = 2;
 b3.data = 3;
 b4.data = 4;
 b5.data = 5;
 //构建树关系
 b1.lchild = &b2;
 b1.rchild = &b3;
 b2.lchild = &b4;
 b3.lchild = &b5;
 printf("\n先根遍历");
 PreOrder(&b1);
 printf("\n中根遍历");
 InOrder(&b1);
 printf("\n后根遍历");
 PostOrder(&b1);
 {
  int ncoutn = 0;
  CountLeaf2(&b1, &ncoutn);
  printf("\n叶子结点个数:%d\n", ncoutn);
 }
 int dep = depth(&b1);
 printf("树的深度:%d \n", dep);
 BiTree *bt = copyTree(&b1);
 PreOrder(bt);
 system("pause");
}



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值