Robson方法遍历二叉树
来源:互联网 发布:乐高电机有哪些端口 编辑:程序博客网 时间:2024/06/15 18:35
逆转链方法遍历二叉树:
在检测指针指向左子树或右子树遍历下去时,把原来的左子女指针或右子女指针逆转,记忆父节点。
在回溯时,再把指向父节点的指针逆转回来。
为了识别是从左子女翻上去还是从右子女翻上去的,需要为每个节点增加一个标志tag---在翻转左子女指针的时候tag = 1,在翻转右子女指针的时候tag = 0;
在退回到父节点后,若tag = 1,恢复左子女的指针指向,否则恢复右子女的指针的指向。
#include<iostream>using namespace std;#include"BinaryTree.h"template<class T>void Robson(BinTreeNode<T> *BT){ if(BT == NULL)return; BinTreeNode<T> *p = BT,*q = NULL,*r = BT,*avail,*top = NULL; do{ if(p->leftChild != NULL || p->rightChild != NULL){ if(p->leftChild != NULL){ //下降进入左子树 q = p->leftChild;p->leftChild = r; r = p;p = q; } else{ q = p->rightChild;p->rightChild = r; r = p;p = q; } } else{ cout << p->data << endl; avail = p; //此叶节点可以用来存储栈元素 while(p != BT && (r != NULL && (r->rightChild == NULL || r->leftChild == NULL || (top != NULL && r == top->rightChild)))){ //连续上升,父节点的左指针或者右指针指向当前节点 // ,上升到父节点,若无指针指向当前节点,则取出栈顶元素,在判断指针时限判断是否不为空 if(r->rightChild == NULL){ //从左子树上升 q = r->leftChild;r->leftChild = p; //回复左子树指针的指向 p = r; r = q; } if(r->leftChild == NULL){ //从右子树上升 q = r->rightChild;r->rightChild = p; p = r; r = q; } if(r == top->rightChild){ //从右子树回溯,退栈,top的rightChild存储刚进栈的叶节点p的地址 q = top; top = top->leftChild; //top->leftChild是栈顶的下一个元素 q->leftChild = q->rightChild = NULL; q = r->rightChild; //q存储回溯之后的父节点 r->rightChild = p; p = r;r = q; } cout << p->data << endl; } if(p != BT){ //从左子树退回并进入右子树 avail->leftChild = top;avail->rightChild = r; top = avail;//当前节点进栈 q = r->rightChild; r->rightChild = r->leftChild; r->leftChild = p; p = q; } } }while(p != BT);}int main(){ BinaryTree<char> A; Robson(A.getRoot()); return 0;}
Robson方法遍历二叉树的特点如下:
1)使用逆转链的思想
2)不适用tag标志,而是用内嵌的栈代替tag的作用。使用叶节点作为栈的结构,不另设存储空间。
3)利用栈解决在回溯时分辨究竟是从左子树还是右子树上升的问题
#include<iostream>using namespace std;#include"BinaryTree.h"template<class T>void Reverse_chain(BinTreeNode<T> *BT){ if(BT == NULL)return; BinTreeNode<T> *p = BT,*q,*r = NULL; do{ cout << p->data << endl; if(p->leftChild != NULL || p->rightChild != NULL){ if(p->leftChild != NULL){ //逆转左子树 p->tag = 1; //标志左子树 q = p->leftChild; p->leftChild = r; r = p; p = q; } else{ q = p->rightChild; p->rightChild = r; r = p; p = q; } } else{ while(r != NULL && r->tag == 0 || r!=NULL && r->tag == 1 && r->rightChild == NULL){ if(r != NULL && r->tag == 0){ //从右子树上升 q = r->rightChild; r->rightChild = p; //恢复右子树 p = r; r = q; } else{ //从左子树上升 r->tag = 0; q = r->leftChild; r->leftChild = p; p = r; r = q; } } if(r != NULL){ r->tag = 0; q = r->rightChild; r->rightChild = r->leftChild; //逆转右子树 r->leftChild = p; //恢复左子树 p = q; }//从r的左子树上升进入右子树 } }while(r != NULL); //父节点为空则结束}int main(){ BinaryTree<char> A; Reverse_chain(A.getRoot()); return 0;}
0 0
- Robson方法遍历二叉树
- 逆转链方法遍历二叉树 不使用栈与递归 Robson方法 与 Morris方法
- 二叉树遍历方法
- 二叉树遍历方法
- 二叉树的遍历方法
- 二叉树遍历方法小结
- 二叉树的遍历方法
- 二叉树遍历方法总结
- Morris方法遍历二叉树
- Morris方法遍历二叉树
- 二叉树的遍历方法
- 二叉树的遍历方法
- 二叉树的遍历方法
- 一种二叉树遍历方法
- 数据结构--二叉树遍历方法
- 二叉树遍历,三种方法
- 二叉树的遍历(递归方法)
- 二叉树的三种遍历方法
- Flex
- 学习的那些网址
- 初识js中的闭包
- android中调用App市场对自身App评分
- 如何处理mapper数量的大小的问题
- Robson方法遍历二叉树
- Tabbar上拉隐藏下拉显示
- Android-下拉刷新
- Lua—第9章协同程序
- C# DEV PopupContainerEdit和PopupContainerControll
- Python
- 【数据结构与算法】二叉树给定两个节点的最短距离(C++实现)
- 锁,同步代码块,同步方法 区别
- 采用Lazy方式加载的Fragment