二叉树的创建及遍历

一、二叉树的创建及遍历

(1)初始化队列

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

(2)入队、出队

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("队满!\r\n");
		return;
	}
	paraQueuePtr->nodePtrs[paraQueuePtr->rear] = paraBTNodePtr;
	paraQueuePtr->rear = (paraQueuePtr->rear + 1) % QUEUE_SIZE;
	printf("%c入队.\r\n", paraBTNodePtr->element);
}

BTNodePtr dequeue(QueuePtr paraQueuePtr){
	if (isQueueEmpty(paraQueuePtr)) {
		printf("队空!\r\n");
		return NULL;
	}

	paraQueuePtr->front = (paraQueuePtr->front + 1) % QUEUE_SIZE;
	//BTNodePtr tempPtr = paraQueuePtr->nodePtrs[paraQueuePtr->front + 1];

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

(3)二叉树的遍历

以下面的二叉树为例:
在这里插入图片描述
二叉树的的遍历有四种方式:前序遍历、中序遍历、后序遍历和层序遍历

1、前序遍历:先访问根节点,再分别前序遍历左、右两颗子树。前序遍历结果为:acbedf

void preorder(BTNodePtr tempPtr){
	if (!tempPtr){
		return;
	}

	printf("%c", tempPtr->element);
	preorder(tempPtr->lChild);
	preorder(tempPtr->rChild);
}

2、中序遍历:先中序遍历左子树,然后访问根节点,最后中序遍历右子树。中序遍历结果为:bcadef

void inorder(BTNodePtr tempPtr){
	if (!tempPtr){
		return;
	}

	inorder(tempPtr->lChild);
	printf("%c", tempPtr->element);
	inorder(tempPtr->rChild);
}

3、后序遍历:先后序遍历左子树,再后序遍历右子树,最后访问根节点。后序遍历结果为:bcdfea

void postorder(BTNodePtr tempPtr){
	if (!tempPtr){
		return;
	}

	postorder(tempPtr->lChild);
	postorder(tempPtr->rChild);
	printf("%c", tempPtr->element);
}

4、层序遍历:根节点开始,逐层访问各子节点。层序遍历结果为:acebdf

void levelwise(BTNodePtr paraTreePtr){
	//Use a queue to manage the pointers
	char tempString[100];
	int i = 0;
	QueuePtr tempQueuePtr = initQueue();
	BTNodePtr tempNodePtr;
	enqueue(tempQueuePtr,paraTreePtr);
	while(!isQueueEmpty(tempQueuePtr)){
		tempNodePtr = dequeue(tempQueuePtr);
		
		//For output.
		tempString[i] = tempNodePtr->element;
		i ++;

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

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

二、全部代码

(1)代码如下

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

#define QUEUE_SIZE 5
#define true 1
#define false 0

//binary tree node.
typedef struct BTNode{
	char element;
	BTNode* lChild;
	BTNode* rChild;
}BTNode,*BTNodePtr;

//A queue with a number of pointers
typedef struct BTNodePtrQueue{
    BTNodePtr* nodePtrs;
    int front;
    int rear;
}BTNodePtrQueue,*QueuePtr;

//Initialize the queue.(初始化)
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;
}

//Is the queue empty? 判断队是否为空
bool isQueueEmpty(QueuePtr paraQueuePtr){
	if((paraQueuePtr->front + 1)%QUEUE_SIZE == paraQueuePtr->rear){//判断队列是否为空的条件 
		return true;
	}
	else{
		return false;
	}
}

// Add a pointer to the queue.
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("队满!\r\n");
		return;
	}
	paraQueuePtr->nodePtrs[paraQueuePtr->rear] = paraBTNodePtr;
	paraQueuePtr->rear = (paraQueuePtr->rear + 1) % QUEUE_SIZE;
	printf("%c入队.\r\n", paraBTNodePtr->element);
}

// Remove an element from the queue and return.
BTNodePtr dequeue(QueuePtr paraQueuePtr){
	if (isQueueEmpty(paraQueuePtr)) {
		printf("队空!\r\n");
		return NULL;
	}

	paraQueuePtr->front = (paraQueuePtr->front + 1) % QUEUE_SIZE;
	//BTNodePtr tempPtr = paraQueuePtr->nodePtrs[paraQueuePtr->front + 1];

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

// Construct a BTNode using the given char.
BTNodePtr constructBTNode(char paraChar){
	BTNodePtr resultPtr = (BTNodePtr)malloc(sizeof(BTNode));
	resultPtr->element = paraChar;
	resultPtr->lChild = NULL;
	resultPtr->rChild = NULL;
	return resultPtr;
}

// Construct a binary tree using the given string.
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);

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

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

	return resultHeader;
}

// Levelwise.(层序遍历)
void levelwise(BTNodePtr paraTreePtr){
	//用队列存储指针
	char tempString[100];
	int i = 0;
	QueuePtr tempQueuePtr = initQueue();
	BTNodePtr tempNodePtr;
	enqueue(tempQueuePtr,paraTreePtr);
	while(!isQueueEmpty(tempQueuePtr)){
		tempNodePtr = dequeue(tempQueuePtr);
		
		//For output.
		tempString[i] = tempNodePtr->element;
		i ++;

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

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

// Preorder.(前序遍历)
void preorder(BTNodePtr tempPtr){
	if (!tempPtr){
		return;
	}

	printf("%c", tempPtr->element);
	preorder(tempPtr->lChild);
	preorder(tempPtr->rChild);
}

// Inorder.(中序遍历)
void inorder(BTNodePtr tempPtr){
	if (!tempPtr){
		return;
	}

	inorder(tempPtr->lChild);
	printf("%c", tempPtr->element);
	inorder(tempPtr->rChild);
}

// Postorder.(后序遍历)
void postorder(BTNodePtr tempPtr){
	if (!tempPtr){
		return;
	}

	postorder(tempPtr->lChild);
	postorder(tempPtr->rChild);
	printf("%c", tempPtr->element);
}

// The entrance.
int main(){
	BTNodePtr tempHeader;

	char* tempString = "aceb#df######";

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

(2) 运行结果

front = 0, rear = 1.
a入队.
a出队.
front = 1, rear = 2.
c入队.
front = 1, rear = 3.
e入队.
c出队.
front = 2, rear = 4.
b入队.
e出队.
front = 3, rear = 0.
d入队.
front = 3, rear = 1.
f入队.
b出队.
d出队.
f出队.
Preorder: acbedf
Inorder: bcadef
Postorder: bcdfea
Levelwise: front = 0, rear = 1.
a入队.
a出队.
front = 1, rear = 2.
c入队.
front = 1, rear = 3.
e入队.
c出队.
front = 2, rear = 4.
b入队.
e出队.
front = 3, rear = 0.
d入队.
front = 3, rear = 1.
f入队.
b出队.
d出队.
f出队.
Levelwise: acebdf
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小白123**

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值