BinaryTree.h
#pragma once
#include<stdio.h>
#include<malloc.h>
#include<assert.h>
#include<stdlib.h>
#include<string.h>
#include"Queue.h"
typedef char BTDataType;
//树
typedef struct TreeNode
{
BTDataType _data;
struct TreeNode* _fristChild;
struct TreeNode* _nextBrother;
}TreeNode;
//二叉树
typedef struct BTNode
{
BTDataType _data;
struct BTNode* _left; //左孩子
struct BTNode* _right; //有孩子
}BTNode;
//创建二叉树
BTNode* CreateBTree(BTNode **ppRoot,BTDataType* arr, size_t *pIndex, BTDataType invalid, size_t len);
//创建一个节点
BTNode* BuyBTNode(BTDataType data);
//前序遍历递归
void BTreePrevOrderRV(BTNode *pRoot);
//中序遍历递归
void BTreeInOrderRV(BTNode *pRoot);
//后序遍历递归
void BTreePostOrderRV(BTNode *pRoot);
//层序遍历
void BTreeLevelOrder(BTNode *pRoot);
//拷贝二叉树
BTNode* CopyBinaryTree(BTNode *pRoot);
//求二叉树节点个数
size_t BinaryTreeSize(BTNode *pRoot);
//销毁二叉树
void BinaryTreeDestory(BTNode **pRoot);
//求叶子节点
size_t BinaryTreeLeafSize(BTNode *pRoot, size_t *count);
//二叉树的镜像(递归)
void BinaryTreeMirrorRV(BTNode *pRoot);
//二叉树的镜像(非递归)
void BinaryTreeMirror(BTNode *pRoot);
//求第k层的节点个数
size_t BinaryTreeKNode(BTNode *pRoot, int k);
//求二叉树的高度
size_t BinaryTreeHeight(BTNode *pRoot);
//判断是否是完全二叉树
int IsCompleteBinaryTree(BTNode *pRoot);
//找当前树中是否有data这个数
BTNode* FindDataBinaryTree(BTNode *pRoot, BTDataType data);
//找当前树中是否有这个节点
int FindNodeBinaryTree(BTNode *pRoot, BTNode *node);
//非递归前序遍历(方法一)
void BinaryTreePrevOrder1(BTNode *pRoot);
//非递归前序遍历(方法二)
void BinaryTreePrevOrder2(BTNode *pRoot);
//非递归的中序遍历
void BinaryTreeInOrder(BTNode *pRoot);
//后序非递归遍历
void BinaryTreePostOrder(BTNode *pRoot);
BinaryTree.c
#include"BinaryTree.h"
#include"Queue.h"
BTNode* BuyBTNode(BTDataType data)
{
BTNode *newnode = (BTNode*)malloc(sizeof(BTNode));
if (NULL == newnode)
{
assert(0);
return NULL;
}
newnode->_data = data;
newnode->_left = NULL;
newnode->_right = NULL;
return newnode;
}
//创建二叉树
BTNode* CreateBTree(BTNode **ppRoot, BTDataType* arr, size_t *pIndex, BTDataType invalid, size_t len)
{
assert(ppRoot);
if ((*pIndex < len) && (invalid != arr[*pIndex]))
{
//创建根节点
*ppRoot = BuyBTNode(arr[*pIndex]);
//创建左子树
++(*pIndex);
(*ppRoot)->_left = CreateBTree(&((*ppRoot)->_left), arr, &(*pIndex), invalid, len);
//创建右子树
++(*pIndex);
(*ppRoot)->_right = CreateBTree(&((*ppRoot)->_right), arr, &(*pIndex), invalid, len);
}
return *ppRoot;
}
//前序遍历
void BTreePrevOrderRV(BTNode *pRoot)
{
if (NULL == pRoot)
return;
printf("%c ", pRoot->_data);
BTreePrevOrderRV(pRoot->_left);
BTreePrevOrderRV(pRoot->_right);
}
//中序遍历
void BTreeInOrderRV(BTNode *pRoot)
{
if (NULL == pRoot)
return;
BTreeInOrderRV(pRoot->_left);
printf("%c ", pRoot->_data);
BTreeInOrderRV(pRoot->_right);
}
//后序遍历
void BTreePostOrderRV(BTNode *pRoot)
{
if (NULL == pRoot)
return;
BTreePostOrderRV(pRoot->_left);
BTreePostOrderRV(pRoot->_right);
printf("%c ", pRoot->_data);
}
//层序遍历
void BTreeLevelOrder(BTNode *pRoot)
{
BTNode *cur = NULL;
Queue q;
QueueInit(&q);
if (NULL == pRoot)
return;
//根节点入队列
QueuePush(&q, pRoot);
while (EmptyQueue(&q))
{
//先遍历根节点
cur = QueueFront(&q);
printf("%c ", cur->_data);
//遍历完出队列
QueuePop(&q);
//左子树存在则遍历
if (cur->_left)
QueuePush(&q, cur->_left);
//右子树存在则遍历
if (cur->_right)
QueuePush(&q, cur->_right);
}
}
//拷贝二叉树
BTNode* CopyBinaryTree(BTNode *pRoot)
{
BTNode *newtree = NULL;
if (NULL == pRoot)
return NULL;
newtree = pRoot;
newtree->_left = CopyBinaryTree(pRoot->_left);
newtree->_right = CopyBinaryTree(pRoot->_right);
return newtree;
}
size_t BinaryTreeSize(BTNode *pRoot)
{
size_t left = 0;
size_t right = 0;
if (NULL == pRoot)
return 0;
//left = left + BinaryTreeSize(pRoot->_left);
//right = right + BinaryTreeSize(pRoot->_right);
//return left + right + 1;
return BinaryTreeSize(pRoot->_left) + right + BinaryTreeSize(pRoot->_right) + 1;
}
//销毁二叉树
void BinaryTreeDestory(BTNode **pRoot)
{
assert(pRoot);
if (*pRoot) //如果树不为空
{
//销毁左子树
BinaryTreeDestory(&(*pRoot)->_left);
//销毁右子树
BinaryTreeDestory(&(*pRoot)->_right);
//销毁根
free(*pRoot);
*pRoot = NULL;
}
}
//求叶子节点
size_t BinaryTreeLeafSize(BTNode *pRoot, size_t *count)
{
if (NULL == pRoot)
return 0;
if (NULL == pRoot->_left && NULL == pRoot->_right)
++(*count);
else
{
BinaryTreeLeafSize(pRoot->_left, &(*count));
BinaryTreeLeafSize(pRoot->_right, &(*count));
}
return *count;
}
//交换函数
void Swap(BTNode **left, BTNode **right)
{
BTNode *tmp = NULL;
tmp = *left;
*left = *right;
*right = tmp;
}
//二叉树的镜像(前序递归)
void BinaryTreeMirrorRV(BTNode *pRoot)
{
if (NULL == pRoot)
return;
//先遍历根节点
printf("%c ", pRoot->_data);
//交换左右子树
Swap(&(pRoot->_left), &(pRoot->_right));
BinaryTreeMirrorRV(pRoot->_left);
BinaryTreeMirrorRV(pRoot->_right);
}
//二叉树的镜像(层序非递归) 在层序遍历的时候交换左右节点
void BinaryTreeMirror(BTNode *pRoot)
{
if (NULL == pRoot)
return;
Queue q;
QueueInit(&q);
//根入队
QueuePush(&q, pRoot);
while (EmptyQueue(&q))
{
//取队头元素
BTNode *cur = QueueFront(&q);
//遍历根节点
printf("%c ", cur->_data);
QueuePop(&q);
if (cur->_left)
QueuePush(&q, cur->_left);
if (cur->_right)
QueuePush(&q, cur->_right);
//交换左右节点(无论是否存在)
Swap(&(cur->_left), &(cur->_right));
}
}
//求第k层的节点个数
size_t BinaryTreeKNode(BTNode *pRoot, int k)
{
if (NULL == pRoot || k <= 0)
return 0;
if (1 == k)
return 1;
else
return BinaryTreeKNode(pRoot->_left, k - 1)
+ BinaryTreeKNode(pRoot->_right, k - 1);
}
//求二叉树的高度
size_t BinaryTreeHeight(BTNode *pRoot)
{
if (NULL == pRoot)
return 0;
//优化,可以少递归将近一半
if (NULL == pRoot->_left && NULL == pRoot->_right)
return 1;
return BinaryTreeHeight(pRoot->_left) > BinaryTreeHeight(pRoot->_right) ?
BinaryTreeHeight(pRoot->_left) + 1 : BinaryTreeHeight(pRoot->_right) + 1;
}
//判断是否是完全二叉树
int IsCompleteBinaryTree(BTNode *pRoot)
{
if (NULL == pRoot)
return 0;
Queue q;
QueueInit(&q);
BTNode *cur = NULL;
int flag = 0;
//根节点入队
QueuePush(&q, pRoot);
while (EmptyQueue(&q))
{
//取队头并出队
cur = QueueFront(&q);
QueuePop(&q);
//临界点后面的节点一定没有孩子
if (flag)
{
if (cur->_left || cur->_right)
return 0;
}
else
{
if (cur->_left && cur->_right)
{
QueuePush(&q, cur->_left);
QueuePush(&q, cur->_right);
}
else if (cur->_right)
return 0; //不是完全二叉树
else if (cur->_left)
{
flag = 1;
QueuePush(&q, cur->_left);
}
else
flag = 1;
}
}
return 1;
}
//找当前树中是否有data
BTNode* FindDataBinaryTree(BTNode *pRoot, BTDataType data)
{
if (NULL == pRoot)
return NULL;
if (data == pRoot->_data)
return pRoot;
FindDataBinaryTree(pRoot->_left, data);
FindDataBinaryTree(pRoot->_right, data);
}
//找当前树中是否有这个节点
int FindNodeBinaryTree(BTNode *pRoot, BTNode *node)
{
if (NULL == pRoot)
return 0;
if (node == pRoot)
return 1;
FindNodeBinaryTree(pRoot->_left, node);
FindNodeBinaryTree(pRoot->_right, node);
}
//非递归的前序遍历(方法一) 和层次遍历的步骤一样
void BinaryTreePrevOrder1(BTNode *pRoot)
{
if (NULL == pRoot)
return;
Stack s;
StackInit(&s);
//根入栈
StackPush(&s, pRoot);
while (EmptyStack(&s))
{
//遍历
BTNode *cur = StackTop(&s);
printf("%c ", cur->_data);
//出栈
StackPop(&s);
//先让右孩子入栈
if (cur->_right)
StackPush(&s, cur->_right);
//再让左孩子入栈
if (cur->_left)
StackPush(&s, cur->_left);
}
}
//非递归前序遍历(方法二)
void BinaryTreePrevOrder2(BTNode *pRoot)
{
if (NULL == pRoot)
return;
Stack s;
StackInit(&s);
//把根节点入栈
StackPush(&s, pRoot);
while (EmptyStack(&s))
{
//取栈顶元素并出栈
BTNode *cur = StackTop(&s);
StackPop(&s);
while (cur)
{
//遍历栈顶节点
printf("%c ", cur->_data);
//如果该节点有右孩子就入栈
if (cur->_right)
StackPush(&s, cur->_right);
//然后往左边走
cur = cur->_left;
}
}
}
//非递归的中序遍历
void BinaryTreeInOrder(BTNode *pRoot)
{
if (NULL == pRoot)
return;
Stack s;
StackInit(&s);
BTNode *cur = pRoot;
//先找这棵树的最左边的节点,并保存这条路径上的所有节点
while (cur || EmptyStack(&s))
{
while (cur)
{
StackPush(&s, cur);
cur = cur->_left;
}
//去栈顶节点并遍历
cur = StackTop(&s);
printf("%c ", cur->_data);
//出栈
StackPop(&s);
//再遍历右子树
cur = cur->_right;
}
}
//后序非递归遍历
void BinaryTreePostOrder(BTNode *pRoot)
{
if (NULL == pRoot)
return;
Stack s;
StackInit(&s);
BTNode *cur = pRoot;
BTNode *top = NULL;
//用来标记前一个被遍历的节点
BTNode *sign = NULL;
//找最左节点并保存路径中的所有节点
while (cur || EmptyStack(&s))
{
while (cur)
{
StackPush(&s, cur);
cur = cur->_left;
}
//取栈顶元素
top = StackTop(&s);
//如果该节点右子树为空或者右子树已经遍历过了则遍历这个节点,遍历完出栈
if (NULL == top->_right || top->_right == sign)
{
printf("%c ", top->_data);
//该节点已遍历则标记
sign = top;
StackPop(&s);
}
else
cur = top->_right;
}
}
test.c
#include"BinaryTree.h"
#include"Queue.h"
test1()
{
BTNode *root;
//BTNode *newTree;
//BTDataType arr[] = "ABD##G##CE##F";
BTDataType arr[] = "ABD###CE##F";
size_t pIndex = 0;
size_t len = strlen(arr);
CreateBTree(&root, arr, &pIndex, '#', len);
printf("递归前序遍历为: ");
BTreePrevOrderRV(root);
printf("\n");
printf("非递归前序遍历为: ");
BinaryTreePrevOrder1(root);
printf("\n");
printf("非递归前序遍历为: ");
BinaryTreePrevOrder2(root);
printf("\n");
printf("递归中序遍历为: ");
BTreeInOrderRV(root);
printf("\n");
printf("非递归中序遍历为: ");
BinaryTreeInOrder(root);
printf("\n");
printf("递归后序遍历为: ");
BTreePostOrderRV(root);
printf("\n");
printf("非递归后序遍历为: ");
BinaryTreePostOrder(root);
printf("\n");
//newTree = CopyBinrayTree(root);
//printf("前序遍历为: ");
//BTreePrevOrderRV(newTree);
//printf("\n");
//printf("层序遍历为: ");
//BTreeLevelOrder(root);
//printf("\n");
//printf("该树的节点个数为:%u\n", BinaryTreeSize(root));
//size_t count = 0;
//printf("该树的叶子个数为:%u\n", BinaryTreeLeafSize(root, &count));
二叉树的镜像
//printf("该二叉树的镜像二叉树为(前序递归):");
//BinaryTreeMirrorRV(root);
//printf("\n");
//printf("该二叉树的镜像二叉树为(层序非递归):");
//BinaryTreeMirror(root);
//printf("\n");
//printf("第K层的节点个数为:%u\n", BinaryTreeKNode(root, 3))
//printf("该二叉树的高度为:%u\n", BinaryTreeHeight(root));
//BinaryTreeDestory(&root);
//printf("该树的节点个数为:%u\n", BinaryTreeSize(root));
//printf("该树中是否有data: %p0x\n", FindDataBinaryTree(root, 'C'));
//BTNode *node = FindDataBinaryTree(root, 'a');
//printf("该树中是否有node: %d\n", FindNodeBinaryTree(root, node));
//printf("判断该树是否是完全二叉树:%d\n", IsCompleteBinaryTree(root));
}
int main()
{
test1();
system("pause");
return 0;
}