借助了点集成好的函数和STL,仅供参考
#include <iostream>
#include "cstring"
#include<stack>
#include<queue>
using namespace std;
struct tree {
int data;//数据域
tree* lc, * rc;//指针域,指向左右节点
};//用链表存储树节点
//创建二叉树(递归)
void Create(tree*& T, int e)
{
//如果指向的地址为空,则创建空间并将数据e赋值进去形成新节点
if (!T) {
tree* p = new tree;
p->data = e;
p->lc = p->rc = NULL;
T = p;
}
else if (e < T->data)Create(T->lc, e);//如果数据e比当前节点的数据域小,则访问其左子树
else if (e > T->data)Create(T->rc, e);//如果数据e比当前节点的数据域大,则访问其右子树
}
//前序遍历
void PreOrderTraverse(tree* T) {
if (!T)return;
cout << T->data << ' ';
PreOrderTraverse(T->lc);
PreOrderTraverse(T->rc);
} // PreOrderTraverse
//中序遍历
void InOrderTraverse(tree* T) {
if (!T)return;
InOrderTraverse(T->lc);
cout << T->data << ' ';
InOrderTraverse(T->rc);
} // InOrderTraverse
//后序遍历
void PostOrderTraverse(tree* T) {
if (!T)return;
PostOrderTraverse(T->lc);
PostOrderTraverse(T->rc);
cout << T->data << ' ';
} // PostOrderTraverse
//查找要查找的数据data是否在该二叉排序树里,有返回1,没有则返回0(递归)
void Find(tree* T, int data) {
if (!T) {
cout << 0 << endl;
return;
}
if (data < T->data)Find(T->lc, data);
else if (data > T->data)Find(T->rc, data);
else {
cout << 1 << endl;
return;
}
}
//插入数据e到二叉排序树中(递归)
void Insert(tree*& T, int e)
{
//原理与上面的创建差不多
if (!T) {
tree* p = new tree;
p->data = e;
p->lc = p->rc = NULL;
T = p;
}
else if (e < T->data)Insert(T->lc, e);
else if (e > T->data)Insert(T->rc, e);
}
//中序遍历(非递归,但借助栈)
void InOrderTraverse2(tree* T) {
if (!T)
return;
stack<tree*> s;
tree* p = T;//p先指向根节点
//实际上就是用栈模拟中序遍历的遍历过程
while (!s.empty() || p)//只要栈不空或者p不指向空,就继续运行
{
//利用栈先进后出的特点实现中序遍历
while (p)//只要p非空就运行
{
s.push(p);//把p塞入栈
p = p->lc;//p指向其左子树
}
if (!s.empty())//如果栈非空
{
p = s.top();//读取栈顶
s.pop();//弹出栈顶
cout << p->data << ' ';//输出当前节点数据域
p = p->rc;//p指向右节点
}
}
}
//层序遍历(有点不熟悉)
//用到队列,可以用queue,但其实用普通的数组模拟队列就行
void LeOrder(tree* T) {
tree* q[1000];//树的指针的队列
int f = 0, r = 0;
if (T)//非空树
q[r++] = T;
//实际上就相当于两个指针,一个指针访问并输出数据域,
//另外一个趁机将第一个访问的该节点的左右指针域存到队列以便于下次访问
while (f != r)
{
tree* temp = q[f++];//出队
cout << temp->data << ' ';
if (temp->lc)
q[r++] = temp->lc;//入队
if (temp->rc)
q[r++] = temp->rc;//入队
}
}
//小写的swap是提供的函数,大写的Swap是自定义函数
//交换左右子树(递归)
void Swap(tree*& T) {
if (!T)return;
swap(T->lc, T->rc);
Swap(T->lc);
Swap(T->rc);
}
//得二叉树的高度(递归)
int Getheight(tree* T) {
if (!T)return 0;
return max(Getheight(T->lc), Getheight(T->rc)) + 1;
//每次递归返回上一层时都将该层最大值往上传递并且+1,利用max函数得出最大值就是整个二叉树的高度
}
//得出二叉树的叶子节点数
int Getnum(tree* T) {
if (!T)return 0;//该指针为空则表示没节点,返回0
if (!T->lc && !T->rc)return 1;//指针指向的节点左右指针域为空,则返回1
return Getnum(T->lc) + Getnum(T->rc);
//将本节点的左右子树统计出来的叶子节点数得到当前节点作为根这一子树的叶子节点数,并向上一层递归传递
}
int main()
{
tree* T = NULL;
int n, e;
cin >> n;
while (n--) {//创建有n个节点的二叉排序树
cin >> e;
Create(T, e);
}
{//前中后序遍历
PreOrderTraverse(T); cout << endl;
InOrderTraverse(T); cout << endl;
PostOrderTraverse(T); cout << endl;
}
{
cin >> e; Find(T, e); //找二叉排序树中是否存在该数据
cin >> e; Find(T, e); //找二叉排序树中是否存在该数据
cin >> e; Insert(T, e);//插入数据e到二叉排序树中
}
{//插入数据e后的前中后序遍历
PreOrderTraverse(T); cout << endl;
InOrderTraverse(T); cout << endl;
PostOrderTraverse(T); cout << endl;
}
//中序遍历(非递归)
InOrderTraverse2(T); cout << endl;
//层序遍历
LeOrder(T); cout << endl;
//交换左右子树
Swap(T);
{//前中后序遍历+3
PreOrderTraverse(T); cout << endl;
InOrderTraverse(T); cout << endl;
PostOrderTraverse(T); cout << endl;
}
//交换左右子树+2
Swap(T);
{//前中后序遍历+4
PreOrderTraverse(T); cout << endl;
InOrderTraverse(T); cout << endl;
PostOrderTraverse(T); cout << endl;
}
//得到二叉树高度
cout << Getheight(T) << endl;
//得到叶子节点数
cout << Getnum(T) << endl;
}