废话不多说,直接堆代码。
Tree.h
typedef struct TreeNode{
struct TreeNode* lchild;
struct TreeNode* rchild;
char data;
}TreeNode;
main.cpp
#include<stdio.h>
#include<stdlib.h>
#include"Tree.h"
TreeNode* LCreateTree(); //创建二叉树
void FrontTraversal(TreeNode* t, int &numOfNode); //前序遍历二叉树 递归
void MidTraversal(TreeNode* t); //中序遍历二叉树
void BackTraversal(TreeNode* t); //后序遍历二叉树
void FrontTraversal_s(TreeNode* t, int numOfNode); //前序遍历二叉树 非递归
void MidTraversal_s(TreeNode* t, int numOfNode); //中序遍历二叉树
void BackTraversal_s(TreeNode* t, int numOfNode); //后序遍历二叉树
void LevelTraversal(TreeNode* t, int numOfNode); //层次遍历二叉树
int main() {
TreeNode* root;
root = LCreateTree(); //前序创建二叉树
int numOfNode = 0; //记录二叉树结点个数
//递归方法
FrontTraversal(root, numOfNode); //前序遍历二叉树
MidTraversal(root); //中序遍历二叉树
BackTraversal(root); //后序遍历二叉树
printf("%d\n", numOfNode);
//非递归方法
FrontTraversal_s(root, numOfNode); //前序遍历二叉树
MidTraversal_s(root, numOfNode); //中序遍历二叉树
BackTraversal_s(root, numOfNode); //后序遍历二叉树
LevelTraversal(root,numOfNode); //层次遍历二叉树
return 0;
}
TreeNode* LCreateTree() { //前序遍历二叉树
char c;
TreeNode* t;
c = getchar();
if (c == '#')
return NULL;
else {
t = (TreeNode*)malloc(sizeof(TreeNode));
t->data = c;
t->lchild = LCreateTree();
t->rchild = LCreateTree();
}
return t;
}
void FrontTraversal(TreeNode* t, int &numOfNode) {
TreeNode* p = t;
if (p) {
printf("%c ", p->data);
numOfNode++;
FrontTraversal(p->lchild, numOfNode);
FrontTraversal(p->rchild, numOfNode);
}
}
void MidTraversal(TreeNode* t) {
TreeNode* p = t;
if (p) {
MidTraversal(p->lchild);
printf("%c ", p->data);
MidTraversal(p->rchild);
}
}
void BackTraversal(TreeNode* t) {
TreeNode* p = t;
if (p) {
BackTraversal(p->lchild);
BackTraversal(p->rchild);
printf("%c ", p->data);
}
}
void FrontTraversal_s(TreeNode* t, int numOfNode) { //分治,对于每一个结点,先输出它的记录
TreeNode* stack; //然后压入右孩子,最后压入左孩子
stack = (TreeNode*)malloc(sizeof(TreeNode) * numOfNode);
int top = -1;
TreeNode* p;
p = (TreeNode*)malloc(sizeof(TreeNode));
if (t != NULL) {
top++;
stack[top] = *t;
while (top > -1) {
*p = stack[top];
top--;
printf("%c ", p->data);
if (p->rchild) { //压入右结点
top++;
stack[top] = *(p->rchild);
}
if (p->lchild) { //压入左结点
top++;
stack[top] = *(p->lchild);
}
}
}
printf("\n");
free(stack);
free(p);
}
void MidTraversal_s(TreeNode* t, int numOfNode) { //分治,先遍历到最左的结点,输出它的记录,出栈 ---1
TreeNode* stack; //然后看它有没有右子树,有重复1,没有就再取栈顶结点。
stack = (TreeNode*)malloc(sizeof(TreeNode) * numOfNode);
TreeNode* p;
p = (TreeNode*)malloc(sizeof(TreeNode) * numOfNode);
int top = -1;
if (t) {
p = t;
while (top > -1 || p) {
while (p) { //遍历到最左侧,同时不停压栈---1
top++;
stack[top] = *p;
p = p->lchild;
}
if (top > -1) {
p = &stack[top];
top--;
printf("%c ", p->data);
p = (p->rchild); //右子树重复1过程
}
}
}
printf("\n");
free(stack);
free(p);
}
void BackTraversal_s(TreeNode* t, int numOfNode) { //首先要遍历到最左侧,决定一个结点是否输出的是右孩子---1
TreeNode* stack[10]; //如果右孩子为NULL,由于该结点是最左侧(或则它的左子树已经输出)的结点,所以直接输出
TreeNode* p = NULL; //如果右孩子不为NULL,要判断右孩子是否已经输出,如果是,则输出,否,则让右孩子经历步骤1
TreeNode* b = t;
int top = -1;
int sign;
if (b) {
do {
while (b) { //遍历到最左侧
top++;
stack[top] = b;
b = b->lchild;
}
p = NULL;
sign = 1;
while (top != -1 && sign) { //判断右孩子
b = stack[top];
if (b->rchild == p) { //右子树已经输出
printf("%c ", b->data);
top--;
p = b;
}
else { //右孩子还没有遍历
b = b->rchild;
sign = 0;
}
}
} while (top > -1);
}
printf("\n");
}
void LevelTraversal(TreeNode* t, int numOfNode) { //借助队列层次输出二叉树
TreeNode *queue;
queue = (TreeNode*)malloc(sizeof(TreeNode) * numOfNode);
int num = 1; //每次加入队列的结点个数
int count = 0; //每次输出层次的起点
int size = 0; //中间记录变量
TreeNode *p = t;
if (p) {
queue[count] = *p;
while(num > 0) {
for (int j = count; j < count + num; j++) //从层次的起点输出num个结点的记录
printf("%c ", queue[j].data);
printf("\n");
TreeNode temp;
for (int i = count; i < count + num;) { //输出完一层后,得压入新的一层结点
temp = queue[i];
if (temp.lchild) { //压入已输出层结点的左孩子
queue[count + num + size] = *temp.lchild;
size++;
}
if (temp.rchild) { //压入已输出层结点的右孩子
queue[count + num + size] = *temp.rchild;
size++;
}
i++;
}
count += num; //层次起点更换
num = size; //新层次的结点数更换
size = 0; //临时记录归0
}
}
}