二叉树的遍历(递归,迭代,Morris遍历)
2024-10-18 23:33:02
二叉树的三种遍历方法:
先序,中序,后序,这三种遍历方式每一个都可以用递归,迭代,Morris三种形式实现,其中Morris效率最高,空间复杂度为O(1)。
主要参考博客:
Morris Traversal方法遍历二叉树(非递归,不用栈,O(1)空间)
#include <iostream>
#include <vector>
#include <stack>
using namespace std; struct TreeNode{
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int _val) :val(_val){
left = NULL; right = NULL;
} }; TreeNode* BuildTree()
{
TreeNode* root = new TreeNode(6); int array[] = { 2, 7, 1, 4, 9, 3, 5, 8 };
vector<TreeNode*> list;
//cout << sizeof(array) / sizeof(array[0]) << endl;
for (size_t i = 0; i <sizeof(array)/sizeof(array[0]); i++)
{
TreeNode* t = new TreeNode(array[i]);
list.push_back(t);
}
root->left = list[0];
root->right = list[1];
list[0]->left = list[2];
list[0]->right = list[3];
list[1]->right = list[4];
list[3]->left = list[5];
list[3]->right = list[6];
list[4]->left = list[7]; return root;
} void preorderRecursive(TreeNode* t)
{
if (t == NULL)
return;
cout << t->val << " ";
preorderRecursive(t->left);
preorderRecursive(t->right); } void preorderIterative(TreeNode* root)
{
if (root == NULL)
return;
stack<TreeNode*> stk;
TreeNode* cur = root;
while (cur || !stk.empty())
{
while (cur)
{
cout << cur->val << " ";
stk.push(cur);
cur = cur->left;
}
if (!stk.empty())
{
cur = stk.top();
stk.pop();
cur = cur->right;
}
} } void preorderMorris(TreeNode* root)
{
if (root == NULL)
return;
TreeNode* cur = root;
TreeNode* pre = NULL;//前驱节点
while (cur)
{
if (cur->left == NULL){
cout << cur->val << " ";
cur = cur->right;
}
else{
pre = cur->left;
while (pre->right != NULL && pre->right != cur)
pre = pre->right;
if (pre->right == NULL){
cout << cur->val << " ";
pre->right = cur;
cur = cur->left;
}
else{
pre->right = NULL;
cur = cur->right;
}
}
}
} void inorderRecursive(TreeNode* root)
{
if (root == NULL)
return;
inorderRecursive(root->left);
cout << root->val << " ";
inorderRecursive(root->right);
} void inorderIterative(TreeNode* root)
{
stack<TreeNode* > stk;
TreeNode* cur = root;
while (cur || !stk.empty())
{
while (cur){
stk.push(cur);
cur = cur->left;
}
if (!stk.empty()){ cur = stk.top();
cout << cur->val << " ";
stk.pop();
cur = cur->right;
} }
} void inorderMorris(TreeNode* root)
{
TreeNode* cur = root;
TreeNode* pre = NULL; //前驱节点
while (cur)
{
if (cur->left == NULL){
cout << cur->val << " ";
cur = cur->right;
}
else{
pre = cur->left;
while (pre->right != NULL && pre->right != cur)
pre = pre->right;
if (pre->right == NULL){
pre -> right = cur;
cur = cur->left;
}
else{
cout << cur->val << " ";
pre->right = NULL;
cur = cur->right;
}
}
}
} void postorderRecursive(TreeNode* root)
{
if (root == NULL)
return;
postorderRecursive(root->left);
postorderRecursive(root->right);
cout << root->val << " "; } void postorderIterative(TreeNode* root)
{
stack<TreeNode*> stk;
TreeNode* cur = root;
TreeNode* pre = NULL;
while (cur || !stk.empty()){
while (cur){
stk.push(cur);
cur = cur->left;
}
if (!stk.empty()){
cur = stk.top();
if (cur->right != NULL && cur->right != pre){
cur = cur->right;
}
else{
cout << cur->val<<" ";
pre = cur;
stk.pop();
cur = NULL;
}
}
}
} void reverse(TreeNode *begin, TreeNode *end) {
if (begin == end)
return;
TreeNode *pre = begin;
TreeNode *cur = begin->right;
TreeNode *next;
while (pre != end) {
TreeNode* temp = cur->right;
cur->right = pre;
pre = cur;
cur = temp;
}
} void traversalReversal(TreeNode *begin, TreeNode *end) {
reverse(begin, end);
TreeNode *it = end;
while (true) {
cout << it->val << " ";
if (it == begin)
break;
it = it->right;
}
reverse(end, begin);
} void postorderMorris(TreeNode *root) {
if (!root)
return;
TreeNode dump(0);
dump.left = root;
TreeNode *cur = &dump;
TreeNode *pre = NULL;
while (cur) {
if (cur->left == NULL) {
cur = cur->right;
}
else {
pre = cur->left;
while (pre->right != NULL && pre->right != cur)
pre = pre->right;
if (pre->right == NULL) {
pre->right = cur;
cur = cur->left;
}
else {
traversalReversal(cur->left, pre);
pre->right = NULL;
cur = cur->right;
}
}
}
} int main(void)
{ TreeNode* root = BuildTree();
cout << "----------Preorder Recursive--------------" << endl;
preorderRecursive(root);
cout <<endl;
cout << "----------Preorder Iterative---------------" << endl;
preorderIterative(root);
cout << endl;
cout << "----------Preorder Morris---------------" << endl;
preorderMorris(root);
cout << endl;
cout << endl; cout << "----------Inorder Recursive--------------" << endl;
inorderRecursive(root);
cout << endl;
cout << "----------Inorder Iterative--------------" << endl;
inorderIterative(root);
cout << endl;
cout << "----------Inorder Morris-----------------" << endl;
inorderMorris(root);
cout << endl;
cout << endl; cout << "----------Postorder Recursive--------------" << endl;
postorderRecursive(root);
cout << endl;
cout << "----------Postorder Iterative--------------" << endl;
postorderIterative(root);
cout << endl;
cout << "----------Postorder Morris-----------------" << endl;
postorderMorris(root);
cout << endl; }
最新文章
- Ubuntu 一直掉线 以及连不上网 解决办法
- ClassNotFoundException: org.apache.catalina.loader.DevLoader 自己摸索,丰衣足食
- 第三篇——软件之殇,WE ARE THOUSANDS APART!
- IE WebBrowser事件触发
- Mobile testing基础之签名
- JSP学习初体验
- UserControl调用Umbraco的Data Types
- 【转】Android开发中adb启动失败adb连接异常的解决办法 offline
- java(try块语句变量,和匿名类变量生存时间
- look look C#7
- Oracle问题之ORA-12560TNS:协议适配器错误
- 模拟select选中option的效果
- CentOS_7下安装Nginx服务
- aizhan爱站关键字采集
- 雷林鹏分享:jQuery EasyUI 数据网格 - 创建自定义视图
- asp.net mvc接收安卓post的json字符串
- latex 公式 和排版
- javar入门——基本数据类型
- python selenium webdriver方法封装(find_element_by)
- JQuery extend()与工具方法、实例方法
热门文章
- Android中TextView添加删除线
- 编译生成IOS开发使用的FFmpeg的过程
- NSString 字符串替换
- php并发编程相关扩展
- a标签加入单击事件 屏蔽href跳转页面
- 服务器磁盘扩展卷时遭遇&ldquo;There is not enough space available on the disk(s) to complete this operation.&rdquo;错误
- Android程序函数 将assets文件夹下的文件复制到手机的sd卡中(包括子文件夹)
- 聚合及UML表示
- Python使用QRCode模块生成二维码
- sqlserver 用 RowNumber 分组