C语言实现二叉树前中后序遍历、层序遍历、中序非递归遍历、交换左右子树、求树的深度、添加删除结点...

源代码

#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <stdlib.h>
#define MAXSIZE 100

// 树的结点
typedef struct node {
	char data[10];
	struct node *left;
	struct node *right;
}Node;

// 队列的结点
typedef struct queueNode {
	Node node;
	struct queueNode *next;
}QueueNode;

// 定义队列,层序遍历会用到 
typedef struct {
	QueueNode *front;
	QueueNode *rear;
}Queue;

// 定义栈,中序非递归遍历会用到
typedef struct{
	// 结点指针数组
	Node *nodes[MAXSIZE];
	// 栈顶指针
	int top;
}Stack;

// 初始化队列
void initQueue(Queue *q) {
	if (!(q->front = (QueueNode *)malloc(sizeof(QueueNode)))) {
		printf("\n队列初始化失败!\n");
		return;
	}
	q->rear = q->front;
	q->front->next = NULL;
	q->rear->next = NULL;
}

// 入队
void enQueue(Queue *q, Node node) {
	// 创建新结点
	QueueNode *qn;
	if ( !(qn = (QueueNode *)malloc(sizeof(QueueNode)) ) ) {
		printf("\n队列结点初始化失败!\n");
		return;
	}
	// 添加数据
	qn->node = node;
	qn->next = NULL;
	// 把新结点添加到队尾
	q->rear->next = qn;
	q->rear = qn;
}

// 出队
Node deQueue(Queue *q) {
	if (q->front == q->rear) {
		printf("\n队列为空!\n");
		exit(-1);
	}

	QueueNode *qn;
	Node node;
	if (q->front->next == q->rear) {
		qn = q->rear;
		node = qn->node;
		
		q->rear = q->front;
		free(qn);
	}
	else
	{
		qn = q->front->next;
		node = qn->node;
		q->front->next = qn->next;
		free(qn);
	}

	return node;
}

// 初始化栈
void initStack(Stack *s) {
	s->top = -1;
}

// 判断栈是否为空
int StackIsEmpty(Stack *s) {
	if(s->top < 0){
		return 1;
	}else{
		return 0;
	}
}

// 判断栈是否满
int StackIsFull(Stack *s) {
	if (s->top >= MAXSIZE) {
		return 1;
	}
	else
	{
		return 0;
	}
}

// 入栈
void StackPush(Stack *s, Node *node) {
	if (StackIsFull(s)) {
		printf("\n栈已满!\n");
		return;
	}
	s->top++;
	s->nodes[s->top] = node;
}

// 出栈
Node *StackPop(Stack *s) {
	if(StackIsEmpty(s)){
		printf("\n栈为空!\n");
		return NULL;
	}
	Node *node = s->nodes[s->top];
	s->top--;
	return node;
}

// 取栈顶元素
Node *StackGetTop(Stack *s) {
	if(StackIsEmpty(s)){
		return NULL;
	}
	return s->nodes[s->top];
}

// 添加结点
// 参数依次为:父结点,子结点,1:左子树		2:右子树
// 返回值:1:添加成功	0:添加失败
int addNode(Node *parent, Node *node, int type) {
	if (parent == NULL) {
		printf("父结点不存在!\n");
		return 0;
	}
	// 判断要添加到左边还是右边
	switch (type)
	{
		case 1:
			if (parent->left) {
				//printf("左子结点不为空!无法添加新结点!\n");
				return 0;
			}
			else {
				parent->left = node;
			}
			break;
		case 2:
			if (parent->right) {
				//printf("右子结点不为空!无法添加新结点!\n");
				return 0;
			}
			else
			{
				parent->right = node;
			}
			break;
		default:
			printf("参数有误!\n");
			return 0;
	}
	return 1;
}

// 获取左右子树
Node *getLeftTree(Node *parent) {
	if (parent) {
		return parent->left;
	}
	else
	{
		return NULL;
	}
}

Node *getRightTree(Node *parent) {
	if (parent) {
		return parent->right;
	}
	else
	{
		return NULL;
	}
}

// 返回二叉树是否为空
int isEmpty(Node *node) {
	if (node) {
		return 0;
	}
	else
	{
		return 1;
	}
}

// 求二叉树的深度
int getTreeDepth(Node *parent) {
	int depth1, depth2;

	if (parent == NULL) {
		return 0;
	}
	else {
		// 求左子树的深度
		depth1 = getTreeDepth(parent->left);
		// 求右子树的深度
		depth2 = getTreeDepth(parent->right);
		// 该树的深度取决于最深的子树
		if (depth1 > depth2) {
			return depth1 + 1;
		}
		else {
			return depth2 + 1;
		}
	}
}

// 查找结点
Node *find(Node *parent, char* data) {
	Node *target;
	// 该结点是否为空
	if (!parent) {
		return NULL;
	}
	else {
		// 该结点是否是我们要找的
		if (strcmp(parent->data, data) == 0) {
			return parent;
		}
		else {
			// 向左递归查找
			if (target = find(parent->left, data)) {
				return target;
			}// 向右递归查找
			else if(target = find(parent->right, data)){
				return target;
			}
			else {
				return NULL;
			}
		}
	}
}

Node *find2(Node *parent, char* data) {
	Node *target;
	// 该结点是否为空
	if (!parent) {
		return NULL;
	}
	else {
		// 该结点是否是我们要找的
		//if (strcmp(parent->data, data) == 0) {
		//	return parent;
		//}
		//else {
			// 向左递归查找
			if (target = find(parent->left, data)) {
				return target;
			}// 向右递归查找
			else if (target = find(parent->right, data)) {
				return target;
			}
			else {
				return NULL;
			}
		//}
	}
}

// 释放二叉树
void destroyTree(Node *parent) {
	if (parent) {
		// 递归释放左子树
		destroyTree(parent->left);
		// 递归释放右子树
		destroyTree(parent->right);
		// 释放当前结点
		free(parent);
		parent = NULL;
	}
	// 如果该结点为空,直接返回
	return;
}

// 前序遍历
void preOrder(Node *node) {
	if (node) {
		printf("%s  ", node->data);
		preOrder(node->left);
		preOrder(node->right);
	}

	return;
}

// 中序遍历
void infixOrder(Node *node) {
	if (node) {

		infixOrder(node->left);
		printf("%s  ", node->data);
		infixOrder(node->right);
	}

	return;
}

// 中序非递归遍历
void infixOrder2(Node *node) {
	Stack *s;
	if (!(s = (Stack *)malloc(sizeof(Stack)))) {
		printf("创建栈失败!\n");
		return;
	}
	Node *p;
	initStack(s);
	// 树根入栈
	StackPush(s,node);
	printf("\n");
	while(!StackIsEmpty(s)){
		while(p = StackGetTop(s)){
			StackPush(s, p->left);
		}
		// 空指针出栈 
		StackPop(s);
		if(!StackIsEmpty(s)){
			p = StackPop(s);
			printf("\t%s\t",p->data);
			StackPush(s, p->right);
		}
	} 
	printf("\n");
}

// 后序遍历
void postOrder(Node *node) {
	if (node) {

		postOrder(node->left);
		postOrder(node->right);
		printf("%s  ", node->data);
	}

	return;
}

// 利用队列实现层序遍历
void levelOrder(Node *root) {
	Queue *q = (Queue *)malloc(sizeof(Queue));
	initQueue(q);
	Node node;

	printf("\n层序遍历:\n");
	if (root != NULL) {

		enQueue(q,*root);
		while (q->front != q->rear) {
			node = deQueue(q);
			printf("\t%s", node.data);
			if (node.left != NULL) {
				enQueue(q, *node.left);
			}
			if (node.right != NULL) {
				enQueue(q, *node.right);
			}
		}
	}
	else
	{
		printf("\n这是一棵空树!\n");
	}
}

void addNode(Node *bt) {
	Node *node, *parent;
	char data[10];
	char choice;
	//int option = 0;

	if (node = (Node *)malloc(sizeof(Node))) {
		printf("\n请输入该结点的数据:");
		fflush(stdin);
		scanf("%s", node->data);
		//node->data = data;
		node->left = NULL;
		node->right = NULL;
		printf("\n输入父结点数据: ");
		fflush(stdin);
		scanf("%s", data);
		parent = find(bt, data);
		if (!parent) {
			printf("\n未找到父结点!\n");
			free(node);
			return;
		}
		printf("\n1.添加到左子树		2.添加到右子树\n");
		do {
			choice = getch();
			
			//option = choice - '0';
			if (choice == '1' || choice == '2') {
				while (addNode(parent, node, choice - '0') == 0) {
					parent = find2(parent, data);
					if (parent == NULL) {
						return;
					}
				}
			}
		} while (choice != '1' && choice != '2');

	}
	return;
}

// 交换左右结点
void revertNode(Node *node) {
	if (node->left != NULL || node->right != NULL) {
		Node * temp;
		temp = node->left;
		node->left = node->right;
		node->right = temp;
	}
	if (node->left != NULL) {
		revertNode(node->left);
	}
	if (node->right != NULL) {
		revertNode(node->right);
	}
}

// 初始化树根
Node *initRoot() {
	Node *root;
	char data[10];
	if (root = (Node *)malloc(sizeof(Node))) {
		printf("\n请输入根结点数据:");
		scanf("%s", root->data);
		//root->data = data;
		root->left = NULL;
		root->right = NULL;
		return root;
	}
	return NULL;
}


int main() {
	Node *root = NULL;
	int choice = 0;

	do {
		printf("\n1.设置树根		2.添加结点\n");
		printf("3.先序遍历		4.中序遍历\n");
		printf("5.后序遍历		6.二叉树深度\n");
		printf("7.清空二叉树		0.退出\n");
		printf("8.层序遍历		9.中序非递归遍历\n");
		printf("10.交换所有结点左右子树\n");

		printf("\n请输入选项:");
		scanf("%d",&choice);

		switch (choice)
		{
			case 1:
				root = initRoot();
				break;
			case 2:
				addNode(root);
				break;
			case 3:
				printf("\n先序遍历:\n");
				preOrder(root);
				break;
			case 4:
				printf("\n中序遍历:\n");
				infixOrder(root);
				break;
			case 5:
				printf("\n后序遍历:\n");
				postOrder(root);
				break;
			case 6:
				printf("\n二叉树深度为:%d\n", getTreeDepth(root));
				break;
			case 7:
				destroyTree(root);
				break;
			case 8:
				levelOrder(root);
				break;
			case 9:
				infixOrder2(root);
				break;
			case 10:
				revertNode(root);
				printf("交换完成...\n");
				break;
			default:
				break;
		}

	} while (choice != 0);

	destroyTree(root);
	root = NULL;
	return 0;
}

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值