非递归中序遍历二叉树的应用

今天在准备武汉理工考研复试的时候看到这么一道题,使用非递归函数计算二叉树的单节点个数。 由于有很长一段时间没有写有关树的编程了,去网上搜了下信息结合自己之前的笔记,完成了这道题。 学习篇(2)

首先,回忆如何建立二叉树。建立二叉树是使用递归的方法,由于在键盘上输入并不方便。将待输入的放在txt中更好,只不过格式必须没错,不然会触发异常。输入格式例子 1 2 4 # # 5 # # 3 4 # # #
把它存在txt文件中,名字为data.txt。想改成什么就改成什么,不必每次调试都输入
建立出的二叉树应该是这个样子
在这里插入图片描述

先上代码

#include "pch.h"
#include <iostream>
#include <fstream>
#include <stack>

using namespace std;

ifstream input;
typedef struct TreeNode
{
 char data;
 struct TreeNode *lchild;
 struct TreeNode *rchild;
}TreeNode;

TreeNode* CreateTreeNode()
{
 TreeNode *p;
 char tmp;
 input >> tmp;  //文件流向后读取一个字符,空格忽略
 if (tmp == '#')
 {
  p = NULL;
 }
 else
 {
  p = new TreeNode;
  p->data = tmp;
  p->lchild = CreateTreeNode();
  p->rchild = CreateTreeNode();
 }
 return p;
}

void InOrderTraverse(TreeNode *T) //先回忆下中序递归遍历
{
 if (T != NULL)
 {
  InOrderTraverse(T->lchild);
  cout << T->data<<' ';
  InOrderTraverse(T->rchild);
 }
}
void InOrderTravel(TreeNode *Tree) //回忆下非递归中序遍历二叉树
{
 TreeNode *T = Tree;
 stack<TreeNode> st; //非递归遍历的话就必须得存储从根节点走下来得路径,用栈来模拟
 while (T || !st.empty())  //T代表得是当前得节点
 {
  while (T)  //当前节点不空 就一直向左走且存到栈
  {
   st.push(*T);
   T = T->lchild;
  }
  if (!st.empty()) //到这里说明左边空了,此时如果栈中有节点,也就可以弹出来,访问它了
  {
   T = &st.top();  //注意T是指针
   st.pop();
   cout << T->data << ' ';
   T = T->rchild;  //T访问完了,此时可以进入它的右分支了 重复以上操作
  //这段代码需要好好理解  最好画图 自己走一遍过程,然后就可以懂了。但是不一定会写,所以要练习
  }
 }
}
int MyFunc(TreeNode *Tree) //非递归中序遍历计算单节点个数,这个就直接应用非递归中序遍历了
{
 int count = 0;
 TreeNode *T = Tree;
 stack<TreeNode> st;
 while (T || !st.empty())
 {
  while (T)
  {
   st.push(*T);
   T = T->lchild;
  }
  if (!st.empty())
  {
   T = &st.top();
   st.pop();
   if (T->lchild == NULL && T->rchild != NULL) count++; //可以把这俩行代码看作遍历时需要对节点的操作,
   else if (T->rchild == NULL && T->lchild != NULL) count++;
   T = T->rchild;
  }
 }
 return count;
} //这种非递归遍历 可以解决二叉树中的许多问题,考试还是很有用的。初试也考过
int main()
{
 input.open("F:\\AlgorithmPRJ\\树编程\\data.txt"); //这就是存放待输入文件txt的路径
 if (!input.is_open()) return -1;
 TreeNode *T = CreateTreeNode(); //建树
 cout << "中序遍历..." << endl;
 InOrderTraverse(T);
 cout << endl;
 cout << "非递归中序遍历.." << endl;
 InOrderTravel(T);
 cout << endl;
 cout << "非递归遍历二叉树得二叉树单节点个数为" << MyFunc(T) << endl;
 return 0;
 }

小结下吧:其实树的编程说复杂也复杂,看代码想的头疼,说简单也简单。主要是画一下图 多走几遍流程就懂了。然而算法看的懂不代表会写,多多练习 受益匪浅。

PS:好多算法 都忘光了,我会一一捡起来更新…fresh bird一只,有错误希望指正。

猜你喜欢

转载自blog.csdn.net/MikeBoat/article/details/88181605