二叉树前序遍历
- 打印当前节点,将该节点入栈。如果该节点有左子树,访问左子树,重复此步骤,直到没有左子树。
- 访问栈顶元素的右孩子,并出栈。重复1的操作。
- 当栈为空且指针为空时,遍历结束。
二叉树中序遍历
- 将当前节点入栈。如果有左孩子,访问左孩子,重复此步骤,直至没有左孩子。
- 打印栈顶元素,出栈,访问栈顶右孩子,重复步骤1。
- 当栈为空且指针为空时遍历结束。
二叉树后序遍历
- 将当前节点入栈,清空该节点的标记。如果有左孩子,访问左孩子,重复此步骤,直至没有左孩子。
- 标记栈顶元素,访问栈顶元素的右孩子,重复1步骤。如果当前栈顶元素被标记过则打印栈顶元素并出栈,设置指针为空。
- 当栈为空且指针为空则遍历结束。
BTree.h
#ifndef _BTREE_H_
#define _BTREE_H_
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef char BTDataType;
typedef struct BinaryTreeNode
{
BTDataType _Bdata;
struct BinaryTreeNode* _left;
struct BinaryTreeNode* _right;
}BTNode;
typedef BTNode* DataType;
typedef struct QueueNode
{
DataType _Qdata;
struct QueueNode* _next;
}QueueNode;
typedef struct Queue
{
QueueNode* _front; // 队头
QueueNode* _rear; // 队尾
}Queue;
typedef BTNode* STDataType;
typedef struct Stack
{
STDataType* _a;
int _top; // 栈顶
int _capacity; // 容量
}Stack;
void StackInit(Stack* ps, BTNode *test);
void StackDestory(Stack* ps);
void StackPush(Stack* ps, STDataType x);
void StackPop(Stack* ps);
STDataType StackTop(Stack* ps);
int StackEmpty(Stack* ps);
int StackSize(Stack* ps);
// 通过前序遍历的数组"ABD##E#H##CF##G##"构建二叉树
BTNode* BinaryTreeCreate(BTDataType* a);
void BinaryTreeDestory(BTNode** root);
int BinaryTreeSize(BTNode* root);
int BinaryTreeLeafSize(BTNode* root);
int BinaryTreeLevelKSize(BTNode* root, int k);
BTNode* BinaryTreeFind(BTNode* root, BTDataType x);
// 遍历
void BinaryTreePrevOrder(BTNode* root);
void BinaryTreeInOrder(BTNode* root);
void BinaryTreePostOrder(BTNode* root);
void QueueInit(Queue *que, BTNode *test);
void QueuePush(Queue *pq, BTNode *node);
void BinaryTreeLevelOrder(BTNode* root);
// 非递归遍历
// 层序遍历
void BinaryTreeLevelOrder(BTNode* root);
// 判断二叉树是否是完全二叉树
int BinaryTreeComplete(BTNode* root);
void BinaryTreePrevOrderNonR(BTNode* root);
void BinaryTreeInOrderNonR(BTNode* root);
void BinaryTreePostOrderNonR(BTNode* root);
#endif /*_BTREE_H_*/
BTree.c
#include"BTree.h"
// 通过前序遍历的数组"ABD##E#H##CF##G##"构建二叉树
BTNode* BinaryTreeCreate(BTDataType* a)
{
static int i = 0;
if (a[i] == '#')
{
i++;
return NULL;
}
else
{
BTNode *node = (BTNode*)malloc(sizeof(BTNode));
node->_Bdata = a[i];
i++;
node->_left = BinaryTreeCreate(a);
node->_right = BinaryTreeCreate(a);
return node;
}
}
void BinaryTreeDestory(BTNode** root)
{
if ((*root)->_left != NULL)
BinaryTreeDestory(&(*root)->_left);
if ((*root)->_right != NULL)
BinaryTreeDestory(&(*root)->_right);
free(*root);
}
int BinaryTreeSize(BTNode* root)
{
int count = 0;
if (root == NULL)
count = 0;
else
count = 1 + BinaryTreeSize(root->_left) + BinaryTreeSize(root->_right);
return count;
}
int BinaryTreeLeafSize(BTNode* root)
{
int count = 0;
if (root == NULL)
count = 0;
else if (root->_left == NULL&&root->_right == NULL)
count = 1;
else
count = BinaryTreeLeafSize(root->_left) + BinaryTreeLeafSize(root->_right);
return count;
}
int BinaryTreeLevelKSize(BTNode* root, int k)//计算第k层结点的个数
{
int count = 0;
if (root == NULL)
count = 0;
else if (k == 1)
count = 1;
else
count = BinaryTreeLevelKSize(root->_left, k - 1) + BinaryTreeLevelKSize(root->_right, k - 1);
return count;
}
BTNode* BinaryTreeFind(BTNode* root, BTDataType x)
{
static BTNode* bn = NULL;
if (root->_Bdata == x)
{
bn = root;
return root;
}
if (root->_left != NULL)
BinaryTreeFind(root->_left, x);
if (root->_right != NULL)
BinaryTreeFind(root->_right, x);
return bn;
}
// 遍历
void BinaryTreePrevOrder(BTNode* root)
{
if (root != NULL)
{
printf("%c", root->_Bdata);
BinaryTreePrevOrder(root->_left);
BinaryTreePrevOrder(root->_right);
}
}
void BinaryTreeInOrder(BTNode* root)
{
if (root != NULL)
{
BinaryTreeInOrder(root->_left);
printf("%c", root->_Bdata);
BinaryTreeInOrder(root->_right);
}
}
void BinaryTreePostOrder(BTNode* root)
{
if (root != NULL)
{
BinaryTreePostOrder(root->_left);
BinaryTreePostOrder(root->_right);
printf("%c", root->_Bdata);
}
}
void QueueInit(Queue *que, BTNode *test)
{
QueueNode *node = (QueueNode*)malloc(sizeof(QueueNode));
node->_Qdata = test;
node->_next = NULL;
que->_front = que->_rear = node;
}
void QueuePush(Queue *pq, BTNode *node)
{
QueueNode *Qnode = (QueueNode*)malloc(sizeof(QueueNode));
pq->_rear->_next = Qnode;
Qnode->_next = NULL;
Qnode->_Qdata = node;
pq->_rear = pq->_rear->_next;
}
// 层序遍历
void BinaryTreeLevelOrder(BTNode* root)
{
Queue *pq = (Queue*)malloc(sizeof(Queue));
QueueInit(pq, root);
while (pq->_front != NULL)
{
if (pq->_front->_Qdata->_left != NULL)
QueuePush(pq, pq->_front->_Qdata->_left);
if (pq->_front->_Qdata->_right != NULL)
QueuePush(pq, pq->_front->_Qdata->_right);
printf("%c", pq->_front->_Qdata->_Bdata);
QueueNode *pt = pq->_front;
pq->_front = pq->_front->_next;
free(pt);
}
printf("\n");
}
// 判断二叉树是否是完全二叉树
int BinaryTreeComplete(BTNode* root)
{
Queue *pq = (Queue*)malloc(sizeof(Queue));
QueueInit(pq, root);
int key = 0;
while (pq->_front != NULL)
{
if (pq->_front->_Qdata->_left == NULL&&pq->_front->_Qdata->_right != NULL)
return 0;
if (key && (pq->_front->_Qdata->_left != NULL || pq->_front->_Qdata->_right != NULL))
return 0;
if (pq->_front->_Qdata->_right == NULL)
key = 1;
if (pq->_front->_Qdata->_left != NULL)
QueuePush(pq, pq->_front->_Qdata->_left);
if (pq->_front->_Qdata->_right != NULL)
QueuePush(pq, pq->_front->_Qdata->_right);
QueueNode *pt = pq->_front;
pq->_front = pq->_front->_next;
free(pt);
}
return 1;
}
void BinaryTreePrevOrderNonR(BTNode* root)
{
Stack test;
StackInit(&test, root);
while (!StackEmpty(&test) || root != NULL)
{
printf("%c", root->_Bdata);
if (root->_right != NULL)
StackPush(&test, root->_right);
if (root->_left != NULL)
root = root->_left;
else
{
root = StackTop(&test);
StackPop(&test);
}
}
StackDestory(&test);
}
void BinaryTreeInOrderNonR(BTNode* root)
{
Stack test;
StackInit(&test, root);
while (!StackEmpty(&test) || root != NULL)
{
while (root != NULL)
{
StackPush(&test, root);
root = root->_left;
}
root = StackTop(&test);
StackPop(&test);
putchar(root->_Bdata);
root = root->_right;
}
StackDestory(&test);
}
void BinaryTreePostOrderNonR(BTNode* root)
{
BTNode * cur = root;
Stack st;
int tag[32] = { 0 }; //左孩子遍历标签
StackInit(&st, cur);
while (cur || !StackEmpty(&st))
{
for (; cur; cur = cur->_left) //类似中序,将左孩子入栈,cur为空时,代表上一个节点的右孩子为空,只有这种情况,才可能进入下面的while
{
StackPush(&st, cur); //push操作会导致size+1
tag[st._top+1] = 0; //由于入栈的是左孩子,所以这里的左孩子遍历标签置0
}
//只要上面的for执行过哪怕一次循环(右孩子不为空),这个while的后半部分条件都不可能满足
while (!StackEmpty(&st) && tag[st._top+1] == 1) //左孩子还没遍历完成时,不能进入打印
//所以,这里确保了只有左右子树都遍历完成时,才会进入这个while
{
cur = StackTop(&st);
putchar(cur->_Bdata); //打印根
StackPop(&st); //pop操作会导致size-1
cur = NULL; //为了循环正常跳出
}
if (!StackEmpty(&st))
{
tag[st._top+1] = 1; //进入这里证明左子树遍历完毕,左子树标签置1
cur = StackTop(&st)->_right; //进入右子树继续遍历
}
}
StackDestory(&st);
/*int bool[26] = { 0 };
Stack test;
StackInit(&test, root);
while (!StackEmpty(&test) || root != NULL)
{
while (root != NULL)
{
if (bool[root->_Bdata - 'A'] == 0)
{
StackPush(&test, root);
bool[root->_Bdata - 'A'] = 1;
}
if (root->_right != NULL)
{
if (bool[root->_right->_Bdata - 'A'] == 0)
{
StackPush(&test, root->_right);
bool[root->_right->_Bdata - 'A'] = 1;
}
}
if (root->_left != NULL&&bool[root->_left->_Bdata - 'A'] == 1)
break;
root = root->_left;
}
root = StackTop(&test);
if (root->_left != NULL&&bool[root->_left->_Bdata - 'A'] == 0)
continue;
if (root->_right == NULL||bool[root->_right->_Bdata - 'A'] == 1)
{
StackPop(&test);
putchar(root->_Bdata);
root = StackTop(&test);
}
if (root != NULL&&root->_right != NULL&&bool[root->_right->_Bdata - 'A'] == 0)
{
root = root->_right;
}
}
StackDestory(&test);*/
}
void StackInit(Stack* ps, BTNode *test)
{
int size = BinaryTreeSize(test);
ps->_a = (STDataType*)malloc(size*sizeof(STDataType));
ps->_capacity = size;
ps->_top = -1;
}
void StackDestory(Stack* ps)
{
free(ps->_a);
ps->_capacity = 0;
ps->_top = -1;
}
void StackPush(Stack* ps, STDataType x)
{
ps->_top++;
ps->_a[ps->_top] = x;
}
void StackPop(Stack* ps)
{
if (ps->_top > -1)
ps->_top--;
}
STDataType StackTop(Stack* ps)
{
if (ps->_top == -1)
return NULL;
return ps->_a[ps->_top];
}
int StackEmpty(Stack* ps)
{
if (ps->_top == -1)
return 1;
return 0;
}
int StackSize(Stack* ps)
{
return ps->_top + 1;
}
main.c
#include"BTree.h"
int main()
{
BTNode *test = BinaryTreeCreate("ABDF####CE#GH##I#J###");
printf("%d\n", BinaryTreeSize(test));
printf("%d\n", BinaryTreeLeafSize(test));
//printf("%d\n", BinaryTreeLeve1KSize(test,5));
printf("%p\n", BinaryTreeFind(test, 'D'));
BinaryTreePrevOrder(test);
printf("\n");
BinaryTreePrevOrderNonR(test);
printf("\n");
BinaryTreeInOrder(test);
printf("\n");
BinaryTreeInOrderNonR(test);
printf("\n");
BinaryTreePostOrder(test);
printf("\n");
BinaryTreePostOrderNonR(test);
printf("\n");
BinaryTreeLevelOrder(test);
printf("%d\n", BinaryTreeComplete(test));
printf("%d\n", BinaryTreeLevelKSize(test, 7));
BinaryTreeDestory(&test);
return 0;
}