一、数据结构定义
1、链式二叉树
/* 链式二叉树 定义 */
typedef char TreeType;
typedef struct BinaryTreeNode {
TreeType data;
struct BinaryTreeNode* lchild, * rchild;
}*BiTree, BiTNode;
本次代码中二叉树的结构如下图,用先序序列可以表示为 ABD##E#H##CF##G##
2、链式栈
/* 链式栈 定义 */
typedef BiTNode* StackType;
typedef struct StackNode {
StackType data;
struct StackNode* next;
}StackNode;
typedef struct {
StackNode* top;
}LinkStack;
二叉树的非递归遍历(先序遍历、中序遍历、后续遍历)需要使用栈进行辅助
3、链式队列
/* 链式队列 定义 */
typedef BiTNode* QueueType;
typedef struct QueueNode {
QueueType data;
struct QueueNode* next;
}QueueNode;
typedef struct {
QueueNode* front, * rear;
}LinkQueue;
二叉树的层次遍历需要使用队列进行辅助
二、方法概览
1、二叉树
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、栈
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、队列
void initQueue(LinkQueue* Q);//初始化队列
int isQueueEmpty(LinkQueue Q);//判断队列是否为空
void enQueue(LinkQueue* Q, QueueType data);//入队
int deQueue(LinkQueue* Q, QueueType* x);//出队
三、方法详解
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;
}
2、队列
/*------------- 队列基本操作 ---------------*/
//初始化队列
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、二叉树基本操作
/*------------- 树的操作 ---------------*/
//先序方法创建二叉树
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、二叉树递归遍历
(1)对节点的操作
//对结点T的操作
void visit(BiTNode* node) {
printf(" %c", node->data);
}
(2)先序遍历
//先序遍历(递归)
void preOrder_recursion(BiTree root) {
if (root != NULL) {
visit(root);
preOrder_recursion(root->lchild);
preOrder_recursion(root->rchild);
}
}
(3)中序遍历
//中序遍历(递归)
void inOrder_recursion(BiTree root) {
if (root != NULL) {
inOrder_recursion(root->lchild);
visit(root);
inOrder_recursion(root->rchild);
}
}
(4)后序遍历
//后序遍历(递归)
void postOrder_recursion(BiTree root) {
if (root != NULL) {
postOrder_recursion(root->lchild);
postOrder_recursion(root->rchild);
visit(root);
}
}
5、二叉树非递归遍历
(1)先序遍历
//先序遍历(非递归)
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)中序遍历
//中序遍历(非递归)
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)后序遍历
//后续遍历(非递归)
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、二叉树层次遍历
//层次遍历
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);
}
}
}
四、运行结果
main方法代码如下:
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;
}
运行结果如下:
五、源代码
#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;
}