1. Data structure definition
1. Chained binary tree
/* 链式二叉树 定义 */
typedef char TreeType;
typedef struct BinaryTreeNode {
TreeType data;
struct BinaryTreeNode* lchild, * rchild;
}*BiTree, BiTNode;
The structure of the binary tree in this code is as shown in the figure below, which can be expressed as ABD##E#H##CF##G## in the preorder sequence
2. Chained stack
/* 链式栈 定义 */
typedef BiTNode* StackType;
typedef struct StackNode {
StackType data;
struct StackNode* next;
}StackNode;
typedef struct {
StackNode* top;
}LinkStack;
Non-recursive traversal of binary trees (pre-order traversal, in-order traversal, subsequent traversal) requires the use of stacks for assistance
3. Chain queue
/* 链式队列 定义 */
typedef BiTNode* QueueType;
typedef struct QueueNode {
QueueType data;
struct QueueNode* next;
}QueueNode;
typedef struct {
QueueNode* front, * rear;
}LinkQueue;
The hierarchical traversal of the binary tree needs to be assisted by the use of queues
2. Method overview
1. Binary tree
BiTree createTree();//先序方法创建二叉树
int count_TreeSize(BiTree root);//计算所有结点数
int count_LeafNode(BiTree root);//计算叶结点数
int count_TreeDepth(BiTree root);//计算树的深度
int count_TreeLevelSize(BiTNode* root, int level);//计算第i层节点个数
void changeRight_Left(BiTree root);//互换二叉树左右子树
void destoryTree(BiTree* root);//二叉树销毁
void visit(BiTNode* node);//对结点T的操作
void preOrder_recursion(BiTree root);//先序遍历(递归)
void inOrder_recursion(BiTree root);//中序遍历(递归)
void postOrder_recursion(BiTree root);//后序遍历(递归)
void inOrder_non_recursion(BiTree root);//中序遍历(非递归)
void preOrder_non_recursion(BiTree root);//先序遍历(非递归)
void levelOrder(BiTree root);//层次遍历
2. stack
void initStack(LinkStack* S);//初始化栈
int isStackEmpty(LinkStack S);//判断栈是否为空
int pushStack(LinkStack* L, StackType data);//入栈
int popStack(LinkStack* L, StackType* data);//出栈
int getStackTop(LinkStack* L, StackType* x);//取栈顶元素
int destroyStack(LinkStack* L);//销毁栈
3. Queue
void initQueue(LinkQueue* Q);//初始化队列
int isQueueEmpty(LinkQueue Q);//判断队列是否为空
void enQueue(LinkQueue* Q, QueueType data);//入队
int deQueue(LinkQueue* Q, QueueType* x);//出队
3. Detailed explanation of the method
1. stack
/*------------- 栈基本操作 ---------------*/
//初始化栈
void initStack(LinkStack* S) {
S->top = (StackNode*)malloc(sizeof(StackNode)); // 分配头节点
S->top = NULL; //初始化为空
}
//判断栈是否为空
int isStackEmpty(LinkStack S) {
if (S.top == NULL) return 1;
else return 0;
}
//入栈
int popStack(LinkStack* L, StackType* data) {
StackNode* del;
if (L->top == NULL) return -1;
else {
del = L->top;
*data = del->data;
L->top = L->top->next;
free(del);
return 0;
}
}
//出栈
int pushStack(LinkStack* L, StackType data) {
StackNode* news = (StackNode*)malloc(sizeof(struct StackNode));
if (news == NULL) return -1;
else {
news->data = data;
news->next = L->top;
L->top = news;
return 0;
}
}
//取栈顶元素
int getStackTop(LinkStack* L, StackType* x) {
if (L->top == NULL) {
*x = NULL;
return -1;
}
else {
*x = L->top->data;
return 1;
}
}
//销毁栈
int destroyStack(LinkStack* L) {
int cnt = 0;
if (L == NULL) return 0;
struct StackNode* p = L->top, * q;
free(L);
while (p->next != NULL) {
q = p->next;
cnt++;
free(p);
p = q;
}
return cnt;
}
2. Queue
/*------------- 队列基本操作 ---------------*/
//初始化队列
void initQueue(LinkQueue* Q) {
Q->front = Q->rear = (QueueNode*)malloc(sizeof(QueueNode)); // 分配头节点
Q->front->next = NULL; //初始化为空
}
//判断队列是否为空
int isQueueEmpty(LinkQueue Q) {
if (Q.front == Q.rear) return 1;
else return 0;
}
//入队
void enQueue(LinkQueue* Q, QueueType data) {
QueueNode* news = (QueueNode*)malloc(sizeof(QueueNode));
news->data = data; // 创建新节点,插入队列尾部
news->next = NULL;
Q->rear->next = news;
Q->rear = news;
}
//出队
int deQueue(LinkQueue* Q, QueueType* x) {
if (Q->front == Q->rear) return 0;
QueueNode* del = Q->front->next;
*x = del->data;
Q->front->next = del->next;
if (Q->rear == del)
Q->rear = Q->front; // 若原队列只有一个节点,删除后变空
free(del);
return 1;
}
3. Basic operation of binary tree
/*------------- 树的操作 ---------------*/
//先序方法创建二叉树
BiTree createTree() {
BiTree root;
TreeType data;
scanf("%c", &data);
if (data == '#') root = NULL;
else {
root = (struct BinaryTreeNode*)malloc(sizeof(struct BinaryTreeNode));
root->data = data;
root->lchild = createTree();
root->rchild = createTree();
}
return root;
}
//计算所有结点数
int count_TreeSize(BiTree root) {
if (root == NULL) return 0;
return count_TreeSize(root->lchild) + count_TreeSize(root->rchild) + 1;
}
//计算叶结点数
int count_LeafNode(BiTree root) {
if (root == NULL) return 0;
else if (root->lchild == NULL && root->rchild == NULL) return 1;
else return count_LeafNode(root->lchild) + count_LeafNode(root->rchild);
}
//计算树的深度
int count_TreeDepth(BiTree root) {
if (root == NULL) {
return 0;
}
else {
int l = count_TreeDepth(root->lchild);
int r = count_TreeDepth(root->rchild);
return l > r ? l + 1 : r + 1;
}
}
//计算第i层节点个数
int count_TreeLevelSize(BiTNode* root, int level) {
if (root == NULL) return 0;
if (level == 1) return 1;
return count_TreeLevelSize(root->lchild, level - 1) + count_TreeLevelSize(root->rchild, level - 1);
}
//互换二叉树左右子树
void changeRight_Left(BiTree root) {
BiTree temp;
if (root == NULL);
else if (root->lchild == NULL && root->rchild == NULL);
else {
temp = root->lchild;
root->lchild = root->rchild;
root->rchild = temp;
changeRight_Left(root->lchild);
changeRight_Left(root->rchild);
}
}
//二叉树销毁
void destoryTree(BiTree* root) {
if (*root != NULL) {
if ((*root)->lchild) //有左孩子
destoryTree(&(*root)->lchild);
if ((*root)->rchild) //有右孩子
destoryTree(&(*root)->rchild);
free(*root); //释放根结点
*root = NULL; //空指针NULL
}
}
4. Binary tree recursive traversal
(1) Operations on nodes
//对结点T的操作
void visit(BiTNode* node) {
printf(" %c", node->data);
}
(2) Preorder traversal
//先序遍历(递归)
void preOrder_recursion(BiTree root) {
if (root != NULL) {
visit(root);
preOrder_recursion(root->lchild);
preOrder_recursion(root->rchild);
}
}
(3) Inorder traversal
//中序遍历(递归)
void inOrder_recursion(BiTree root) {
if (root != NULL) {
inOrder_recursion(root->lchild);
visit(root);
inOrder_recursion(root->rchild);
}
}
(4) Post-order traversal
//后序遍历(递归)
void postOrder_recursion(BiTree root) {
if (root != NULL) {
postOrder_recursion(root->lchild);
postOrder_recursion(root->rchild);
visit(root);
}
}
5. Binary tree non-recursive traversal
(1) Preorder traversal
//先序遍历(非递归)
void preOrder_non_recursion(BiTree root) {
LinkStack S;
initStack(&S);
BiTree p = root;
while (p || !isStackEmpty(S)) {
if (p) {
visit(p);
pushStack(&S, p);
p = p->lchild;
}
else {
popStack(&S, &p);
p = p->rchild;
}
}
}
(2) Inorder traversal
//中序遍历(非递归)
void inOrder_non_recursion(BiTree root) {
LinkStack S;
initStack(&S);
BiTree p = root;
while (p || !isStackEmpty(S)) {
if (p) {
pushStack(&S, p);
p = p->lchild;
}
else {
popStack(&S, &p);
visit(p);
p = p->rchild;
}
}
}
(3) Post-order traversal
//后续遍历(非递归)
void postOrder_non_recursion(BiTree root) {
LinkStack S;
initStack(&S);
BiTNode* p = root;
BiTNode* r = NULL;
while (p || !isStackEmpty(S)) {
if (p) {
pushStack(&S, p);
p = p->lchild;
}
else {
getStackTop(&S, &p);
if (p->rchild && p->rchild != r)
p = p->rchild;
else {
popStack(&S, &p);
visit(p);
r = p;
p = NULL;
}
}
}
}
6. Binary tree level traversal
//层次遍历
void levelOrder(BiTree root) {
LinkQueue Q;
initQueue(&Q);
BiTree p;
enQueue(&Q, root);
while (!isQueueEmpty(Q)) {
deQueue(&Q, &p);
visit(p);
if (p->lchild != NULL) {
enQueue(&Q, p->lchild);
}
if (p->rchild != NULL) {
enQueue(&Q, p->rchild);
}
}
}
4. Running results
The main method code is as follows:
int main() {
// 输入先序序列 ABD##E#H##CF##G## 创建二叉树
printf("输入先序序列创建二叉树:");
BiTree root = createTree();
printf("\n先序遍历(递 归):");
preOrder_recursion(root);
printf("\n先序遍历(非递归):");
preOrder_non_recursion(root);
printf("\n中序遍历(递 归):");
inOrder_recursion(root);
printf("\n中序遍历(非递归):");
inOrder_non_recursion(root);
printf("\n后序遍历(递 归):");
postOrder_recursion(root);
printf("\n后序遍历(非递归):");
postOrder_non_recursion(root);
printf("\n层次遍历:");
levelOrder(root);
changeRight_Left(root);
printf("\n交换左右子树后的先序遍历:");
postOrder_recursion(root);
printf("\n树的深度 = %d", count_TreeDepth(root));
printf("\n所有结点数 = %d", count_TreeSize(root));
printf("\n叶结点数 = %d", count_LeafNode(root));
int level;
printf("\n输入层数:");
scanf("%d", &level);
printf("第%d层结点数 = %d", level, count_TreeLevelSize(root, level));
return 0;
}
The result of the operation is as follows:
5. Source code
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
/* 链式二叉树 定义 */
typedef char TreeType;
typedef struct BinaryTreeNode {
TreeType data;
struct BinaryTreeNode* lchild, * rchild;
}*BiTree, BiTNode;
/* 链式栈 定义 */
typedef BiTNode* StackType;
typedef struct StackNode {
StackType data;
struct StackNode* next;
}StackNode;
typedef struct {
StackNode* top;
}LinkStack;
/* 链式队列 定义 */
typedef BiTNode* QueueType;
typedef struct QueueNode {
QueueType data;
struct QueueNode* next;
}QueueNode;
typedef struct {
QueueNode* front, * rear;
}LinkQueue;
void initQueue(LinkQueue* Q);//初始化队列
int isQueueEmpty(LinkQueue Q);//判断队列是否为空
void enQueue(LinkQueue* Q, QueueType data);//入队
int deQueue(LinkQueue* Q, QueueType* x);//出队
void initStack(LinkStack* S);//初始化栈
int isStackEmpty(LinkStack S);//判断栈是否为空
int pushStack(LinkStack* L, StackType data);//入栈
int popStack(LinkStack* L, StackType* data);//出栈
int getStackTop(LinkStack* L, StackType* x);//取栈顶元素
int destroyStack(LinkStack* L);//销毁栈
BiTree createTree();//先序方法创建二叉树
int count_TreeSize(BiTree root);//计算所有结点数
int count_LeafNode(BiTree root);//计算叶结点数
int count_TreeDepth(BiTree root);//计算树的深度
int count_TreeLevelSize(BiTNode* root, int level);//计算第i层节点个数
void changeRight_Left(BiTree root);//互换二叉树左右子树
void destoryTree(BiTree* root);//二叉树销毁
void visit(BiTNode* node);//对结点T的操作
void preOrder_recursion(BiTree root);//先序遍历(递归)
void inOrder_recursion(BiTree root);//中序遍历(递归)
void postOrder_recursion(BiTree root);//后序遍历(递归)
void inOrder_non_recursion(BiTree root);//中序遍历(非递归)
void preOrder_non_recursion(BiTree root);//先序遍历(非递归)
void levelOrder(BiTree root);//层次遍历
/*------------- 队列基本操作 ---------------*/
//初始化队列
void initQueue(LinkQueue* Q) {
Q->front = Q->rear = (QueueNode*)malloc(sizeof(QueueNode)); // 分配头节点
Q->front->next = NULL; //初始化为空
}
//判断队列是否为空
int isQueueEmpty(LinkQueue Q) {
if (Q.front == Q.rear) return 1;
else return 0;
}
//入队
void enQueue(LinkQueue* Q, QueueType data) {
QueueNode* news = (QueueNode*)malloc(sizeof(QueueNode));
news->data = data; // 创建新节点,插入队列尾部
news->next = NULL;
Q->rear->next = news;
Q->rear = news;
}
//出队
int deQueue(LinkQueue* Q, QueueType* x) {
if (Q->front == Q->rear) return 0;
QueueNode* del = Q->front->next;
*x = del->data;
Q->front->next = del->next;
if (Q->rear == del)
Q->rear = Q->front; // 若原队列只有一个节点,删除后变空
free(del);
return 1;
}
/*------------- 栈基本操作 ---------------*/
//初始化栈
void initStack(LinkStack* S) {
S->top = (StackNode*)malloc(sizeof(StackNode)); // 分配头节点
S->top = NULL; //初始化为空
}
//判断栈是否为空
int isStackEmpty(LinkStack S) {
if (S.top == NULL) return 1;
else return 0;
}
//入栈
int popStack(LinkStack* L, StackType* data) {
StackNode* del;
if (L->top == NULL) return -1;
else {
del = L->top;
*data = del->data;
L->top = L->top->next;
free(del);
return 0;
}
}
//出栈
int pushStack(LinkStack* L, StackType data) {
StackNode* news = (StackNode*)malloc(sizeof(struct StackNode));
if (news == NULL) return -1;
else {
news->data = data;
news->next = L->top;
L->top = news;
return 0;
}
}
//取栈顶元素
int getStackTop(LinkStack* L, StackType* x) {
if (L->top == NULL) {
*x = NULL;
return -1;
}
else {
*x = L->top->data;
return 1;
}
}
//销毁栈
int destroyStack(LinkStack* L) {
int cnt = 0;
if (L == NULL) return 0;
struct StackNode* p = L->top, * q;
free(L);
while (p->next != NULL) {
q = p->next;
cnt++;
free(p);
p = q;
}
return cnt;
}
/*------------- 树的操作 ---------------*/
//先序方法创建二叉树
BiTree createTree() {
BiTree root;
TreeType data;
scanf("%c", &data);
if (data == '#') root = NULL;
else {
root = (struct BinaryTreeNode*)malloc(sizeof(struct BinaryTreeNode));
root->data = data;
root->lchild = createTree();
root->rchild = createTree();
}
return root;
}
//计算所有结点数
int count_TreeSize(BiTree root) {
if (root == NULL) return 0;
return count_TreeSize(root->lchild) + count_TreeSize(root->rchild) + 1;
}
//计算叶结点数
int count_LeafNode(BiTree root) {
if (root == NULL) return 0;
else if (root->lchild == NULL && root->rchild == NULL) return 1;
else return count_LeafNode(root->lchild) + count_LeafNode(root->rchild);
}
//计算树的深度
int count_TreeDepth(BiTree root) {
if (root == NULL) {
return 0;
}
else {
int l = count_TreeDepth(root->lchild);
int r = count_TreeDepth(root->rchild);
return l > r ? l + 1 : r + 1;
}
}
//计算第i层节点个数
int count_TreeLevelSize(BiTNode* root, int level) {
if (root == NULL) return 0;
if (level == 1) return 1;
return count_TreeLevelSize(root->lchild, level - 1) + count_TreeLevelSize(root->rchild, level - 1);
}
//互换二叉树左右子树
void changeRight_Left(BiTree root) {
BiTree temp;
if (root == NULL);
else if (root->lchild == NULL && root->rchild == NULL);
else {
temp = root->lchild;
root->lchild = root->rchild;
root->rchild = temp;
changeRight_Left(root->lchild);
changeRight_Left(root->rchild);
}
}
//二叉树销毁
void destoryTree(BiTree* root) {
if (*root != NULL) {
if ((*root)->lchild) //有左孩子
destoryTree(&(*root)->lchild);
if ((*root)->rchild) //有右孩子
destoryTree(&(*root)->rchild);
free(*root); //释放根结点
*root = NULL; //空指针NULL
}
}
//对结点T的操作
void visit(BiTNode* node) {
printf(" %c", node->data);
}
//先序遍历(递归)
void preOrder_recursion(BiTree root) {
if (root != NULL) {
visit(root);
preOrder_recursion(root->lchild);
preOrder_recursion(root->rchild);
}
}
//中序遍历(递归)
void inOrder_recursion(BiTree root) {
if (root != NULL) {
inOrder_recursion(root->lchild);
visit(root);
inOrder_recursion(root->rchild);
}
}
//后序遍历(递归)
void postOrder_recursion(BiTree root) {
if (root != NULL) {
postOrder_recursion(root->lchild);
postOrder_recursion(root->rchild);
visit(root);
}
}
//先序遍历(非递归)
void preOrder_non_recursion(BiTree root) {
LinkStack S;
initStack(&S);
BiTree p = root;
while (p || !isStackEmpty(S)) {
if (p) {
visit(p);
pushStack(&S, p);
p = p->lchild;
}
else {
popStack(&S, &p);
p = p->rchild;
}
}
}
//中序遍历(非递归)
void inOrder_non_recursion(BiTree root) {
LinkStack S;
initStack(&S);
BiTree p = root;
while (p || !isStackEmpty(S)) {
if (p) {
pushStack(&S, p);
p = p->lchild;
}
else {
popStack(&S, &p);
visit(p);
p = p->rchild;
}
}
}
//后续遍历(非递归)
void postOrder_non_recursion(BiTree root) {
LinkStack S;
initStack(&S);
BiTNode* p = root;
BiTNode* r = NULL;
while (p || !isStackEmpty(S)) {
if (p) {
pushStack(&S, p);
p = p->lchild;
}
else {
getStackTop(&S, &p);
if (p->rchild && p->rchild != r)
p = p->rchild;
else {
popStack(&S, &p);
visit(p);
r = p;
p = NULL;
}
}
}
}
//层次遍历
void levelOrder(BiTree root) {
LinkQueue Q;
initQueue(&Q);
BiTree p;
enQueue(&Q, root);
while (!isQueueEmpty(Q)) {
deQueue(&Q, &p);
visit(p);
if (p->lchild != NULL) {
enQueue(&Q, p->lchild);
}
if (p->rchild != NULL) {
enQueue(&Q, p->rchild);
}
}
}
int main() {
// 输入先序序列 ABD##E#H##CF##G## 创建二叉树
printf("输入先序序列创建二叉树:");
BiTree root = createTree();
printf("\n先序遍历(递 归):");
preOrder_recursion(root);
printf("\n先序遍历(非递归):");
preOrder_non_recursion(root);
printf("\n中序遍历(递 归):");
inOrder_recursion(root);
printf("\n中序遍历(非递归):");
inOrder_non_recursion(root);
printf("\n后序遍历(递 归):");
postOrder_recursion(root);
printf("\n后序遍历(非递归):");
postOrder_non_recursion(root);
printf("\n层次遍历:");
levelOrder(root);
changeRight_Left(root);
printf("\n交换左右子树后的先序遍历:");
postOrder_recursion(root);
printf("\n树的深度 = %d", count_TreeDepth(root));
printf("\n所有结点数 = %d", count_TreeSize(root));
printf("\n叶结点数 = %d", count_LeafNode(root));
int level;
printf("\n输入层数:");
scanf("%d", &level);
printf("第%d层结点数 = %d", level, count_TreeLevelSize(root, level));
return 0;
}