二叉树的构建与遍历

2022-07-16 13:49:58

引言

树是一种比较重要的数据结构,尤其是二叉树。在这里简单介绍二叉树。

二叉树是一种特殊的树,在二叉树中每个节点最多有两个子节点,一般称为左子节点和右子节点(或左孩子和右孩子),并且二叉树的子树有左右之分,其次序不能任意颠倒。

1. 二叉树的定义

二叉树是n(n>=0)个结点的有限集合,该集合或者为空集(称为空二叉树),或者由一个根结点和两棵互不相交的、分别称为根结点的左子树和右子树组成。

2. 二叉树的遍历

二叉树的存储分为顺序存储链式存储 。顺序存储在右斜树这种极端情况下,会十分浪费存储空间,顺序存储结构一般适用于完全二叉树。因此二叉树的存储一般会使用链式存储,在这里只介绍链式存储:

二叉树的链式存储结构,将节点的数据结构定义为一个数据域和两个指针域,如下图所示:

一、结构体的定义

typedef struct BTNode{
 	char element;
 	BTNode* left;
 	BTNode* right;
 }BTNode, *BTNodePtr;
 
 /**
  * A queue with a number of pointer;
  */
  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;
   }// of initQueue

三、判断是否为空

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

四、入队

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;
		}// Of if
		paraQueuePtr->nodePtrs[paraQueuePtr->rear] = paraBTNodePtr;
		paraQueuePtr->rear = (paraQueuePtr->rear +1)% QUEUE_SIZE;
		printf("enqueue %c ends.\r\n",paraBTNodePtr->element);
	}// Of enqueue

五、出队

BTNodePtr dequeue(QueuePtr paraQueuePtr){
		if(isQueueEmpty(paraQueuePtr)) {
			printf("Error, empty queue\r\n");
			return NULL;
		}// Of if
		
		paraQueuePtr->front = (paraQueuePtr->front + 1) % QUEUE_SIZE;
		// BTNodePtr tempPtr = paraQueuePtr->nodePtrs[paraQueuePtr->front +1 ];
		
		printf("dequeue %c ends.\r\n",paraQueuePtr->nodePtrs[paraQueuePtr->front]->element);
		return paraQueuePtr->nodePtrs[paraQueuePtr->front];
	}// Of dequeue

六、构造一个结点

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

七、将字符串转化成函数

BTNodePtr stringToBTree(char* paraString){
	  	int i;
	  	char ch;
	  	
	  	//Use a queue to manage the pointers.
	  	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->left = NULL;
			  }else{
			  	tempLeftChild = constructBTNode(ch);
			  	enqueue(tempQueuePtr, tempLeftChild);
			  	tempParent->left = tempLeftChild;
			  }// Of if
			  
			  
			  // The right child
			  i++;
			  ch = paraString[i];
			  if(ch == '#'){
			  	tempParent->right = NULL;
			  } else {
			  	tempRightChild = constructBTNode(ch);
			  	enqueue(tempQueuePtr, tempRightChild);
			  	tempParent->right = tempRightChild;
			  } // Of if
		  }//Of while
		  
		  return resultHeader;
	  }// Of stringToBTree;

八、层序遍历

 void levelwise(BTNodePtr paraTreePtr){
	   	// Use a queue to mange the pointer.
	   	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->left != NULL){
	   			enqueue(tempQueuePtr, tempNodePtr->left);
			   }// Of if
			   if(tempNodePtr->right != NULL){
			   	enqueue(tempQueuePtr, tempNodePtr->right);
			   }// Of if
		   }// Of while
		   tempString[i] = '\0';
		   
		   printf("Levelwise: %s\r\n",tempString);
	   }// Of levelwise

九、先序

 void preorder(BTNodePtr tempPtr){
	    	if(tempPtr == NULL){
	    		return;
			}// Of if
			
			printf("%c,tempPtr->element");
			preorder(tempPtr->left);
			preorder(tempPtr->right);
		}// Of preorder

十、中序

 void inorder(BTNodePtr tempPtr){
		 	if(tempPtr == NULL){
		 		return;
			 }// Of if
			 
			 inorder(tempPtr->left);
			 printf("%c", tempPtr->element);
			 inorder(tempPtr->right);
		 }// Of inorder

十一、后序

void postorder(BTNodePtr tempPtr){
		  	if(tempPtr == NULL){
		  		return;
			  }// Of if
			  
			  postorder(tempPtr->left);
			  postorder(tempPtr->right);
			  printf("%c",tempPtr->element);
		  }// Of postorder.

十二、完整代码

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

#define QUEUE_SIZE 5

/**
 * Binary tree node
 */
 typedef struct BTNode{
 	char element;
 	BTNode* left;
 	BTNode* right;
 }BTNode, *BTNodePtr;
 
 /**
  * A queue with a number of pointer;
  */
  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;
   }// of initQueue
   
   /**
    * Is the queue empty?
    */
    bool isQueueEmpty(QueuePtr paraQueuePtr){
    	if((paraQueuePtr->front + 1)% QUEUE_SIZE == paraQueuePtr->rear){
    		return true;
		}// Of if
		
		return false;
	}// Of isQueueEmpty
	
	/**
	* 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("Error, trying to enqueue %c.queue full.\r\n",paraBTNodePtr->element);
			return;
		}// Of if
		paraQueuePtr->nodePtrs[paraQueuePtr->rear] = paraBTNodePtr;
		paraQueuePtr->rear = (paraQueuePtr->rear +1)% QUEUE_SIZE;
		printf("enqueue %c ends.\r\n",paraBTNodePtr->element);
	}// Of enqueue
	
	/**
	* Remove an element from the queue and return.
	*/
	BTNodePtr dequeue(QueuePtr paraQueuePtr){
		if(isQueueEmpty(paraQueuePtr)) {
			printf("Error, empty queue\r\n");
			return NULL;
		}// Of if
		
		paraQueuePtr->front = (paraQueuePtr->front + 1) % QUEUE_SIZE;
		// BTNodePtr tempPtr = paraQueuePtr->nodePtrs[paraQueuePtr->front +1 ];
		
		printf("dequeue %c ends.\r\n",paraQueuePtr->nodePtrs[paraQueuePtr->front]->element);
		return paraQueuePtr->nodePtrs[paraQueuePtr->front];
	}// Of dequeue
	
	/**
	 * Construct a BTNode using the given char.
	 */
	 BTNodePtr constructBTNode(char paraChar){
	 	BTNodePtr resultPtr = (BTNodePtr)malloc(sizeof(BTNode));
	 	resultPtr->element = paraChar;
	 	resultPtr->left = NULL;
	 	resultPtr->right = NULL;
	 	return resultPtr;
	 }// Of constructBTNode
	 
	 /**
	  * Construct a binary tree using the given string.
	  */
	  BTNodePtr stringToBTree(char* paraString){
	  	int i;
	  	char ch;
	  	
	  	//Use a queue to manage the pointers.
	  	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->left = NULL;
			  }else{
			  	tempLeftChild = constructBTNode(ch);
			  	enqueue(tempQueuePtr, tempLeftChild);
			  	tempParent->left = tempLeftChild;
			  }// Of if
			  
			  
			  // The right child
			  i++;
			  ch = paraString[i];
			  if(ch == '#'){
			  	tempParent->right = NULL;
			  } else {
			  	tempRightChild = constructBTNode(ch);
			  	enqueue(tempQueuePtr, tempRightChild);
			  	tempParent->right = tempRightChild;
			  } // Of if
		  }//Of while
		  
		  return resultHeader;
	  }// Of stringToBTree;
	  
	  /**
	   * Levelwise.
	   */
	   void levelwise(BTNodePtr paraTreePtr){
	   	// Use a queue to mange the pointer.
	   	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->left != NULL){
	   			enqueue(tempQueuePtr, tempNodePtr->left);
			   }// Of if
			   if(tempNodePtr->right != NULL){
			   	enqueue(tempQueuePtr, tempNodePtr->right);
			   }// Of if
		   }// Of while
		   tempString[i] = '\0';
		   
		   printf("Levelwise: %s\r\n",tempString);
	   }// Of levelwise
	   
	   /**
	    * Preorder.
	    */
	    void preorder(BTNodePtr tempPtr){
	    	if(tempPtr == NULL){
	    		return;
			}// Of if
			
			printf("%c,tempPtr->element");
			preorder(tempPtr->left);
			preorder(tempPtr->right);
		}// Of preorder
		
		/**
		 * Inorder.
		 */
		 void inorder(BTNodePtr tempPtr){
		 	if(tempPtr == NULL){
		 		return;
			 }// Of if
			 
			 inorder(tempPtr->left);
			 printf("%c", tempPtr->element);
			 inorder(tempPtr->right);
		 }// Of inorder
		 
		 /**
		  * Post order.
		  */
		  void postorder(BTNodePtr tempPtr){
		  	if(tempPtr == NULL){
		  		return;
			  }// Of if
			  
			  postorder(tempPtr->left);
			  postorder(tempPtr->right);
			  printf("%c",tempPtr->element);
		  }// Of postorder.
		  
		  /**
		   * The entrance.
		   */
		   int main(){
		   	BTNodePtr tempHeader;
		   	tempHeader = constructBTNode('c');
		   	printf("There is only one node. Preorder visit: ");
		   	preorder(tempHeader);
		   	printf("\r\n");
		   	
		   	char* tempString = "abde#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; 
		   }// Of main

十三、运行代码

There is only one node. Preorder visit: 0,tempPtr->element
front = 0, rear = 1.
enqueue a ends.
dequeue a ends.
front = 1, rear = 2.
enqueue d ends.
dequeue d ends.
Preorder: 0,tempPtr->element0,tempPtr->element
Inorder: ad
Postorder: da
Levelwise: front = 0, rear = 1.
enqueue a ends.
dequeue a ends.
front = 1, rear = 2.
enqueue d ends.
dequeue d ends.
Levelwise: ad
  • 作者:Minion。。
  • 原文链接:https://blog.csdn.net/qq_70137750/article/details/124923906
    更新时间:2022-07-16 13:49:58