文章目录
- 前言
- 思路
-
- 设计思想
- 非递归前序遍历的思路
- 非递归中序遍历的思路
- 非递归后序遍历的思路
- 层序遍历的思路
- 完整代码
-
- MyBinaryTree.h
- MyBinaryTree.cpp
- Main.cpp
- 效果展示
前言
- 作者水平有限,全部的代码是学习前人+部分原创
- 不要搬代码,一定要借鉴学习,自己动手!!!
思路
设计思想
- 二叉树的创建:采用先序遍历的顺序,依次写出每个非空节点的数值,如果没有孩子节点就用$符号代替。并采用递归的方式进行实现,依次创建根节点、所有的左子树、右子树
- 二叉树的前、中、后序的递归遍历:本质上的遍历顺序都是一样的,只是打印的时机不同,控制好打印的时机即可。
非递归前序遍历的思路
- 栈s初始化;
- 循环直到p为空且栈s为空
- 当p不空时循环
- 输出p->data;
- 将指针p的值保存到栈中;
- 继续遍历p的左子树
- 当p为空,栈s不空,则
- 将栈顶元素弹出至p;
- 准备遍历p的右子树;

非递归中序遍历的思路
- 栈s初始化;
- 访问左孩子,左孩子存在继续步骤1;
- 左孩子不存在弹出函数栈帧;
- 访问右孩子,右孩子存在继续步骤1;
- 右孩子不存在弹出函数栈帧,访问该节点;
- 弹出函数栈帧,返回上一级函数栈帧。
非递归后序遍历的思路
- 从当前节点开始遍历:
- 若当前节点存在,就存入栈中,并且置节点flag为1(第一次访问),然后访问其左子树;
- 直到当前节点不存在,需要回退,这里有两种情况:
- 当栈顶节点flag为0时,则表明是从左子树回退,这时需置栈顶节点flag为2(第二次访问),然后通过栈顶节点访问其右子树(取栈顶节点用,但不出栈)
- 当栈顶节点flag为1时,则表明是从右子树回退,这时需出栈,并取出栈节点做访问输出。
- 不断重复12,直到当前节点不存在且栈空。
层序遍历的思路
- 从上到下,从左到右,则利用队列存放各子树结点的指针,初始时把根节点入队,当根结点出队后,令其左、右孩子结点入队(空不入队),而左孩子出队时又令它的左右孩子结点入队,……由此便可产生按层次输出的效果。

完整代码
MyBinaryTree.h
#pragma once
#include
using namespace std;
typedef char E;
typedef struct TreeNode {
E element;
struct TreeNode* left, * right;
int flag;
}*Node;
typedef Node T;
typedef struct StackNode {
T element;
struct StackNode* next;
} *SNode;
typedef struct QueueNode {
T element;
struct QueueNode* next;
}*QNode;
typedef struct Queue {
QNode front, rear;
}*LinkedQueue;
Node createBiTree(Node& root);
void preOrder(Node root);
void inOrder(Node root);
void postOrder(Node root);
void initStack(SNode head);
int pushStack(SNode head, T element);
int IsEmpty(SNode head);
T peekStack(SNode head);
T popStack(SNode head);
void preOrder2(Node root);
void inOrder0(Node root);
void inOrder2(Node root);
void postOrder2(Node root);
int initQueue(LinkedQueue queue);
int offerQueue(LinkedQueue queue, T element);
int isEmpty(LinkedQueue queue);
T pollQueue(LinkedQueue queue);
void levelOrder(Node root);
int getDepthTreeNode(Node root);
MyBinaryTree.cpp
#include"MyBinaryTree.h"
Node createBiTree(Node& root) {
char ch;
cin >> ch;
if (ch == '$') {
root = NULL;
}
else {
root = (Node)malloc(sizeof(struct TreeNode));
root->element = ch;
createBiTree(root->left);
createBiTree(root->right);
}
return root;
}
void preOrder(Node root) {
if (root != NULL) {
cout << root->element << " ";
preOrder(root->left);
preOrder(root->right);
}
}
void inOrder(Node root) {
if (root == NULL) return;
inOrder(root->left);
cout << root->element << " ";
inOrder(root->right);
}
void postOrder(Node root) {
if (root == NULL) return;
postOrder(root->left);
postOrder(root->right);
cout << root->element << " ";
}
void initStack(SNode head) {
head->next = NULL;
}
int pushStack(SNode head, T element) {
SNode node = (SNode)malloc(sizeof(struct StackNode));
if (node == NULL) return 0;
node->next = head->next;
node->element = element;
head->next = node;
return true;
}
int IsEmpty(SNode head) {
return head->next == NULL;
}
T peekStack(SNode head) {
return head->next->element;
}
T popStack(SNode head) {
SNode top = head->next;
head->next = head->next->next;
T e = top->element;
free(top);
return e;
}
void preOrder2(Node root) {
struct StackNode stack;
initStack(&stack);
while (root || !IsEmpty(&stack)) {
while (root) {
cout << root->element << " ";
pushStack(&stack, root);
root = root->left;
}
Node node = popStack(&stack);
root = node->right;
}
}
void inOrder2(Node root) {
struct StackNode stack;
initStack(&stack);
while (root || !IsEmpty(&stack)) {
while (root) {
pushStack(&stack, root);
root = root->left;
}
Node node = popStack(&stack);
cout << node->element << " ";
root = node->right;
}
}
void inOrder0(Node root) {
struct StackNode stack;
initStack(&stack);
T p;
pushStack(&stack, root);
while (!IsEmpty(&stack)) {
while ((p = peekStack(&stack)) && p) {
pushStack(&stack, p->left);
}
p = popStack(&stack);
if (!IsEmpty(&stack)) {
p = popStack(&stack);
cout << p->element << " ";
pushStack(&stack, p->right);
}
}
}
void postOrder2(Node root) {
struct StackNode stack;
initStack(&stack);
while (root || !IsEmpty(&stack)) {
while (root) {
pushStack(&stack, root);
root->flag = 0;
root = root->left;
}
root = peekStack(&stack);
if (root->flag == 0) {
root->flag = 1;
root = root->right;
}
else {
cout << root->element << " ";
popStack(&stack);
root = NULL;
}
}
}
int initQueue(LinkedQueue queue) {
QNode node = (QNode)malloc(sizeof(struct QueueNode));
if (node == NULL) return 0;
queue->front = queue->rear = node;
return true;
};
int offerQueue(LinkedQueue queue, T element) {
QNode node = (QNode)malloc(sizeof(struct QueueNode));
if (node == NULL) return 0;
node->element = element;
queue->rear->next = node;
queue->rear = node;
return true;
}
int isEmpty(LinkedQueue queue) {
return queue->front == queue->rear;
}
T pollQueue(LinkedQueue queue) {
T e = queue->front->next->element;
QNode qNode = queue->front->next;
queue->front->next = queue->front->next->next;
if (queue->rear == qNode) queue->rear = queue->front;
free(qNode);
return e;
}
void levelOrder(Node root) {
struct Queue queue;
initQueue(&queue);
offerQueue(&queue, root);
while (!isEmpty(&queue)) {
Node node = pollQueue(&queue);
cout << node->element << " ";
if (node->left)
offerQueue(&queue, node->left);
if (node->right)
offerQueue(&queue, node->right);
}
}
int getDepthTreeNode(Node root) {
if (root == NULL) {
return 0;
}
else {
int lLength = getDepthTreeNode(root->left);
int rlength = getDepthTreeNode(root->right);
int max = rlength > lLength ? (rlength + 1) : (lLength + 1);
return max;
}
};
Main.cpp
#include"MyBinaryTree.h"
int main() {
cout << "1--创建二叉树" << endl;
cout << "2--先序遍历二叉树【递归方式】" << endl;
cout << "3--中序遍历二叉树【递归方式】" << endl;
cout << "4--后序遍历二叉树【递归方式】" << endl;
cout << "5--先序遍历二叉树【非递归方式】" << endl;
cout << "6--中序遍历二叉树【非递归方式1】" << endl;
cout << "7--中序遍历二叉树【非递归方式2】" << endl;
cout << "8--后序遍历二叉树【非递归方式】" << endl;
cout << "9--层序遍历二叉树" << endl;
cout << "10--求二叉树的深度" << endl;
cout << "-1--退出" << endl;
int option;
Node t;
t = NULL;
do {
cout << "请输入选择:";
cin >> option;
switch (option)
{
case 1:
cout << "请按先序输入二叉树中节点的值(一个字符)$字符表示空树:";
t = createBiTree(t);
if (t) {
cout << "创建二叉树成功!" << endl;
}
break;
case 2:
cout << "前序遍历【递归实现】:";
preOrder(t);
cout << endl;
break;
case 3:
cout << "中序遍历二叉树【递归方式】";
inOrder(t);
cout << endl;
break;
case 4:
cout << "后序遍历二叉树【递归方式】";
postOrder(t);
cout << endl;
break;
case 5:
cout << "先序遍历二叉树【非递归方式】";
preOrder2(t);
cout << endl;
break;
case 6:
cout << "中序遍历二叉树【非递归方式1】";
inOrder0(t);
cout << endl;
break;
case 7:
cout << "中序遍历二叉树【非递归方式2】";
inOrder2(t);
cout << endl;
break;
case 8:
cout << "后序遍历二叉树【非递归方式】";
postOrder2(t);
cout << endl;
break;
case 9:
cout << "层序遍历二叉树【非递归实现】";
levelOrder(t);
cout << endl;
break;
case 10:
cout << "二叉树的深度为:";
cout << getDepthTreeNode(t) << endl;
break;
case -1:
cout << "谢谢使用!再见!" << endl;
return 0;
default:
cout << "请输入正确的操作!";
break;
}
} while (option != -1);
}
效果展示

