二叉树的创建以及遍历
#include <iostream>
#include <queue>
#include <stack>
#define NoInfo '0' // 用‘0’表示没有结点
using namespace std;
typedef char ElementType; // 假设结点数据是字符串类型
typedef struct TNode * Position; // 结点TNode定义为Position
typedef Position BinTree; // 重命名为二叉树
struct TNode { // 树的结点TNode定义
ElementType Data;
BinTree Left; // 指向左子树
BinTree Right; // 指向右子树
};
BinTree CreatBinTree(string str) {
// 创建二叉树,层序创建法
// 这里读入所有字符串str
ElementType Data;
BinTree BT, T;
queue<BinTree> Q; //创建空队列
int index = 0; // 字符串读取索引
// 建立第一个结点,即根节点
Data = str[index++]; // 读取根结点数据
if(Data != NoInfo) { // 如果根结点存在
BT = (BinTree)malloc(sizeof(struct TNode)); // 分配内存给新结点
BT->Data = Data;
BT->Left = BT->Right = NULL; // 初始化,新结点左右置空
Q.push(BT); // 新结点入队
}else return NULL; // 若根结点不存在,返回空树
// 取出队列元素添加孩子
while (!Q.empty()) {
T = Q.front();Q.pop(); // 取出队列元素并删除
// 添加左孩子
Data = str[index++]; // 读取下一个数据
if(Data == NoInfo) T->Left = NULL; // 若无左孩子,则置空
else { // 若有左孩子,则分配新节点,新结点入队
T->Left = (BinTree)malloc(sizeof(struct TNode)); // 分配新结点内存
T->Left->Data = Data;
T->Left->Left = T->Left->Right = NULL; // 初始化,新结点左右置空
Q.push(T->Left); // 新结点入队
}
// 添加右孩子
Data = str[index++]; // 读取下一个数据
if(Data == NoInfo) T->Right = NULL; // 若无右孩子,则置空
else { // 若有右孩子,则分配新结点,新结点入队
T->Right = (BinTree)malloc(sizeof(struct TNode)); // 分配新结点内存
T->Right->Data = Data;
T->Right->Left = T->Right->Right = NULL; // 初始化,新结点左右置空
Q.push(T->Right); // 新结点入队
} // 结束while
}
return BT; // 返回构建好的树BT
}
// 二叉树的访问操作
void Visit(BinTree T) {
cout << T->Data; // 打印结点数据Data
}
// 二叉树的遍历-递归法
void InorderTraveral(BinTree BT) {
// 中序遍历法
if(BT) {
InorderTraveral(BT->Left);
Visit(BT);
InorderTraveral(BT->Right);
}
}
void PreorderTraveral(BinTree BT) {
// 先序遍历法
if(BT) {
Visit(BT);
PreorderTraveral(BT->Left);
PreorderTraveral(BT->Right);
}
}
void PostorderTraveral(BinTree BT) {
// 后序遍历法
if(BT) {
PostorderTraveral(BT->Left);
PostorderTraveral(BT->Right);
Visit(BT);
}
}
// 非递归遍历
void InorderTraveral_NonRecursive(BinTree BT) {
// 中序遍历法
BinTree T;
stack<BinTree> s; // 创建空栈s,元素类型为BinTree
T = BT; // 从根结点出发
while (T || !s.empty()) { // 当当前结点不为空或者栈不为空时
while (T) { // 一直向左并将沿途结点压入堆栈
s.push(T); // 入栈
T = T->Left; // 一直向左,直到遇到叶子结点(无左孩子)
}
T = s.top(); s.pop(); // 弹出栈顶结点(原路返回一格)
Visit(T); // 访问结点
T = T->Right; // 转向右子树
}
}
void LevelorderTraveral(BinTree BT) {
// 层序遍历法
queue<BinTree> Q; // 创建空队列
BinTree T;
Q.push(BT); // 将根结点入队
while (!Q.empty()) { // 当队列非空,依次取出每个结点进行访问,并将其左右孩子依次入队
T = Q.front(); Q.pop(); // 结点出队
Visit(T); // 访问该结点
if(T->Left) Q.push(T->Left);
if(T->Right) Q.push(T->Right);
}
}
// 二叉树功能函数
int GetHeight(BinTree BT) {
// 递归法求二叉树树高
int HL, HR, MaxH;
if(BT) { // 如果二叉树非空
HL = GetHeight(BT->Left); // 求左子树高度
HR = GetHeight(BT->Right); // 求右子树高度
MaxH = HL > HR ? HL : HR; // 取左右子树较大高度者
return MaxH + 1; // 加上自身高度1
} // 如果二叉树为空
return 0; // 空树高度为0
}
void DestroyBinTree(BinTree BT) {
// 释放二叉树内存(可选,但建议添加)
if (BT) { // 后序遍历法删除所有结点
DestroyBinTree(BT->Left);
DestroyBinTree(BT->Right);
free(BT);
}
}
int main(int argc, char *argv[]) {
string input; // 定义输入的字符串input
cin >> input;
/* 输入ABCD0EF0G0HI0000000
* 树的结构如下:
* A
/ \
B C
/ / \
D E F
\ \ /
G H I
*/
BinTree B = CreatBinTree(input); // 创建二叉树
cout << "前序遍历(递归):"; PreorderTraveral(B); cout << endl;
cout << "中序遍历(递归):"; InorderTraveral(B); cout << endl;
cout << "后序遍历(递归):"; PostorderTraveral(B); cout << endl;
cout << "中序遍历(非递归):"; InorderTraveral_NonRecursive(B); cout << endl;
cout << "层序遍历(非递归):"; LevelorderTraveral(B); cout << endl;
cout << "树高:" << GetHeight(B) << endl;
DestroyBinTree(B); // 释放内存
}
前序遍历(递归):ABDGCEHFI
中序遍历(递归):DGBAEHCIF
后序遍历(递归):GDBHEIFCA
中序遍历(非递归):DGBAEHCIF
层序遍历(非递归):ABCDEFGHI
树高:4
608

被折叠的 条评论
为什么被折叠?



