如何利用前序遍历序列和中序遍历序列非递归的创建二叉树
来源:互联网 发布:python idle打开闪退 编辑:程序博客网 时间:2024/06/05 10:18
说到二叉树的创建,我们一般会想到用递归的方法,因为利用递归写的代码看起来很简洁,但是递归的使用也同样存在效率不够高的问题。所以这里我们要说的是如何利用前序遍历序列和中序遍历序列非递归的创建二叉树。
思想:利用两个栈实现(当然也可以用一个栈,这里针对自己的数据类型设计),一个栈s用来存放树的各个结点,另一个栈isindex用来存放第一个栈中元素对应于中序序列中的下标。首先,我们先将根结点(即前序序列中的第一个元素)及其在中序序列中相应的下标分别入栈s和isindex,并将根结点置于当前结点。然后,从前序序列中首元素开始,依次比较相邻两个元素在中序序列中对应的下标,来确定后一个元素是当前结点的左子树还是右子树,具体有以下几种情况:
1. index2 == -1 这是在中序序列中没找到前序序列中的元素,说明是遍历序列有问题,直接退出
2. index1 > index2 前序序列中后一个元素在中序序列中相对较前的位置,说明后一个元素是当前结点的左子树
3. index1 < index2 前序序列中后一个元素在中序序列中相对较后的位置,说明后一个元素是当前结点的右子树,至于是那棵右子树,还需对index2和栈isindex栈顶元素作循环比较
说到这里就有一个疑问了:为什么index2要和isindex栈顶元素比较呢?首先我们得知道isindex2里面存的是什么,前面已经说过,isindex里面存的是已经创建好的部分树的结点在中序序列中的下标,根据中序遍历的特点:中序遍历左子树,访问根节点,中序遍历右子树,我们知道,中序序列中右结点总是在左结点以及根结点的后边,即右结点在中序序列中的下标要大于左结点和根结点的下标,所以要想知道index2所对应的元素是已创建好的部分树的哪一个结点的右孩子结点,我们需要循环比较index2和栈isindex的栈顶元素的结点,如果栈顶元素较index2小,则栈s和isindex同时出栈,并将出栈结点作为当前结点,直到两栈为空或者遇到第一个比index2大的元素(即我们循环的目的就是找到最后一个比index2小的元素,这样index2所对应的元素就是找到的元素的右孩子结点),此时index2对应的元素就是当前结点的右孩子结点。
那么index1==index2这种情况有没有可能出现呢?在这里我们一般不考虑重结点的情况,所以这种情况不会出现。
变量说明:
ps 前序序列指针
is 中序序列指针
s 栈,存放树的各个结点
isindex 利用数组模拟的栈,用来存放栈s中对应元素在中序序列中的下标
index1 前序序列中前一个元素在中序序列中的下标
index2 前序序列中后一个元素的中序序列中的下标
参考代码:“
typedef char ElemType;typedef struct btnode //二叉树的结点定义{ ElemType data; btnode *leftchild; btnode *rightchild;}BtNode,*BtTree; //在中序序列中查找元素函数int find (char *is,char ch){ if (is == NULL) { exit (1); } int i = 0; while (is[i] != 0) { if (is[i] == ch) { return i; } else { i ++; } } return -1;}BtNode *NiceCreatTreePI (char *ps,char *is){ if (NULL == ps && NULL == is) { return NULL; } int isindex[MAXSIZE] = {0}; //用数组模拟一个顺序栈 (从数组最后入栈和出栈) for (int j = 0;j < MAXSIZE;j ++) //初始化全用-1表示,以便出栈处理 { isindex[j] = -1; } int i = 0; SeqStack s; Init_stack (&s); BtNode * p = BuyNode (); p -> data = *ps; Push (&s,p); BtNode *child = NULL; BtNode *tree = p; int index1 = find (is,*ps); isindex[i ++] = index1; //相当于进栈 int index2 = index1; while (*(ps + 1) != 0) { index1 = index2; index2 = find (is,*(ps + 1)); if (index1 == -1 || index2 == -1) { exit (1); } if (index1 > index2) //左子树 { child = BuyNode (); ps ++; child -> data = *ps; p -> leftchild = child; p = p -> leftchild; Push (&s,child); isindex[i ++] = index2; } else //右子树 { i --; while (i >= 0 && index2 > isindex[i]) { p = top (&s); pop (&s); isindex[i] = -1; i --; } child = BuyNode (); ps ++; child -> data = *ps; p -> rightchild = child; p = p -> rightchild; Push (&s,child); i ++; isindex[i ++] = index2; } } return tree;}
本文如有需要改进的地方,还请各位大神指点。
- 如何利用前序遍历序列和中序遍历序列非递归的创建二叉树
- 由二叉树的前序遍历序列和中序遍历序列求后序遍历序列
- 根据前序遍历序列和中序遍历序列创建二叉树
- 从二叉树的前序遍历序列和中序遍历序列重构出二叉树
- 如何根据前序遍历序列和中序遍历序列确定二叉树
- 如何根据前序遍历序列和中序遍历序列确定二叉树
- 树的学习——(递归构建二叉树、递归非递归前序中序后序遍历二叉树、根据前序序列、中序序列构建二叉树)
- 【二叉树】 前序、中序和后序的递归遍历与非递归遍历
- 二叉树 前序遍历的非递归实现 中序遍历的非递归实现 后序遍历的非递归实现 创建二叉树
- 已知前序遍历序列和中序遍历序列,求二叉树的后序遍历
- 二叉树的前序遍历、中序遍历和后序遍历的递归和非递归算法
- 由前序遍历序列跟中序遍历序列生成二叉树,如果输入序列不正确返回fail~ 如果正确则前序遍历创建的二叉树
- 二叉树非递归前序和中序遍历
- 二叉树的创建,遍历(前序,中序,后序)-递归 非递归
- 通过二叉树的中序和后序遍历序列构造二叉树(非递归)
- 前序遍历和中序遍历序列能确定唯一的一棵二叉树
- 根据前序遍历序列和中序遍历序列构造二叉树
- 根据前序遍历序列和中序遍历序列构造二叉树算法
- 欢迎使用CSDN-markdown编辑器
- python3 读写文件的两种小方法
- Java面试题二
- Mac系统中Python3的安装与切换
- CorelDRAW可以随意的让图片倾斜旋传这些方法得记住了
- 如何利用前序遍历序列和中序遍历序列非递归的创建二叉树
- 训练总结
- 1286 Unknown storage engine 'InnoDB'的解决办法
- 到底应该使用count(*) 还是count(1)
- Java线程池
- [公告]同步详询
- Ascii,Unicode和utf-8的发展演变,java下字符和字节关系
- Java面试题三
- palindrome-partitioning