C++ 遍历二叉树实例详解

C++ 遍历二叉树实例详解

2叉数又叫红黑树,关于2叉数的遍历问题,有很多,一般有三种常用遍历方法:

(1)前序遍历(2)中序遍历(3)后续遍历

以下是经典示例:

#include "stdafx.h" 

#include<stdio.h>
#include<malloc.h>
#include <math.h >
#define MaxSize 20 

typedef struct BiTNode
{
 int data;
 struct BiTNode *lchild, *rchild;
}BiTNode,*BiTree; 

//建立二叉树
void CreateBiTree(BiTree *T)
{
 char ch;
 scanf("%c",&ch);
 getchar();
 if(ch==' ')
 {
  printf("不产生子树。\n");
  *T=NULL;
 }
 else
 {
  if(!(*T=(BiTNode *)malloc(sizeof(BiTNode))))
  {
   printf("分配空间失败");
   return;
  }//生成一个新节点
  (*T)->data = ch;
  printf("产生左右子树。\n");
  CreateBiTree(&(*T)->lchild);
  CreateBiTree(&(*T)->rchild);
 }
} 

//递归前序遍历
void Preorder(BiTNode *T)
{
 if(T)
 {
  printf("%c ",T->data);
  Preorder(T->lchild);
  Preorder(T->rchild);
 }
} 

//递归中序遍历
void Inorder(BiTNode *T)
{
 if(T)
 {
  Inorder(T->lchild);
  printf("%c ",T->data);
  Inorder(T->rchild);
 }
} 

//递归后序遍历
void Postorder(BiTNode *T)
{
 if(T)
 {
  Postorder(T->lchild);
  Postorder(T->rchild);
  printf("%c ",T->data);
 }
} 

//非递归前序遍历
void NPreorder(BiTNode *T)
{
 BiTNode *stack[MaxSize],*p;
 int top=-1;
 if(T)
 {
  top++;
  stack[top]=T;     //根节点进栈
  while(top>-1)     //栈不为空时循环
  {
   p=stack[top];    //退栈并访问该节点
   top--;
   printf("%c ",p->data);
   if(p->rchild)    //右孩子进栈
   {
    top++;
    stack[top]=p->rchild;
   }
   if(p->lchild)    //左孩子进栈
   {
    top++;
    stack[top]=p->lchild;
   }
  }
 }
} 

//非递归中序遍历
void NInorder(BiTNode *T)
{
 BiTNode *stack[MaxSize],*p;
 int top=-1;
 p=T;
 while(p||top!=-1)
 {
  if(p)
  {
   top++;
   stack[top]=p;
   p=p->lchild;
  }        //根节点进栈,遍历左子树
  else       //根节点退栈,访问根节点,遍历右子树
  {
   p=stack[top];
   top--;
   printf("%c ",p->data);
   p=p->rchild;
  }
 }
} 

//非递归后序遍历
void NPostorder(BiTNode *T)
{
 BiTNode *stack[MaxSize],*p;
 int flag,top=-1;
 do
 {
  while(T)
  {
   top++;
   stack[top]=T;
   T=T->lchild;
  }        //所有左节点进栈
  p=NULL;      //p总是指向当前节点的前一个已经访问过的节点
  flag=1;      //flag为1表示当前节点已经访问过了
  while(top!=-1 && flag)
  {
   T=stack[top];
   if(T->rchild==p)   //右子树不存在或者已经被访问过时
   {
    printf("%c ",T->data);
    top--;
    p=T;     //调整p指针
   }
   else
   {
    T=T->rchild;
    flag=0;    //调整访问标志
   }
  }
 } while(top!=-1);
} 

//层次遍历二叉树
void Translever(BiTNode *T)
{
 struct node
 {
  BiTNode *vec[MaxSize];
  int f,r;    //r为队尾,f为队头
 }queue;
 BiTNode *p;
 p=T;
 queue.f=0;
 queue.r=0;
 if(T)
  printf("%c ", p->data);
 queue.vec[queue.r]=p;
 queue.r=queue.r+1;
 while(queue.f<queue.r)
 {
  p=queue.vec[queue.f];
  queue.f=queue.f+1;
  if(p->lchild)
  {
   printf("%c ",p->lchild->data);
   queue.vec[queue.r]=p->lchild;
   queue.r=queue.r+1;
  }
  if(p->rchild)
  {
   printf("%c ",p->rchild->data);
   queue.vec[queue.r]=p->rchild;
   queue.r=queue.r+1;
  }
 }
 printf("\n");
} 

//求二叉树的深度
int Depth(BiTNode *T)
{
 int dep1,dep2;
 if(T==NULL)
  return(0);
 else
 {
  dep1=Depth(T->lchild);
  dep2=Depth(T->rchild);
  if(dep1>dep2)
   return(dep1+1);
  else
   return(dep2+1);
 }
} 

//输出二叉树
void Disptree(BiTNode *T)
{
 if(T)
 {
  printf("%c",T->data);
  if(T->lchild || T->rchild)
  {
   printf("(");
   Disptree(T->lchild);
   if(T->rchild)
    printf(",");
   Disptree(T->rchild);
   printf(")");
  }
 }
}

main.cpp

void main()
{
 BiTree T=NULL;
 char j;
 int sign = 1; 

 printf("本程序可以进行建立二叉树、递归与非递归先序、中序、后序遍历二叉树、层次遍历二叉树、输出二叉树的扩展序列的操作。\n");
 printf("请将二叉树的先序序列输入以建立二叉树,叶子节点用空格代替。\n");
 printf("您必须一个一个地输入字符。\n");
 while(sign)
 {
  printf("请选择: \n");
  printf("0.生成二叉树         1.求二叉树的深度\n");
  printf("2.递归先序遍历        3.非递归先序遍历\n");
  printf("4.递归中序遍历        5.非递归中序遍历\n");
  printf("6.递归后序遍历        7.非递归后序遍历\n");
  printf("8.层次遍历         9.输出二叉树的广义表形式\n");
  printf("q.退出程序\n");
  scanf("%c",&j);
  getchar();
  switch(j)
  {
  case '0':
   printf("生成二叉树:");
   CreateBiTree(&T);
   printf("\n");
   printf("\n");
   break;
  case '1':
   if(T)
   {
    printf("此二叉树的深度为:");
    printf("%d",Depth(T));
    printf("\n");
    printf("\n");
   }
   else printf("二叉树为空!\n");
   break;
  case '2':
   if(T)
   {
    printf("递归先序遍历二叉树:");
    Preorder(T);
    printf("\n");
    printf("\n");
   }
   else
    printf("二叉树为空!\n");
   break;
  case '3':
   if(T)
   {
    printf("非递归先序遍历二叉树:");
    NPreorder(T);
    printf("\n");
    printf("\n");
   }
   else
    printf("二叉树为空!\n");
   break;
  case '4':
   if(T)
   {
    printf("递归中序遍历二叉树:");
    Inorder(T);
    printf("\n");
    printf("\n");
   }
   else printf("二叉树为空!\n");
   break;
  case '5':
   if(T)
   {
    printf("非递归中序遍历二叉树:");
    NInorder(T);
    printf("\n");
    printf("\n");
   }
   else printf("二叉树为空!\n");
   break;
  case '6':
   if(T)
   {
    printf("递归后序遍历二叉树:");
    Postorder(T);
    printf("\n");
    printf("\n");
   }
   else printf("二叉树为空!\n");
   break;
  case '7':
   if(T)
   {
    printf("非递归后序遍历二叉树:");
    NPostorder(T);
    printf("\n");
    printf("\n");
   }
   else printf("二叉树为空!\n");
   break;
  case '8':
   if(T)
   {
    printf("层次遍历二叉树:");
    Translever(T);
    printf("\n");
    printf("\n");
   }
   else printf("二叉树为空!\n");
   break;
  case '9':
   if(T)
   {
    printf("输出二叉树:");
    Disptree(T);
    printf("\n");
    printf("\n");
   }
   else printf("二叉树为空!\n");
   break;
  default:
   sign=0;
   printf("程序运行结束,按任意键退出!\n");
  }
 }
}

示例:

转换成双向链表

先序列:H      F       C       D      M     I        N
中序列:C       F       D      H      I        M     N
后序列:C       D      F       I        N      M     H

#include <iostream>
using namespace std;
struct BSTreeNode{
 char m_val;
 BSTreeNode *m_pLeft;
 BSTreeNode *m_pRight;
};
BSTreeNode *pHead;//链表显示的头结点
BSTreeNode *pListIndex;//游标指针
void showOrderLiust(BSTreeNode *pCurrent);
void createBSTree(BSTreeNode *&pCurrent,char ch)
{
 if (NULL == pCurrent) {
 pCurrent = new BSTreeNode;
 pCurrent->m_val = ch;
 pCurrent->m_pLeft = NULL;
 pCurrent->m_pRight = NULL;
 }else {
 if (pCurrent->m_val > ch) {
 createBSTree(pCurrent->m_pLeft,ch);
 }else if (pCurrent->m_val < ch) {
 createBSTree(pCurrent->m_pRight,ch);
 }
 else
 {
 return;
 }
 }
}
//遍历二叉树/*先序遍历*/
void PreOrderTraverse(BSTreeNode *pCurrent)
{
 if (NULL == pCurrent) {
 return;
 } 

 if (NULL!=pCurrent)
 {
 //先遍历根节点
 cout<<pCurrent->m_val<<endl;
 //在遍历左节点
 PreOrderTraverse(pCurrent->m_pLeft);
 //在遍历右节点
 PreOrderTraverse(pCurrent->m_pRight);
 } 

}
//中序遍历
void InOrderTraverse(BSTreeNode *pCurrent)
{
 if (NULL == pCurrent) {
 return;
 }
 if (NULL != pCurrent->m_pLeft) {
 InOrderTraverse(pCurrent->m_pLeft);
 } 

 showOrderLiust(pCurrent);
 //在遍历右节点
 if (NULL != pCurrent->m_pRight) {
 InOrderTraverse(pCurrent->m_pRight);
 }
}
//后序遍历
void EndOrderTraverse(BSTreeNode *pCurrent)
{
 if (NULL == pCurrent) {
 return;
 }
 if (NULL != pCurrent->m_pLeft) {
 EndOrderTraverse(pCurrent->m_pLeft);
 }
 cout<<pCurrent->m_val<<endl;
 //在遍历右节点
 if (NULL != pCurrent->m_pRight) {
 EndOrderTraverse(pCurrent->m_pRight);
 }
}
/*该二元查找树转换成一个排序的双向链表。
 要求不能创建任何新的结点,只调整指针的指向*/
void showOrderLiust(BSTreeNode *pCurrent)
{
 pCurrent->m_pLeft = pListIndex;
 if (NULL != pListIndex) {
 pListIndex->m_pRight = pCurrent;
 }else
 {
 pHead = pCurrent;
 }
 pListIndex = pCurrent;
 cout<<pCurrent->m_val<<endl;
}
int main(int argc,char**argv)
{
 BSTreeNode *pRoot = NULL;
 pHead = NULL;
 pListIndex = NULL;
 createBSTree(pRoot,'H');
 createBSTree(pRoot,'F');
 createBSTree(pRoot,'C');
 createBSTree(pRoot,'D');
 createBSTree(pRoot,'M');
 createBSTree(pRoot,'I');
 createBSTree(pRoot,'N');
 PreOrderTraverse(pRoot);
 InOrderTraverse(pRoot);
 EndOrderTraverse(pRoot);
 delete pRoot;
 return 0;
}

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

(0)

相关推荐

  • C++基于递归和非递归算法判定两个二叉树结构是否完全相同(结构和数据都相同)

    本文实例讲述了C++基于递归和非递归算法判定两个二叉树结构是否完全相同.分享给大家供大家参考,具体如下: /*两个二叉树结构是否相同(结构和数据都相同) -- 递归和非递归方法 经调试可运行源码及分析如下: ***/ #include <stdlib.h> #include <iostream> #include <queue> using std::cout; using std::cin; using std::endl; using std::queue; /*二

  • 一波二叉树遍历问题的C++解答实例分享

    题目一: 输入一颗二元树,从上往下按层打印树的每个节点,同一层按照从左往右的顺序打印. 输入样例: 8 / / 6 10 / / / / 5 7 9 11 输出样例: 复制代码 代码如下: 8 6 10 5 7 9 11 思路分析: 把一颗二叉树抽象成三个节点:根节点.左节点.右节点. 先序遍历即可得到按行输出的效果. 对于左子树只要保存其根节点,既保存了整个左子树.(右子树一样) 对于根节点之外的两个子树来说说,始终是先访问左子树的根节点,再访问右子树的根节点. 因此可以使用队列存储. 代码实

  • C++ 数据结构完全二叉树的判断

    C++ 数据结构完全二叉树的判断 完全二叉树(Complete Binary Tree):若设二叉树的深度为h,除第h层外,其他各层(1~h-1)的节点数都达到最大个数,第h层所有的节点都连续集中在最左边,这就是完全二叉树.完全二叉树由满二叉树而引起来的.对于深度为K的,有n个节点的二叉树,当且仅当每一个节点都与深度为K的满二叉树中编号从1到n的节点一一对应时称之为完全二叉树. 注意:满二叉树一定是完全二叉树,但完全二叉树不一定是满二叉树. 完全二叉树的特点:完全二叉树的效率极高,堆是一种完全二

  • C++基于先序、中序遍历结果重建二叉树的方法

    本文实例讲述了C++基于先序.中序遍历结果重建二叉树的方法.分享给大家供大家参考,具体如下: 题目: 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回. 实现代码: #include <iostream> #include <vector> #include <stack> using

  • C++使用递归和非递归算法实现的二叉树叶子节点个数计算方法

    本文实例讲述了C++使用递归和非递归算法实现的二叉树叶子节点个数计算方法.分享给大家供大家参考,具体如下: /*求二叉树叶子节点个数 -- 采用递归和非递归方法 经调试可运行源码及分析如下: ***/ #include <stdlib.h> #include <iostream> #include <stack> using std::cout; using std::cin; using std::endl; using std::stack; /*二叉树结点定义*/

  • C++基于递归和非递归算法求二叉树镜像的方法

    本文实例讲述了C++基于递归和非递归算法求二叉树镜像的方法.分享给大家供大家参考,具体如下: /*求二叉树镜像 -- 采用递归和非递归方法 经调试可运行源码及分析如下: ***/ #include <stdlib.h> #include <iostream> #include <queue> using std::cout; using std::cin; using std::endl; using std::queue; /*二叉树结点定义*/ typedef st

  • C++二叉树结构的建立与基本操作

    准备数据定义二叉树结构操作中需要用到的变量及数据等. 复制代码 代码如下: #define MAXLEN 20    //最大长度typedef char DATA;    //定义元素类型struct  CBTType                   //定义二叉树结点类型 { DATA data;           //元素数据  CBTType * left;    //左子树结点指针  CBTType * right;   //右子树结点指针 }; 定义二叉树结构数据元素的类型DA

  • C++ 遍历二叉树实例详解

    C++ 遍历二叉树实例详解 2叉数又叫红黑树,关于2叉数的遍历问题,有很多,一般有三种常用遍历方法: (1)前序遍历(2)中序遍历(3)后续遍历 以下是经典示例: #include "stdafx.h" #include<stdio.h> #include<malloc.h> #include <math.h > #define MaxSize 20 typedef struct BiTNode { int data; struct BiTNode

  • C++树之遍历二叉树实例详解

    在讲遍历之前,我们要先创建一个树: #include <iostream> using namespace std; typedef struct node; typedef node *tree; struct node{ int data; // 结点数值 tree left,right; // 左子树和右子树 }; tree bt; 遍历二叉树有三种方式: 先序遍历 先序遍历的操作如下: 访问根结点 先序遍历左子树(递归) 先序遍历右子树(递归) 二叉树bt的先序遍历结果:1234753

  • PHP实现二叉树深度优先遍历(前序、中序、后序)和广度优先遍历(层次)实例详解

    本文实例讲述了PHP实现二叉树深度优先遍历(前序.中序.后序)和广度优先遍历(层次).分享给大家供大家参考,具体如下: 前言: 深度优先遍历:对每一个可能的分支路径深入到不能再深入为止,而且每个结点只能访问一次.要特别注意的是,二叉树的深度优先遍历比较特殊,可以细分为先序遍历.中序遍历.后序遍历.具体说明如下: 前序遍历:根节点->左子树->右子树 中序遍历:左子树->根节点->右子树 后序遍历:左子树->右子树->根节点 广度优先遍历:又叫层次遍历,从上往下对每一层依

  • Python定义二叉树及4种遍历方法实例详解

    本文实例讲述了Python定义二叉树及4种遍历方法.分享给大家供大家参考,具体如下: Python & BinaryTree 1. BinaryTree (二叉树) 二叉树是有限个元素的集合,该集合或者为空.或者有一个称为根节点(root)的元素及两个互不相交的.分别被称为左子树和右子树的二叉树组成. 二叉树的每个结点至多只有二棵子树(不存在度大于2的结点),二叉树的子树有左右之分,次序不能颠倒. 二叉树的第i层至多有2^{i-1}个结点 深度为k的二叉树至多有2^k-1个结点: 对任何一棵二叉

  • 二叉树的非递归后序遍历算法实例详解

    前序.中序.后序的非递归遍历中,要数后序最为麻烦,如果只在栈中保留指向结点的指针,那是不够的,必须有一些额外的信息存放在栈中.方法有很多,这里只举一种,先定义栈结点的数据结构 复制代码 代码如下: typedef struct{Node * p; int rvisited;}SNode //Node 是二叉树的结点结构,rvisited==1代表p所指向的结点的右结点已被访问过. lastOrderTraverse(BiTree bt){ //首先,从根节点开始,往左下方走,一直走到头,将路径上

  • js实现hashtable的赋值、取值、遍历操作实例详解

    本文实例讲述了js实现hashtable的赋值.取值.遍历操作.分享给大家供大家参考,具体如下: 哈希表(Hashtable)这个概率应该是#c里面的概念,用来赋值.取值.遍历.排序操作提高效率.想起这个东西其实使我们以前经常遇到这样的面试题,一个很大的数组可能有100000个,如何快速知道它里面的出现最多的次数,那么这里我们可能就要用Hashtable的相关知识了.Javascript中,object的实现就是hash表,因此只要在object上封装点方法,再利用原生的hasOwnProper

  • C语言 数据结构之中序二叉树实例详解

    C语言数据结构 中序二叉树 前言: 线索二叉树主要是为了解决查找结点的线性前驱与后继不方便的难题.它只增加了两个标志性域,就可以充分利用没有左或右孩子的结点的左右孩子的存储空间来存放该结点的线性前驱结点与线性后继结点.两个标志性域所占用的空间是极少的,所有充分利用了二叉链表中空闲存的储空间. 要实现线索二叉树,就必须定义二叉链表结点数据结构如下(定义请看代码): left leftTag data rightTag right 说明: 1.       leftTag=false时,表示left

  • Python 列表(List) 的三种遍历方法实例 详解

    Python 遍历 最近学习python这门语言,感觉到其对自己的工作效率有很大的提升,下面废话不多说,直接贴代码 #!/usr/bin/env python # -*- coding: utf-8 -*- if __name__ == '__main__': list = ['html', 'js', 'css', 'python'] # 方法1 print '遍历列表方法1:' for i in list: print ("序号:%s 值:%s" % (list.index(i)

  • python 遍历字符串(含汉字)实例详解

    python 遍历字符串(含汉字)实例详解 s = "中国china" for j in s: print j 首先一个,你这个'a'是什么编码?可能不是你所想的gbk >>> a='中国' >>> a 这样试试看,如果出来是6个字(word),说明是utf-8,如果是4个字,说明gbk. 另外,不管是utf-8还是gbk,都不能这样遍历,因为这里它会一个字一个字拿出来.虚拟机把a当成一个长度为len(a)的字符串了. 接下来是遍历问题. Linux

  • C语言数据结构之图的遍历实例详解

    C语言数据结构之图的遍历实例详解 输入一组顶点,建立无向图的邻接矩阵.输入一组顶点,建立有向图的邻接表.分别对无向图和有向图进行DFS(深度优先遍历)和BFS(广度优先遍历).写出深度优先遍历的递归和非递归算法.根据建立的有向图,判断该图是否是有向无环图,若是,则输出其一种拓扑有序序列. 实现代码: #include <stdio.h> #include <stdlib.h> #define MAX 20 typedef struct ArcNode{ int adjvex; st

随机推荐