二叉树的建立以及遍历C/C++
来源:互联网 发布:mpi编程 编辑:程序博客网 时间:2024/06/16 22:32
一、 二叉树的定义
二叉树(Binary Tree)是个有限元素的集合,该集合或者为空,或者由一个称为根(root)的元素及两个不相交的、分别被称为左子树和右子树的二叉树组成。当集合为空时,称该二叉树为空二叉树,在二叉树中,一个元素也成为一个节点。
二、 二叉树的数据结构
下面为二叉树链式存储结构的定义:
/* *定义二叉树的数据结构 */typedef char datatype ;typedef struct BiTNode{ datatype data ; //数据域 struct BiTNode *lchild , *rchild ; //孩子的左右节点} BiTNode , *BiTree ;
三、 二叉树的递归遍历
1、 二叉树的前序遍历
若二叉树为非空,则依次进行如下操作:
(1) 访问根节点;
(2) 先序遍历左子树;
(3) 先序遍历右子树;
算法如下:
/* *进行二叉树的先序遍历 */void PreOrder(BiTree bt){ if(bt == NULL) //递归的结束的条件 { return ; } printf("%c " , bt->data) ; PreOrder(bt->lchild) ; PreOrder(bt->rchild) ;}
2、 二叉树的中序遍历
若二叉树为非空,则依次进行如下操作:
(1)中序遍历左子树;
(2)访问根节点;
(3)中序遍历右子树;
算法如下:
/* *中序遍历二叉树 */void InOrder(BiTree bt){ if(bt == NULL) //递归的结束条件 { return ; } InOrder(bt->lchild) ; printf("%c " , bt->data) ; InOrder(bt->rchild) ;}
3、 二叉树的后续遍历
若二叉树为非空,则依次进行如下操作:
(1)后序遍历左子树;
(2)后序遍历右子树;
(3)访问根节点;
算法如下:
/* *后序遍历二叉树 */void PostOrder(BiTree bt){ if(bt == NULL) //递归的结束条件 { return ; } PostOrder(bt->lchild) ; PostOrder(bt->rchild) ; printf("%c " , bt->data) ;}
4、 二叉树的层次遍历
借助队列的数据结构进行层次遍历
(1) 访问当前队头节点;
(2) 若该元素所指节点的左、右孩子节点非空,则将该元素所指节点的左孩子指针和右孩子指针顺序入队;
(3) 此过程不断进行,当队列为空时,二叉树的层次遍历结束;
算法如下:
/* *用队列实现二叉树的层次遍历 */ void LevelOrder(BiTree bt) { BiTree quene[MAXSIZE] ; int front , rear ; //分别指向队列的队首语队尾 if(bt == NULL) { return ; } front = -1 ; rear = 0 ; quene[rear] = bt ; while(front != rear) { front++ ; printf("%c " , quene[front]->data) ; if(quene[front]->lchild != NULL) //将队首的左孩子节点加入队列 { rear++; quene[rear] = quene[front]->lchild ; } if(quene[front]->rchild != NULL) //将队首的右孩子节点加入队列 { rear++; quene[rear] = quene[front]->rchild ; } } }
四、 二叉树的非递归遍历
1、 二叉树的非递归前序遍历
借助栈存储当前访问的节点,栈为空时,访问结束。
算法如下:
/* *进行二叉树的非递归前序遍历 */void NRPreOrder(BiTree bt){ BiTree stack[MAXSIZE] , p ; int i , top ; if(bt == NULL) { printf("二叉树为空!\n") ; return ; } top = 0 ; p = bt ; while(p != NULL || top != 0) { while(p != NULL) { printf("%c " , p->data) ; //范围访问当前元素 if(top < MAXSIZE - 1) { stack[top] = p ; //将当前结点压栈 top++ ; } else { printf("栈溢出!\n") ; return ; } p = p->lchild ; //指针指向该节点的左孩子 } if(top <= 0) { return ; } else { top-- ; p = stack[top] ; //从栈中弹出栈顶元素 p = p->rchild ; //指针指向该节点的右孩子 } }}
2、 二叉树的非递归中序遍历
只需将访问节点的代码移动到p = stack[top] 和 p = p->rchild 之间即可。
算法如下:
/* *进行非递归的中序遍历 */void NRInOrder(BiTree bt){ BiTree stack[MAXSIZE] , p ; int i , top ; if(bt == NULL) { printf("二叉树为空!\n") ; return ; } top = 0 ; p = bt ; while(p != NULL || top != 0) { while(p != NULL) { if(top < MAXSIZE - 1) { stack[top] = p ; top++ ; } else { printf("栈溢出!\n") ; return ; } p = p->lchild ; } if(top <= 0) { return ; } else { top-- ; p = stack[top] ; printf("%c " , p->data) ; //范围访问当前元素 p = p->rchild ; } }}
3、 二叉树的后序遍历
在后序遍历过程中,节点在第一次出栈后,还需再次入栈,也就是说节点要入两次栈,出两次栈。而访问节点是在第二次出栈是进行的。因此为了区别节点出栈的次数,定义数据结构:
/* *为二叉树的后续遍历建立数据结构 */typedef struct{ BiTree bt ; int flag ;} stacktype ;算法如下:/* *进行二叉树的后序遍历 */void NRPostOrder(BiTree bt){ stacktype stack[MAXSIZE] ; int top , sign ; BiTree p ; if(bt == NULL) { return ; } top = -1 ; p = bt ; while(p != NULL || top != -1) { if(p != NULL) { top++ ; stack[top].bt = p ; stack[top].flag = 1; p = p->lchild ; } else { p = stack[top].bt ; sign = stack[top].flag ; top-- ; if(sign == 1) { //进行二次压栈 top++ ; stack[top].bt = p ; stack[top].flag = 2 ; p = p->rchild ; } else { printf("%c " , p->data) ; //进行二叉树的访问 p = NULL ; } } }}
五、 二叉树的建立
由二叉树的性质可知,二叉树可有先序序列和中序序列唯一确定,而后序序列与中序序列无法确定唯一二叉树。
算法思想是:运用递归求解二叉树,先根据先序序列的第一个元素建立根节点;然后在中序序列中找到该元素,确定根节点的左、右子树的中序序列;再在先序序列中确定左、右子树的先序序列;最后由左子树的先序序列与中序序列建立左子树,由右子树的先序序列与中序序列建立右子树。
算法如下:
void PreInO(char preOrder[] , char inOrder[] , int i , int j , int k , int h , BiTree *bt){ int m ; if(!((*bt) = (BiTree)malloc(sizeof(BiTNode)))) { return ; } else { (*bt)->data = preOrder[i] ; m = k ; while(preOrder[i] != inOrder[m]) { m++ ; } if(m == k) { (*bt)->lchild = NULL ; } else { PreInO(preOrder , inOrder , i + 1 , m - k + i , k , m - 1 , &((*bt)->lchild)) ; //进行左子树的建立 } if(m == h) { (*bt)->rchild = NULL ; } else { PreInO(preOrder , inOrder , m - k + i + 1 , j , m + 1 , h , &((*bt)->rchild)) ; //进行右子树的建立 } }}/* *根据二叉树的前序遍历序列和中序遍历确定唯一二叉树 *根据二叉树的中序遍历和后续遍历不能确定唯一二叉树 */void ReBiTree(char preOrder[] , char inOrder[] , BiTree *bt){ int len ; len = strlen(preOrder) ; if(len <= 0) { return ; } else { PreInO(preOrder , inOrder , 0 , len - 1 , 0 , len - 1 , bt) ; }}
- 二叉树的建立以及遍历C/C++
- C语言实现二叉树的建立、遍历以及表达式的计算
- c语言实现线索二叉树的建立,线索化以及遍历
- 数据结构 树 二叉树的建立及遍历 C语言版
- 递归实现二叉树的建立及前中后序遍历 c
- 二叉树的建立与递归遍历C语言版
- (C++)二叉树的建立与递归方式遍历
- 线索二叉树的建立与遍历C/C++
- 二叉树的建立和遍历程序代码(Java,C)
- C实现二叉树的建立和遍历
- C++二叉树的建立以及遍历
- 二叉树的建立,以及递归前中后序遍历二叉树
- c语言实现二叉树(BiNodeTree)的建立与先序遍历,中序遍历
- 用c语言编程实现二叉树的建立和遍历二叉树
- 二叉搜索树建立插入及遍历c
- 二叉树的迭代前中后遍历以及不用栈的遍历C语言
- 平衡二叉树的建立,查找,插入,调整,遍历的C语言实现
- [树]二叉树的建立以及三种遍历
- python 数学函数
- hdu4027
- Oracle sql完整的执行顺序:
- MySQL数据库数据类型(char(n),varchar(n),nchar(n),nvarchar(n)的区别)
- EOJ1810 稀疏矩阵三元组转化
- 二叉树的建立以及遍历C/C++
- Hibernate五大核心接口
- 基于ADO的MFC与SQL Server连接
- C语言嵌入式系统编程-----软件架构篇
- 系统学习Java和无基础自学python的一些感受
- R tutorial 09 - Advance Data.frame 进阶函数-数据
- signal函数、sigaction函数及信号集操作函数
- wpf 学习足迹
- TextView里画世界——ReplacementSpan实践