数据结构作业之二叉树的构建和排列

本文介绍了二叉树的基本概念,包括其定义、特点以及在实际问题中的重要性。通过C语言实现了二叉树节点的结构体,以及队列数据结构用于辅助层次遍历。此外,还提供了创建二叉树、四种遍历(先序、中序、后序、层次)的方法,并给出了具体的代码实现。在示例中,展示了如何使用字符串创建二叉树并进行遍历操作。

二叉树

二叉树(Binary tree)是树形结构的一个重要类型。许多实际问题抽象出来的数据结构往往是二叉树形式,即使是一般的树也能简单地转换为二叉树,而且二叉树的存储结构及其算法都较为简单,因此二叉树显得特别重要。二叉树特点是每个节点最多只能有两棵子树,且有左右之分 。

二叉树是n个有限元素的集合,该集合或者为空、或者由一个称为根(root)的元素及两个不相交的、被分别称为左子树和右子树的二叉树组成,是有序树。当集合为空时,称该二叉树为空二叉树。在二叉树中,一个元素也称作一个节点 。

头函数及结构体

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

创建单个节点及二叉树

/*
 * 用给定的字符创建一个BTNode的节点 
 */
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=0;
	char ch;
	
	// 用队列来管理指针
	QueuePtr tempQueuePtr=initQueue();
	
	BTNodePtr resultHeader;
	BTNodePtr tempParent, tempLeftChild, tempRightChild;
	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;
	}
	
	preorder(tempPtr->left);
	printf("%c",tempPtr->element);
	preorder(tempPtr->right);
}

/*
 * 后序遍历 
 */
void postorder(BTNodePtr tempPtr){
	if(tempPtr==NULL){
		return;
	}
	
	preorder(tempPtr->left);
	preorder(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: ");
	preorder(tempHeader);
	printf("\r\n");
	printf("Postorder: ");
	preorder(tempHeader);
	printf("\r\n");
	printf("Levelwise: ");
	levelwise(tempHeader);
	printf("\r\n"); 
	
	return 0; 
} 

输出结果

There is only one node. Preorder visit: c
front = 0, rear = 1.
enqueue a ends.
dequeue a ends.
front = 1, rear = 2.
enqueue c ends.
front = 1, rear = 3.
enqueue d ends.
dequeue c ends.
front = 2, rear = 4.
enqueue e ends.
dequeue d ends.
front = 3, rear = 0.
enqueue b ends.
front = 3, rear = 1.
enqueue f ends.
dequeue e ends.
dequeue b ends.
dequeue f ends.
Preorder: acedbf
Inorder: ceadbf
Postorder: cedbfa
Levelwise: front = 0, rear = 1.
enqueue a ends.
dequeue a ends.
front = 1, rear = 2.
enqueue c ends.
front = 1, rear = 3.
enqueue d ends.
dequeue c ends.
front = 2, rear = 4.
enqueue e ends.
dequeue d ends.
front = 3, rear = 0.
enqueue b ends.
front = 3, rear = 1.
enqueue f ends.
dequeue e ends.
dequeue b ends.
dequeue f ends.
Levelwise: acdebf


--------------------------------
Process exited after 0.0106 seconds with return value 0
请按任意键继续. . .

完整代码

#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];
}
/*
 * 用给定的字符创建一个BTNode的节点 
 */
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=0;
	char ch;
	
	// 用队列来管理指针
	QueuePtr tempQueuePtr=initQueue();
	
	BTNodePtr resultHeader;
	BTNodePtr tempParent, tempLeftChild, tempRightChild;
	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;
	}
	
	preorder(tempPtr->left);
	printf("%c",tempPtr->element);
	preorder(tempPtr->right);
}

/*
 * 后序遍历 
 */
void postorder(BTNodePtr tempPtr){
	if(tempPtr==NULL){
		return;
	}
	
	preorder(tempPtr->left);
	preorder(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 0; 
} 
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值