一、代码
#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;
} //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 is 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;
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;
}//of if
//右分支
i++;
ch = paraString[i];
if(ch == '#'){
tempRightChild->right = NULL;
}else{
tempRightChild = constructBTNode(ch);
enqueue(tempQueuePtr, tempRightChild);
tempParent->right = tempRightChild;
}//of if
}// of while
return resultHeader;
} //of stringToBTree
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);
}//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
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;
}//of main
二、运行结果
三、代码说明与分析
1)该代码首先进行了一个循环队列的元素加入与删除,并在测试的时候跟踪了在删除和添加的过程中front和rear的变化,让我对循环队列的印象进一步加深。
2)前序遍历:首先判断当前节点是否为空,如果为空则返回。然后访问当前节点。接着递归地访问当前节点的左子树。递归地访问当前节点的右子树。最后返回。
中序遍历:首先判断当前节点是否为空,如果为空则返回。然后递归地访问当前节点的左子树。接着访问当前节点。递归地访问当前节点的右子树。最后返回。
后序遍历:首先判断当前节点是否为空,如果为空则返回。然后递归地访问当前节点的左子树。递归地访问当前节点的右子树。接着访问当前节点。最后返回。
3)层次遍历:从根节点出发,依次访问左右孩子结点,再从左右孩子出发,依次它们的孩子结点,直到节点访问完毕。层次遍历与前中后序遍历不同,层次遍历体现了队列的思想。在根节点入队后,其两个子节点会跟着入队,然后根节点出队,以此类推。