博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
算法导论12.1-3习题解答(非递归中序遍历)
阅读量:7064 次
发布时间:2019-06-28

本文共 3110 字,大约阅读时间需要 10 分钟。

CLRS 12.1-3:

给出一个非递归的中序树遍历算法。(提示:有两种方法,在较容易的方法中,可以采用栈作为辅助数据结构;在较为复杂的方法中,不采用栈结构,但假设可以测试两个指针是否相等。)

算法思想:

1.采用栈的话,先寻找最左边的节点,把经过的节点都存入栈中,第一个被弹出来的为最左节点,那么访问其右子树,对右子树也像前面一样遍历,整个流程跟递归一样。

2.不采用栈的话,先是访问最左节点,然后访问其右子树,然后回溯到最左节点的父节点,不断重复这个过程,思路还是一样。这里参考了重剑无锋的

构造的树的树如下:

#include
<
iostream
>
#include
<
time.h
>
using
namespace
std;
class
Node
{
public
:
  int
data;
  Node
*
left;
  Node
*
right;
  Node
*
parent;
  bool
visited;
  //
Node(){}
  Node(
int
d);
  Node(
int
d, Node
*
l, Node
*
r);
};
class
BinaryTree
{
public
:
  Node
*
root;
  BinaryTree(Node
*
r);
  //
递归实现中序遍历
  void
recurse_in_order_visit(Node
*
root);
  //
非递归用栈实现中序遍历
  void
non_recurse_using_stack_in_order_visit(Node
*
root);
  //
非递归且不用栈实现中序遍历
  void
non_recurse_non_stack_in_order_visit(Node
*
root);
  enum
TRAVESAL_STATE
  {
    LEFT_NOT_TRAVERS,
//
左子树未遍历
    LEFT_TRAVERSED,
//
左子树已遍历(包括左子树为空)
    RIGHT_TRAVERSED
//
右子树已遍历(右子树为空)
  };
};
int
main()
{
  Node
*
node1
=
new
Node(
1
, NULL, NULL);
  Node
*
node2
=
new
Node(
2
, node1, NULL);
  Node
*
node3
=
new
Node(
4
, NULL, NULL);
  Node
*
node4
=
new
Node(
3
, node2, node3);
  Node
*
node5
=
new
Node(
7
, NULL, NULL);
  Node
*
node6
=
new
Node(
6
, NULL, node5);
  Node
*
node7
=
new
Node(
9
, NULL, NULL);
  Node
*
node8
=
new
Node(
8
, node6, node7);
  Node
*
root
=
new
Node(
5
, node4, node8);
  BinaryTree
*
binary_tree
=
new
BinaryTree(root);
  cout
<<
"
递归中序遍历的结果:
"
<<
endl;
  binary_tree
->
recurse_in_order_visit(binary_tree
->
root);
  cout
<<
endl;
  cout
<<
"
非递归用栈中序遍历的结果:
"
<<
endl;
  binary_tree
->
non_recurse_using_stack_in_order_visit(binary_tree
->
root);
  cout
<<
endl;
  //
若使用非递归且不用栈来进行中序遍历,则需要parent指针作为辅助
  node1
->
parent
=
node2;
  node2
->
parent
=
node4;
  node3
->
parent
=
node4;
  node5
->
parent
=
node6;
  node6
->
parent
=
node8;
  node7
->
parent
=
node8;
  node4
->
parent
=
root;
  node8
->
parent
=
root;
  cout
<<
"
非递归且不用栈中序遍历的结果:
"
<<
endl;
  binary_tree
->
non_recurse_non_stack_in_order_visit(binary_tree
->
root);
  cout
<<
endl;
  return
0
;
}
Node::Node(
int
d)
{
  data
=
d;
  parent
=
left
=
right
=
NULL;
  visited
=
false
;
}
Node::Node(
int
d, Node
*
l, Node
*
r)
{
  data
=
d;
  left
=
l;
  right
=
r;
  parent
=
NULL;
  visited
=
false
;
}
BinaryTree::BinaryTree(Node
*
r)
{
  root
=
r;
}
//
递归实现中序遍历
void
BinaryTree::recurse_in_order_visit(Node
*
root)
{
  if
(root
!=
NULL)
  {
    recurse_in_order_visit(root
->
left);
    printf(
"
%d\t
"
, root
->
data);
    recurse_in_order_visit(root
->
right);
  }
}
//
非递归用栈实现中序遍历
void
BinaryTree::non_recurse_using_stack_in_order_visit(Node
*
root)
{
  Node
*
stack[
9
];
  int
top
=
-
1
;
  while
(root
!=
NULL
||
top
>
-
1
)
  {
    while
(root
!=
NULL)
    {
      stack[
++
top]
=
root;
      root
=
root
->
left;
    }
    if
(top
>
-
1
)
    {
      root
=
stack[top
--
];
      printf(
"
%d\t
"
, root
->
data);
      root
=
root
->
right;
    }
  }
}
//
非递归且不用栈实现中序遍历
void
BinaryTree::non_recurse_non_stack_in_order_visit(Node
*
root)
{
  while
( root
!=
NULL )
  {
    while
( root
->
left
!=
NULL
&&
!
root
->
left
->
visited )
    {
      //
一路向左
      root
=
root
->
left;
    }
    if
(
!
root
->
visited )
    {
      cout
<<
root
->
data
<<
"
\t
"
;
      root
->
visited
=
true
;
    }
    if
( root
->
right
!=
NULL
&&
!
root
->
right
->
visited )
    {
      //
右子树
      root
=
root
->
right;
    }
    else
    {
      //
回溯至parent节点
      root
=
root
->
parent;
    }
  }
}

 

转载地址:http://bwnll.baihongyu.com/

你可能感兴趣的文章
LeetCode OJ:Maximal Square(最大矩形)
查看>>
抽象工厂 C++实现
查看>>
[KMP]字符串匹配算法
查看>>
[转] 随机数是骗人的,.Net、Java、C为我作证
查看>>
第一天
查看>>
VUE基础插值表达式
查看>>
如何在mysql客户端即mysql提示符下执行操作系统命令
查看>>
人月神话读后感
查看>>
Learning Agile software Development
查看>>
HDFS原理解析(整体架构,读写操作流程及源代码查看等)
查看>>
“精于算计”与“精于计算”我们应该更偏重哪方面?
查看>>
CAFFE安装(10):Mnist测试(可不做)
查看>>
7.2.7、数组指针的操作
查看>>
SetProp()、GetProp()、RemoveProp() API接口
查看>>
ES6 module模块
查看>>
content management system
查看>>
缓存穿透 缓存雪崩
查看>>
System.gc
查看>>
最小二乘法多项式曲线拟合原理与实现(转)
查看>>
Java NIO 系列教程(转)
查看>>