数据结构 二叉树的递归与非递归

数据结构 二叉树的递归与非递归

实例代码:

#include <iostream>
#include <queue>
#include <stack>
#include <assert.h>
using namespace std;
template<class T>
struct BinaryTreeNode
{
  BinaryTreeNode<T>* _left;
  BinaryTreeNode<T>* _right;
  T _data;
  BinaryTreeNode(const T& x)
    :_left(NULL)
    , _right(NULL)
    , _data(x)
  {}
    };
template <class T>
class BinaryTree
{
  typedef BinaryTreeNode<T> Node;
public:
  BinaryTree()
    :_root(NULL)
  {}
  BinaryTree(T* a, size_t n, const T& invalid)
  {
    size_t index = 0;
     _root=CreateTree(a, n, invalid, index);
  }
  BinaryTree(const BinaryTree<T>& t)
  {
    _root = _Copy(t._root);
  }
  BinaryTree<T>& operator=( BinaryTree<T>& t)
  {
    swap(_root,t._root);
    return *this;
  }
  ~BinaryTree()
  {
      _DestroyTree(_root);
  }
  Node* CreateTree(const T* a, size_t n, const T& invalid, size_t& index)
  {
    assert(a);
    Node* root = NULL;
    if (index < n && a[index] != invalid)
    {
      root = new Node(a[index]);
      root->_left = CreateTree(a, n, invalid, ++index);
      root->_right = CreateTree(a, n, invalid, ++index);
    }
    return root;
  }

 先序遍历(递归法)  

 void PrevOrder()
  {
    _PrevOrder(_root);
    cout << endl;
  }
  //先序遍历非递归
  void PrevOrderNorR( )
  {
    Node* cur = _root;
    stack< Node* >s;
    while (cur||!s.empty())
    {
      while (cur)
      {
        cout << cur->_data << " ";
        s.push(cur);
        cur = cur->_left;
      }
      Node* top = s.top();
      s.pop();
      cur = top->_right;
    }
    cout << endl;
  }

后序遍历     

 void PostOrder()
  {
    _PostOrder(_root);
    cout << endl;
  }
  //后序遍历非递归
  void PostOrderNorR()
  {
      Node* cur = _root;
      Node* prev = NULL;
      stack< Node* >s;
      while (cur || !s.empty())
      {
        while (cur)
        {
          s.push(cur);
          cur = cur->_left;
        }
        Node* top = s.top();
        if (NULL==top->_right && prev==top->_right)
        {
          cout << top->_data << " ";
           s.pop();
           prev = top;
        }
        cur = top->_right;
      }
      cout << endl;
  } 

  //中序遍历
  void InOrder()
  {
    _InOrder(_root);
    cout << endl;
  }
  //中序遍历非递归
  void InOrderNorR()
  {
    Node* cur = _root;
    stack< Node* >s;
    while (cur || !s.empty())
    {
      while (cur)
      {
        s.push(cur);
        cur = cur->_left;
      }
      Node* top = s.top();
      s.pop();
      cout << top->_data << " ";
      cur = top->_right;
    }
    cout << endl;
  } 

  //节点个数
  size_t Size()
  {
    return _Size(_root);
  }
  //叶子节点个数
  size_t LeafSize()
  {
    return _LeafSize(_root);
  }
  //树的深度
  size_t Depth()
  {
    return _Depth(_root);
  }
  size_t GetKLevel(size_t k)
  {
    return _GetKLevel(_root,k);
  }
  // 查找
  Node* Find(size_t x)
  {
    return _Find(_root,x);
  }
  //层序遍历
  void LevelOrder()
  {
    queue<Node*> q;
    if (_root)
    {
      q.push(_root);
    }
    while (!q.empty())
    {
      Node* front = q.front();
      cout << front->_data << " ";
      q.pop();
      if (front->_left)
      {
        q.push(front->_left);
      }
      if (front->_right)
      {
        q.push(front->_right);
      }
    }
    cout << endl;
  } 

protected:
  Node* _Copy(Node* root)
  {
    if (root==NULL)
    {
      return NULL;
    }
    Node* NewRoot = new Node(root->_data);
    NewRoot->_left = _Copy(root->_left);
    NewRoot->_right = _Copy(root->_right);
    return NewRoot;
  }
  void _DestroyTree(Node* root)
  {
    if (NULL==root)
    {
      return;
    }
   _DestroyTree(root->_left);
   _DestroyTree(root->_right);
   delete root;
  }
  void _PrevOrder(BinaryTreeNode<T>* root)
  {
    if (root)
    {
      cout << root->_data << " ";
      _PrevOrder(root->_left);
      _PrevOrder(root->_right);
    }
  }
  void _PostOrder(BinaryTreeNode<T>* root)
  {
    if (root)
    {
      _PostOrder(root->_left);
      _PostOrder(root->_right);
      cout << root->_data << " ";
    }
  }
  void _InOrder(BinaryTreeNode<T>* root)
  {
    if (root)
    {
      _InOrder(root->_left);
      cout << root->_data << " ";
      _InOrder(root->_right); 

    }
  }
  int _Size(BinaryTreeNode<T>* root)
  {
   if (root==0)
   {
     return 0;
   }
   return _Size(root->_left) + _Size(root->_right) + 1;
  }
  int _LeafSize(BinaryTreeNode<T>* root)
  {
    if (root==NULL)
    {
    return 0;
    }
    else if (root->_left == NULL&&root->_right == NULL)
    {
      return 1;
    }
    return _LeafSize(root->_left) + _LeafSize(root->_right);
  }
  int _Depth(Node* root)
  {
    if (root==NULL)
    {
      return 0;
    }
    int left = _Depth(root->_left);
    int right = _Depth(root->_right);
    return left > right ? left + 1 : right + 1;
  } 

  int _GetKLevel(Node* root, size_t k)
  {
    assert(k>0);
    if (root==NULL)
    {
      return 0;
    }
    else if (k==1)
    {
      return 1;
    }
    return _GetKLevel(root->_left, k - 1) + _GetKLevel(root->_right, k - 1);
  }
  Node* _Find(Node* root, const T& x)
  {
    if (root==NULL)
    {
      return NULL;
    }
    if (root->_data==x)
    {
      return root;
    }
    Node* ret = _Find(root->_left,x);
    if (ret != NULL)
      return ret;
    return _Find(root->_right, x);
  } 

  private:
  BinaryTreeNode<T>* _root;
};
void TestBinaryTree()
{
  int array[10] = { 1, 2, 3, '#', '#', 4, '#', '#', 5, 6 };
  BinaryTree<int> t1(array,sizeof(array)/sizeof(array[0]),'#');
  BinaryTree<int>t2(t1);
  BinaryTree<int> t3;
  t3 = t2;
  t2.LevelOrder();
  t3.LevelOrder();
  t1.LevelOrder();
  t1.PrevOrder();
  t1.PrevOrderNorR();
  t1.InOrder();
  t1.InOrderNorR();
  t1.PostOrder();
  t1.PostOrderNorR();
  cout << endl;
  cout << t1.Size() << endl;
  cout << t1.LeafSize() << endl;
  cout << t1.Depth() << endl; 

  cout << t1.GetKLevel(2) << endl;
  cout << t1.Find(2) << endl;
}

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

(0)

相关推荐

  • C++非递归建立二叉树实例

    本文实例讲述了C++非递归建立二叉树的方法.分享给大家供大家参考.具体分析如下: 思路: 设置一个标记变量flag并初始化为1. flag = 1表示现在需要创建当前结点的左孩子,2表示需要创建右孩子,3则表示当前结点的左右孩子都已经创建完毕,需要执行出栈操作,直到当前结点不是父结点的右孩子为止. 以先序创建如图所示二杈树: 实现代码: PBTree create() { char ch[20]; scanf("%s",ch); int len = strlen(ch); PBTree

  • C语言数据结构之二叉树的非递归后序遍历算法

    C语言数据结构之二叉树的非递归后序遍历算法 前言: 前序.中序.后序的非递归遍历中,要数后序最为麻烦,如果只在栈中保留指向结点的指针,那是不够的,必须有一些额外的信息存放在栈中. 方法有很多,这里只举一种,先定义栈结点的数据结构 typedef struct{Node * p; int rvisited;}SNode //Node 是二叉树的结点结构,rvisited==1代表p所指向的结点的右结点已被访问过. lastOrderTraverse(BiTree bt){ //首先,从根节点开始,

  • C++基于递归和非递归算法判定两个二叉树结构是否完全相同(结构和数据都相同)

    本文实例讲述了C++基于递归和非递归算法判定两个二叉树结构是否完全相同.分享给大家供大家参考,具体如下: /*两个二叉树结构是否相同(结构和数据都相同) -- 递归和非递归方法 经调试可运行源码及分析如下: ***/ #include <stdlib.h> #include <iostream> #include <queue> using std::cout; using std::cin; using std::endl; using std::queue; /*二

  • C++ 数据结构二叉树(前序/中序/后序递归、非递归遍历)

    C++ 数据结构二叉树(前序/中序/后序递归.非递归遍历) 二叉树的性质: 二叉树是一棵特殊的树,二叉树每个节点最多有两个孩子结点,分别称为左孩子和右孩子. 例: 实例代码: #include <iostream> #include <Windows.h> #include <stack> using namespace std; template <class T> struct BinaryTreeNode { int _data; BinaryTree

  • C++非递归队列实现二叉树的广度优先遍历

    本文实例讲述了C++非递归队列实现二叉树的广度优先遍历.分享给大家供大家参考.具体如下: 广度优先非递归二叉树遍历(或者说层次遍历): void widthFirstTraverse(TNode* root) { queue<TNode*> q; // 队列 q.enqueue(root); TNode* p; while(q.hasElement()) { p = q.dequeue(); // 队首元素出队列 visit(p); // 访问p结点 if(p->left) q.enqu

  • C++使用递归和非递归算法实现的二叉树叶子节点个数计算方法

    本文实例讲述了C++使用递归和非递归算法实现的二叉树叶子节点个数计算方法.分享给大家供大家参考,具体如下: /*求二叉树叶子节点个数 -- 采用递归和非递归方法 经调试可运行源码及分析如下: ***/ #include <stdlib.h> #include <iostream> #include <stack> using std::cout; using std::cin; using std::endl; using std::stack; /*二叉树结点定义*/

  • C++基于递归和非递归算法求二叉树镜像的方法

    本文实例讲述了C++基于递归和非递归算法求二叉树镜像的方法.分享给大家供大家参考,具体如下: /*求二叉树镜像 -- 采用递归和非递归方法 经调试可运行源码及分析如下: ***/ #include <stdlib.h> #include <iostream> #include <queue> using std::cout; using std::cin; using std::endl; using std::queue; /*二叉树结点定义*/ typedef st

  • 数据结构 二叉树的递归与非递归

    数据结构 二叉树的递归与非递归 实例代码: #include <iostream> #include <queue> #include <stack> #include <assert.h> using namespace std; template<class T> struct BinaryTreeNode { BinaryTreeNode<T>* _left; BinaryTreeNode<T>* _right; T

  • Java二叉树的四种遍历(递归与非递归)

    目录 一.先序遍历与后序遍历 二.中序遍历 三.层序遍历 一.先序遍历与后序遍历 先序遍历根节点,再遍历左子树,再遍历右子树. 后序遍历先遍历左子树,再遍历右子树,再遍历根节点. 先序遍历递归实现: public static void preOrderByRecursion(TreeNode root) { // 打印节点值 System.out.println(root.value); preOrder(root.left); preOrder(root.right); } 先序遍历的非递归

  • Java二叉树的四种遍历(递归和非递归)

    二叉树的遍历可以分为前序.中序.后序.层次遍历. 前中后是指何时访问中间节点,即前序遍历,遍历节点的顺序为:中->左->右: 中序遍历,遍历节点的顺序为:左->中->右: 后序遍历,遍历节点的顺序为:左->右->中. 前序遍历 递归实现 public void preorder_Traversal(TreeNode root) { if(root==null)return; //访问节点的逻辑代码块 System.out.print(root.val+" &q

  • java二叉树的几种遍历递归与非递归实现代码

    前序(先序)遍历 中序遍历 后续遍历 层序遍历 如图二叉树: 二叉树结点结构 public class TreeNode { int val; TreeNode left; TreeNode right; TreeNode(int x){ val=x; } @Override public String toString(){ return "val: "+val; } } 访问函数 public void visit(TreeNode node){ System.out.print(

  • Java开发深入分析讲解二叉树的递归和非递归遍历方法

    目录 前言 1.递归遍历 2.非迭代遍历 3.二叉树的统一迭代法 前言 二叉树的遍历方法分为前序遍历,中序遍历,后续遍历,层序遍历. 1.递归遍历 对于递归,就不得不说递归三要素:以前序遍历为例 递归入参参数和返回值 因为要打印出前序遍历节点的数值,所以参数里需要传入List在放节点的数值,除了这一点就不需要在处理什么数据了也不需要有返回值,所以递归函数返回类型就是void,代码如下: public void preorder(TreeNode root, List<Integer> resu

  • python如何实现递归转非递归

    先说总结,这种方案总的来说就是机械化的强转,时间复杂度和空间复杂度没什么变化,唯二的优点可能是1. 不会爆栈,2. 节省了函数调用的开销 而且最终产出的代码效果不那么美观,比较冗长 思路是:当发生递归调用时,模拟函数调用的 压栈 .并处理 入参 和 返回值 和 记录返回到当前栈的时候该继续从哪里执行 以如下递归( leetcode爬楼梯 )为例 def f(n): if n <= 2: return n return f(n - 1) + f(n - 2) 第一步: 将涉及到递归调用的,单独变成

  • Java编程二项分布的递归和非递归实现代码实例

    本文研究的主要内容是Java编程二项分布的递归和非递归实现,具体如下. 问题来源: 算法第四版 第1.1节 习题27:return (1.0 - p) * binomial(N - 1, k, p) + p * binomial(N - 1, k - 1, p); 计算递归调用次数,这里的递归式是怎么来的? 二项分布: 定义:n个独立的是/非试验中成功次数k的离散概率分布,每次实验成功的概率为p,记作B(n,p,k). 概率公式:P(ξ=K)= C(n,k) * p^k * (1-p)^(n-k

  • 分析python动态规划的递归、非递归实现

    概要 本文只是简单的介绍动态规划递归.非递归算法实现 案例一 题目一:求数组非相邻最大和 [题目描述] 在一个数组arr中,找出一组不相邻的数字,使得最后的和最大. [示例输入] arr=1 2 4 1 7 8 3 [示例输出] 15 from functools import wraps def memoDeco(func): ''' memoDeco主要是缓存已遍历的节点,减少递归内存开销 ''' cashe={} @wraps(func) def wrapper(*args): if ar

  • JAVA递归与非递归实现斐波那契数列

    斐波那契数列(Fibonacci sequence),又称黄金分割数列.因数学家列昂纳多·斐波那契(Leonardoda Fibonacci[1] )以兔子繁殖为例子而引入,故又称为"兔子数列",指的是这样一个数列:0.1.1.2.3.5.8.13.21.34.--在数学上,斐波纳契数列以如下被以递归的方法定义:F(0)=0,F(1)=1,F(n)=F(n-1)+F(n-2)(n≥2,n∈N*)在现代物理.准晶体结构.化学等领域,斐波纳契数列都有直接的应用,为此,美国数学会从1963起

随机推荐