Bootstrap

数据结构 | 链式二叉树

一、数据结构定义

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;
}
;