
树是一种非线性数据结构,由n个结点组成的有层次关系的集合,而二叉树是树的一种,特点是最多只有两个子树。一个二叉树由三部分组成,根结点、左子树、右子树。
二叉树的操作 1.队列及相关操作(辅助实现二叉树)队列中存放二叉树结点
//定义队列
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.rn", paraQueuePtr->front, paraQueuePtr->rear);
if ((paraQueuePtr->rear + 1) % QUEUE_SIZE == paraQueuePtr->front % QUEUE_SIZE)
{
printf("队满,不能入队.rn", paraBTNodePtr->element);
return;
}
paraQueuePtr->nodePtrs[paraQueuePtr->rear] = paraBTNodePtr;
paraQueuePtr->rear = (paraQueuePtr->rear + 1) % QUEUE_SIZE;
printf("入队 %c.rn", paraBTNodePtr->element);
}
//出队
BTNodePtr dequeue(QueuePtr paraQueuePtr)
{
if(isQueueEmpty(paraQueuePtr))
{
printf("队空,不能出队.rn");
return NULL;
}
paraQueuePtr->front = (paraQueuePtr->front + 1) % QUEUE_SIZE;
printf("出队 %c.rn", paraQueuePtr->nodePtrs[paraQueuePtr->front]->element);
return paraQueuePtr->nodePtrs[paraQueuePtr->front];
}
2.二叉树结点
//二叉树结点
typedef struct BTNode
{
char element;
struct BTNode* left;
struct BTNode* right;
} BTNode, *BTNodePtr;
3.初始化
//初始化二叉树
BTNodePtr constructBTNode(char paraChar)
{
BTNodePtr resultPtr = (BTNodePtr)malloc(sizeof(BTNode));
resultPtr->element = paraChar;
resultPtr->left = NULL;
resultPtr->right = NULL;
return resultPtr;
}
4.创建二叉树
//创建二叉树
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;
}
图解
5.遍历(递归) 1.前序遍历
根左右,示例遍历结果: abdfhce
//前序遍历
void preorder(BTNodePtr tempPtr)
{
if (tempPtr == NULL)
{
return;
}
printf("%c", tempPtr->element);
preorder(tempPtr->left);
preorder(tempPtr->right);
}
2.中序遍历
左根右,示例遍历结果: dfbhace
//中序遍历
void inorder(BTNodePtr tempPtr)
{
if(tempPtr == NULL)
{
return;
}
inorder(tempPtr->left);
printf("%c", tempPtr->element);
inorder(tempPtr->right);
}
3.后序遍历
左右根,示例遍历结果:fdhbeca
//后序遍历
void postorder(BTNodePtr tempPtr)
{
if (tempPtr == NULL) {
return;
}//Of if
postorder(tempPtr->left);
postorder(tempPtr->right);
printf("%c", tempPtr->element);
}
4.层序遍历
示例遍历结果:abcdhef
//层序遍历
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] = ' ';
printf("层序遍历: %srn", tempString);
}
总代码
#include运行结果#include #include #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.rn", paraQueuePtr->front, paraQueuePtr->rear); if ((paraQueuePtr->rear + 1) % QUEUE_SIZE == paraQueuePtr->front) { printf("队满,不能入队.rn", paraBTNodePtr->element); return; } paraQueuePtr->nodePtrs[paraQueuePtr->rear] = paraBTNodePtr; paraQueuePtr->rear = (paraQueuePtr->rear + 1) % QUEUE_SIZE ; printf("入队 %c.rn", paraBTNodePtr->element); } //出队 BTNodePtr dequeue(QueuePtr paraQueuePtr) { if(isQueueEmpty(paraQueuePtr)) { printf("队空,不能出队.rn"); return NULL; } paraQueuePtr->front = (paraQueuePtr->front + 1) % QUEUE_SIZE ; printf("出队 %c.rn", 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] = ' '; printf("层序遍历: %srn", 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; }//Of if postorder(tempPtr->left); postorder(tempPtr->right); printf("%c", tempPtr->element); } int main() { BTNodePtr tempHeader; tempHeader = constructBTNode('c'); printf("只有一个结点时. 先序遍历: "); preorder(tempHeader); printf("rn"); char* tempString = "abcdh#e#f######"; tempHeader = stringToBTree(tempString); printf("前序遍历: "); preorder(tempHeader); printf("rn"); printf("中序遍历: "); inorder(tempHeader); printf("rn"); printf("后序遍历: "); postorder(tempHeader); printf("rn"); printf("层序遍历: "); levelwise(tempHeader); printf("rn"); return 1; }
只有一个结点时. 先序遍历: c front = 0, rear = 1. 入队 a. 出队 a. front = 1, rear = 2. 入队 b. front = 1, rear = 3. 入队 c. 出队 b. front = 2, rear = 4. 入队 d. front = 2, rear = 0. 入队 h. 出队 c. front = 3, rear = 1. 入队 e. 出队 d. front = 4, rear = 2. 入队 f. 出队 h. 出队 e. 出队 f. 前序遍历: abdfhce 中序遍历: dfbhace 后序遍历: fdhbeca 层序遍历: front = 0, rear = 1. 入队 a. 出队 a. front = 1, rear = 2. 入队 b. front = 1, rear = 3. 入队 c. 出队 b. front = 2, rear = 4. 入队 d. front = 2, rear = 0. 入队 h. 出队 c. front = 3, rear = 1. 入队 e. 出队 d. front = 4, rear = 2. 入队 f. 出队 h. 出队 e. 出队 f. 层序遍历: abcdhef