廢話不多說,直接堆代碼。
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
}
}
}