二叉树的深度(前序 中序 后序 递归非递归搜素)、广度、搜索 C++
2014-08-19 17:57
597 查看
a b c 使用 1 2 3 表示
/* 描述:二叉树的深度(前序 中序 后序 递归非递归搜素)、广度、搜索 作者:jz 日期:20140819 */ #include<stdio.h> #include<malloc.h> #include<process.h> /* exit() */ #include<iostream> using namespace std; #include<stack> #include<queue> #define OK 1 #define TElemType int #define Status int #define Nil (-1) //结束符 #define TRUE 1 #define FALSE 0 #define ERROR 0 typedef struct BiTNode /* 二叉树的二叉链表存储表示 */ { TElemType data; struct BiTNode *lchild,*rchild; /* 左右孩子指针 */ }BiTNode,*BiTree; enum enum_tag {L=1,R=2};//后序遍历使用作为标记 typedef struct StackNode {//后序遍历使用 enum_tag tag; BiTNode* ptr; }StackNode; Status InitBiTree(BiTree *T) { /* 操作结果: 构造空二叉树T */ *T=NULL; return OK; } void DestroyBiTree(BiTree *T) { /* 初始条件: 二叉树T存在。操作结果: 销毁二叉树T */ if(*T) /* 非空树 */ { if((*T)->lchild) /* 有左孩子 */ DestroyBiTree(&(*T)->lchild); /* 销毁左孩子子树 */ if((*T)->rchild) /* 有右孩子 */ DestroyBiTree(&(*T)->rchild); /* 销毁右孩子子树 */ free(*T); /* 释放根结点 */ *T=NULL; /* 空指针赋0 */ } } void CreateBiTree(BiTree *T) { /*按先序次序输入二叉树中结点的值(可为字符型或整型,在主程中 */ /* 定义),构造二叉链表表示的二叉树T。变量Nil表示空(子)树。有改动 */ TElemType ch; scanf("%d",&ch); if(ch==Nil) /* 空 */ *T=NULL; else { *T=(BiTree)malloc(sizeof(BiTNode)); if(!*T) exit(-1); (*T)->data=ch; /* 生成根结点 */ CreateBiTree(&(*T)->lchild); /* 构造左子树 */ CreateBiTree(&(*T)->rchild); /* 构造右子树 */ } } void PreOrderTraverse(BiTree T,Status(*Visit)(TElemType)) { /* 初始条件: 二叉树T存在,Visit是对结点操作的应用函数。算法6.1,有改动 */ /* 操作结果: 先序递归遍历T,对每个结点调用函数Visit一次且仅一次 */ if(T) /* T不空 */ { Visit(T->data); /* 先访问根结点 */ PreOrderTraverse(T->lchild,Visit); /* 再先序遍历左子树 */ PreOrderTraverse(T->rchild,Visit); /* 最后先序遍历右子树 */ } } void InOrderTraverse(BiTree T,Status(*Visit)(TElemType)) { /* 初始条件: 二叉树T存在,Visit是对结点操作的应用函数 */ /* 操作结果: 中序递归遍历T,对每个结点调用函数Visit一次且仅一次 */ if(T) { InOrderTraverse(T->lchild,Visit); /* 先中序遍历左子树 */ Visit(T->data); /* 再访问根结点 */ InOrderTraverse(T->rchild,Visit); /* 最后中序遍历右子树 */ } } void PostOrderTraverse(BiTree T,Status(*Visit)(TElemType)) { /* 初始条件: 二叉树T存在,Visit是对结点操作的应用函数 */ /* 操作结果: 后序递归遍历T,对每个结点调用函数Visit一次且仅一次 */ if(T) /* T不空 */ { PostOrderTraverse(T->lchild,Visit); /* 先后序遍历左子树 */ PostOrderTraverse(T->rchild,Visit); /* 再后序遍历右子树 */ Visit(T->data); /* 最后访问根结点 */ } } Status Visit(TElemType e)//显示 { printf("%d ",e); return OK; } Status InOrderTraverse_use_stack(BiTree T,Status(*Visit)(TElemType)) { /*非递归算法使用栈 进行前序 中序遍历 后序遍历的思想比较复杂需要使用到二次进栈*/ stack<BiTNode*> S; BiTree p=T; do { while(p) { /* 根指针进栈,遍历左子树 */ Visit(p->data);//先序遍历,先输出节点数据再压入栈 S.push(p); p=p->lchild; } if(!S.empty()) { /* 根指针退栈,访问根结点,遍历右子树 */ p=S.top(); //Visit(p->data);//中序遍历,在栈弹出时显示,(需要时将上面的Visit注释掉) S.pop(); p=p->rchild; } }while(p||!S.empty()); printf("\n"); return OK; } /* 后序遍历非递归 后序非递归算法比较复杂,每个结点要到它们左、右子树都遍历完时才得以访问,所以在去遍历它的左、 右子树之前都需要进栈。当它出栈时,需要判断是从左子树回来(即刚遍历完左子树,此时需要去遍历右子树) ,还是从右子树回来(即刚遍历完右子树,此时需要去访问这个结点)。因此,进栈的结点需要伴随着一个标记 tag */ void PostOrderTraverse_use_stack(BiTree T) { stack<StackNode> S; BiTree p; StackNode w; p=T; do { while(p) { w.ptr=p; w.tag=L; S.push(w); p=p->lchild; } int cont_flag=1; while( cont_flag&&!S.empty() ) { w=S.top(); S.pop(); p = w.ptr; switch(w.tag) { case L : w.tag=R; S.push(w); cont_flag = 0; p=p->rchild; break; case R: Visit(p->data); break; } } }while(!S.empty() ); } void LevelOrderTraverse(BiTree T,Status(*Visit)(TElemType)) { /* 初始条件:二叉树T存在,Visit是对结点操作的应用函数 */ /* 操作结果:层序递归遍历T(利用队列),对每个结点调用函数Visit一次且仅一次 */ queue<BiTNode*> qu; BiTree p; p=T; if(T) { qu.push(p); while(!qu.empty()) { p=qu.front(); qu.pop(); Visit(p->data); if(p->lchild!=NULL) qu.push(p->lchild); if(p->rchild!=NULL) qu.push(p->rchild); } printf("\n"); } } int main() { //输入: 1 2 3 -1 -1 4 5 -1 7 -1 -1 6 -1 -1 -1 printf("请输入构造二叉树的值,整数值,空值请输入‘-1’\n"); BiTree BT; InitBiTree(&BT); CreateBiTree(&BT); printf("\n先序递归遍历递归\n"); PreOrderTraverse(BT,Visit); printf("\n中序归遍历递归\n"); InOrderTraverse(BT,Visit); printf("\n后序归遍历递归\n"); PostOrderTraverse(BT,Visit); printf("\n-----------------------\n"); printf("\n先序递归遍历_非递归\n"); InOrderTraverse_use_stack(BT,Visit); printf("\n后序遍历非递归\n"); PostOrderTraverse_use_stack(BT); printf("\n层次遍历非递归\n"); LevelOrderTraverse(BT,Visit); printf("\n"); DestroyBiTree(&BT); return 0; }
相关文章推荐
- 二叉树基本操作的递归实现(二叉树建立,先序,中序,后序,深度的递归遍历。广度优先,高度优先的非递归遍历)
- [C/C++] 先序建立二叉树| 先序、中序、后序遍历二叉树| 求二叉树深度、节点数、叶节点数 算法实现
- 数据结构——二叉树 前序、中序、后序、层次遍历及非递归实现 查找、统计个数、比较、求深度的递归实现
- 数据结构(六)——二叉树 前序、中序、后序、层次遍历及非递归实现 查找、统计个数、比较、求深度的递归实现
- 二叉树构建,先序,中序,后序遍历(以及非递归实现),广度优先遍历
- 数据结构(六)——二叉树 前序、中序、后序、层次遍历及非递归实现 查找、统计个数、比较、求深度的递归实现
- 二叉树 前序、中序、后序、层次遍历及非递归实现 查找、统计个数、比较、求深度的递归实现
- 数据结构(六)——二叉树 前序、中序、后序、层次遍历及非递归实现 查找、统计个数、比较、求深度的递归实现
- 先序,中序,后序,求叶子结点数,深度,拷贝,几种二叉树的常见递归使用方法
- 二叉树 前序、中序、后序、层次遍历及非递归实现 查找、统计个数、比较、求深度的递归实现
- 二叉树的遍历(先序/中序/后序,递归/迭代)与搜索
- 二叉树的广度搜索非递归 深度搜索递归和非递归
- 数据结构(一)——二叉树 前序、中序、后序、层次遍历及非递归实现 查找、统计个数、比较、求深度的递归实现
- 二叉树的深度优先dfs遍历(前序、中序和后序;递归与非递归)
- 二叉树 前序、中序、后序、层次遍历及非递归实现 查找、统计个数、比较、求深度的递归实现
- C++实现二叉树的递归遍历与非递归遍历(先序、中序、后序、层序)
- 二叉树 前序、中序、后序、层次遍历及非递归实现 查找、统计个数、比较、求深度的递归实现
- 二叉树构建,先序,中序,后序遍历(以及非递归实现),广度优先遍历
- 二叉树 前序、中序、后序、层次遍历及非递归实现 查找、统计个数、比较、求深度的递归实现
- 用非递归实现二叉树的前序、中序、后序、层次遍历,用递归实现查找、统计个数、比较、求深度