C语言-二叉树的构建与遍历

代码

#include <stdio.h>
#include <malloc.h>
#include <stdbool.h>

#define QUEUE_SIZE 5

typedef struct BTNode
{
	char element;
	struct BTNode* left;
	struct BTNode* right;
}BTNode, *BTNodePtr;

typedef struct BTNodePtrQueue
{
	BTNodePtr* nodePtrs;
	int front;
	int rear;
}BTNodePtrQueue, *QueuePtr;

QueuePtr initQueue()
{
	QueuePtr resultQueuePtr = (QueuePtr)malloc(sizeof(struct BTNodePtrQueue));
	resultQueuePtr->nodePtrs = (BTNodePtr*)malloc(QUEUE_SIZE * sizeof(BTNodePtr));
	resultQueuePtr->front = 0;
	resultQueuePtr->rear = 1;
	return resultQueuePtr;
}

bool isQueueEmpty(QueuePtr paraQueuePtr)
{
	if ((paraQueuePtr->front + 1) % QUEUE_SIZE == paraQueuePtr->rear) {
		return true;
	}

	return false;
}
void enqueue(QueuePtr paraQueuePtr, BTNodePtr paraBTNodePtr)
{
	printf("front = %d, rear = %d.\r\n", paraQueuePtr->front, paraQueuePtr->rear);
	if ((paraQueuePtr->rear + 1) % QUEUE_SIZE == paraQueuePtr->front % QUEUE_SIZE) {
		printf("Error, trying to enqueue %c. queue full.\r\n", paraBTNodePtr->element);
		return;
	}
	paraQueuePtr->nodePtrs[paraQueuePtr->rear] = paraBTNodePtr;
	paraQueuePtr->rear = (paraQueuePtr->rear + 1) % QUEUE_SIZE;
	printf("enqueue %c ends.\r\n", paraBTNodePtr->element);
}

BTNodePtr dequeue(QueuePtr paraQueuePtr)
{
	if (isQueueEmpty(paraQueuePtr)) {
		printf("Error, empty queue\r\n");
		return NULL;
	}

	paraQueuePtr->front = (paraQueuePtr->front + 1) % QUEUE_SIZE;

	printf("dequeue %c ends.\r\n", paraQueuePtr->nodePtrs[paraQueuePtr->front]->element);
	return paraQueuePtr->nodePtrs[paraQueuePtr->front];
}

BTNodePtr constructBTNode(char paraChar)
{
	BTNodePtr resultPtr = (BTNodePtr)malloc(sizeof(BTNode));
	resultPtr->element = paraChar;
	resultPtr->left = NULL;
	resultPtr->right = NULL;
	return resultPtr;
}

BTNodePtr stringToBTree(char* paraString)
{
	int i;
	char ch;

	QueuePtr tempQueuePtr = initQueue();

	BTNodePtr resultHeader;
	BTNodePtr tempParent, tempLeftChild, tempRightChild;
	i = 0;
	ch = paraString[i];
	resultHeader = constructBTNode(ch);
	enqueue(tempQueuePtr, resultHeader);

	while(!isQueueEmpty(tempQueuePtr)) {
		tempParent = dequeue(tempQueuePtr);

		i ++;
		ch = paraString[i];
		if (ch == '#') {
			tempParent->left = NULL;
		} else {
			tempLeftChild = constructBTNode(ch);
			enqueue(tempQueuePtr, tempLeftChild);
			tempParent->left = tempLeftChild;
		}

		i ++;
		ch = paraString[i];
		if (ch == '#') {
			tempParent->right = NULL;
		} else {
			tempRightChild = constructBTNode(ch);
			enqueue(tempQueuePtr, tempRightChild);
			tempParent->right = tempRightChild;
		}
	}

	return resultHeader;
}

void levelwise(BTNodePtr paraTreePtr)
{
	
	char tempString[100];
	int i = 0;
	QueuePtr tempQueuePtr = initQueue();
	BTNodePtr tempNodePtr;
	enqueue(tempQueuePtr, paraTreePtr);
	while(!isQueueEmpty(tempQueuePtr)) {
		tempNodePtr = dequeue(tempQueuePtr);
		
		tempString[i] = tempNodePtr->element;
		i ++;

		if (tempNodePtr->left != NULL){
			enqueue(tempQueuePtr, tempNodePtr->left);
		}
		if (tempNodePtr->right != NULL){
			enqueue(tempQueuePtr, tempNodePtr->right);
		}
	}
	
	tempString[i] = '\0';

	printf("Levelwise: %s\r\n", tempString);
}

void preorder(BTNodePtr tempPtr)
{
	if (tempPtr == NULL){
		return;
	}

	printf("%c", tempPtr->element);
	preorder(tempPtr->left);
	preorder(tempPtr->right);
}

void inorder(BTNodePtr tempPtr)
{
	if (tempPtr == NULL) {
		return;
	}

	inorder(tempPtr->left);
	printf("%c", tempPtr->element);
	inorder(tempPtr->right);
}

void postorder(BTNodePtr tempPtr){
	if (tempPtr == NULL) {
		return;
	

	postorder(tempPtr->left);
	postorder(tempPtr->right);
	printf("%c", tempPtr->element);
}

int main()
{
	BTNodePtr tempHeader;
	tempHeader = constructBTNode('c');
	printf("There is only one node. Preorder visit: ");
	preorder(tempHeader);
	printf("\r\n");

	char* tempString = "acde#bf######";

	tempHeader = stringToBTree(tempString);
	printf("Preorder: ");
	preorder(tempHeader);
	printf("\r\n");
	printf("Inorder: ");
	inorder(tempHeader);
	printf("\r\n");
	printf("Postorder: ");
	postorder(tempHeader);
	printf("\r\n");
	printf("Levelwise: ");
	levelwise(tempHeader);
	printf("\r\n");

	return 1;
}

 运行结果:

学习二叉树是数据结构和算法学习中的一个重要里程碑。二叉树不仅具有广泛的应用场景,如搜索、排序、存储等,而且它的学习和理解也为后续更复杂的数据结构(如树、图)和算法打下了坚实的基础。以下是我学习二叉树的一些心得:

理解定义和特性:
二叉树是每个节点最多有两个子节点的树结构,通常称为左子节点和右子节点。
理解二叉树的基本特性,如递归性、满二叉树、完全二叉树等,对于后续的学习和应用至关重要。
掌握遍历方法:
二叉树的遍历是理解和操作二叉树的基础。常见的遍历方法有前序遍历、中序遍历和后序遍历。
掌握这些遍历方法不仅可以用于访问树中的所有节点,还可以用于构建二叉树、查找特定节点等。
理解递归遍历和非递归遍历的实现方式,这有助于加深对二叉树结构和遍历过程的理解。
应用实例:
通过解决实际问题来加深对二叉树的理解。例如,使用二叉搜索树实现高效查找,或使用二叉堆实现优先队列等。
在实践中应用二叉树不仅可以加深对其原理的理解,还可以提高编程能力和解决问题的能力。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
线索二叉树也可以使用递归的方式进行中序遍历。下面是使用C语言实现线索二叉树递归中序遍历的代码示例: ```c #include <stdio.h> #include <stdlib.h> // 线索二叉树节点结构体 typedef struct TreeNode { int val; struct TreeNode* left; struct TreeNode* right; int ltag; int rtag; } TreeNode; // 中序遍历线索二叉树(递归) void inorderTraversal(TreeNode* root) { if (root != NULL) { if (root->ltag == 0) { inorderTraversal(root->left); } printf("%d ", root->val); if (root->rtag == 0) { inorderTraversal(root->right); } } } // 创建线索二叉树节点 TreeNode* createTreeNode(int val) { TreeNode* node = (TreeNode*)malloc(sizeof(TreeNode)); node->val = val; node->left = NULL; node->right = NULL; node->ltag = 0; node->rtag = 0; return node; } // 构建线索二叉树 void createThreadedBinaryTree(TreeNode* root) { TreeNode* pre = NULL; if (root != NULL) { createThreadedBinaryTree(root->left); if (root->left == NULL) { root->ltag = 1; root->left = pre; } if (pre != NULL && pre->right == NULL) { pre->rtag = 1; pre->right = root; } pre = root; createThreadedBinaryTree(root->right); } } int main() { // 构建线索二叉树 TreeNode* root = createTreeNode(1); root->left = createTreeNode(2); root->right = createTreeNode(3); root->left->left = createTreeNode(4); root->left->right = createTreeNode(5); root->right->left = createTreeNode(6); root->right->right = createTreeNode(7); createThreadedBinaryTree(root); // 中序遍历线索二叉树 printf("Inorder Traversal: "); inorderTraversal(root); printf("\n"); return 0; } ``` 在`inorderTraversal()`函数中,先判断节点的左子树是否为线索指针,如果不是,则递归遍历其左子树;然后输出节点的值;最后判断节点的右子树是否为线索指针,如果不是,则递归遍历其右子树。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值