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