BinTree.h
#pragma once
#include <stdio.h>
#include <assert.h>
#include <malloc.h>
#include "Stack.h"
#include "SQueue.h"
typedef char BTDataType;
typedef struct BinTreeNode
{
struct BinTreeNode* _pLeft;
struct BinTreeNode* _pRight;
BTDataType _data;
}BTNode,*PBTNode;
//构建二叉树的结点
PBTNode BuyBinTreeNode(BTDataType data);
//创建二叉树
void _CreateBinTree(PBTNode* pRoot,const BTDataType* array,
int size,int* index,BTDataType invalid);
void CreateBinTree(PBTNode* pRoot,const BTDataType* array,
int size,BTDataType invalid);
// 拷贝二叉树
PBTNode CopyBinTree(PBTNode pRoot);
// 销毁二叉树
void DestroyBinTree(PBTNode *pRoot);
// 前序遍历递归
void PreOrder(PBTNode pRoot);
// 前序遍历非递归
void PreOrderNor(PBTNode pRoot);
// 中序遍历递归
void InOrder(PBTNode pRoot);
//中序遍历非递归
void InOrderNor(PBTNode pRoot);
// 后序遍历递归
void PostOrder(PBTNode pRoot);
//后序遍历非递归
void PostOrderNor(PBTNode pRoot);
// 层序遍历
void LevelOrder(PBTNode pRoot);
// 二叉树的镜像递归
void MirrorBinTree(PBTNode pRoot);
// 二叉树的镜像非递归
void MirrorBinTreeNor(PBTNode pRoot);
// 求二叉树中结点的个数
int BinTreeSize(PBTNode pRoot);
// 获取二叉树中叶子结点的个数
int GetLeafCount(PBTNode pRoot);
// 求二叉树中K层结点的个数
int GetKLevelNode(PBTNode pRoot, int K);
// 求二叉树的高度
int Height(PBTNode pRoot);
//判断一个结点是否在一颗二叉树中
int IsNodeInBinTree(PBTNode pRoot,PBTNode pNode);
//判断一棵二叉树是否是完全二叉树
int IsCompeleteBinTree(PBTNode pRoot);
BInTree.c
#define _CRT_SECURE_NO_WARNING 1
#include "BinTree.h"
//构建二叉树的结点
PBTNode BuyBinTreeNode(BTDataType data)
{
PBTNode pNewNode = NULL;
pNewNode = (PBTNode)malloc(sizeof(BTNode));
if(NULL == pNewNode)
{
printf("申请失败!!!\n");
return NULL;
}
pNewNode->_data = data;
pNewNode->_pLeft = NULL;
pNewNode->_pRight = NULL;
return pNewNode;
}
//创建二叉树数据节点(按前序遍历的方式创建)
void _CreateBinTree(PBTNode* pRoot,const BTDataType* array,
int size,int* index,BTDataType invalid)
//(*index)是访问数组array的下标
{
assert(index);
assert(pRoot);
if(NULL == pRoot || array[*index] == invalid)
return;
else if((*index) < size && invalid != array[*index])
{
//创建根节点
*pRoot = BuyBinTreeNode(array[*index]);
//创建根节点的左子树
++(*index);
_CreateBinTree(&(*pRoot)->_pLeft,array,size,index,invalid);
//创建根节点的右子树
++(*index);
_CreateBinTree(&(*pRoot)->_pRight,array,size,index,invalid);
}
}
//创建二叉树结构
void CreateBinTree(PBTNode* pRoot,const BTDataType* array,
int size,BTDataType invalid)
{
int index = 0;
_CreateBinTree(pRoot,array,size,&index,invalid);
}
// 拷贝二叉树
PBTNode CopyBinTree(PBTNode pRoot)
{
PBTNode pNewNode = NULL;
if(NULL == pRoot)
return NULL;
else
{
//1.先拷贝根节点
pNewNode = BuyBinTreeNode(pRoot->_data);
//2.拷贝左子树
pNewNode->_pLeft = CopyBinTree(pRoot->_pLeft);
//3.拷贝右子树
pNewNode->_pRight = CopyBinTree(pRoot->_pRight);
}
return pNewNode;
}
// 销毁二叉树
void DestroyBinTree(PBTNode *pRoot)
{
assert(pRoot);
if(NULL == *pRoot)
return;
else
{
//左子树存在,销毁左子树
if((*pRoot)->_pLeft)
DestroyBinTree(&(*pRoot)->_pLeft);
//右子树存在,销毁右子树
if((*pRoot)->_pRight)
DestroyBinTree(&(*pRoot)->_pRight);
//最后才能销毁根节点
free(*pRoot);
*pRoot = NULL;
}
}
// 前序遍历递归
void PreOrder(PBTNode pRoot)
{
if(pRoot)
{
printf("%c ",pRoot->_data);
PreOrder(pRoot->_pLeft);
PreOrder(pRoot->_pRight);
}
}
// 前序遍历非递归
void PreOrderNor(PBTNode pRoot)
{
Stack s;
PBTNode pCur = NULL;
StackInit(&s);
StackPush(&s,pRoot);
if(NULL == pRoot)
return;
while(!StackEmpty(&s))
{
pCur = StackTop(&s);//用pCur来标记栈顶元素
printf("%c",pCur->_data);
StackPop(&s);
if(pCur->_pLeft)
StackPush(&s,pCur->_pLeft);
else if(pCur->_pRight)
StackPush(&s,pCur->_pRight);
}
}
// 中序遍历递归
void InOrder(PBTNode pRoot)
{
if(pRoot)
{
InOrder(pRoot->_pLeft);
printf("%c ",pRoot->_data);
InOrder(pRoot->_pRight);
}
}
//中序遍历非递归
void InOrderNor(PBTNode pRoot)
{
Stack s;
PBTNode pCur = NULL;
StackInit(&s);
if(NULL == pRoot)
return;
pCur = pRoot;
while(!StackEmpty(&s) || pCur)
{
while(pCur)
{
StackPush(&s,pCur);
pCur = pCur->_pLeft;
}
pCur = StackTop(&s);
printf("%c",pCur->_data);
StackPop(&s);
pCur = pCur->_pRight;
}
}
// 后序遍历递归
void PostOrder(PBTNode pRoot)
{
if(pRoot)
{
PostOrder(pRoot->_pLeft);
PostOrder(pRoot->_pRight);
printf("%c ",pRoot->_data);
}
}
//后序遍历非递归
void PostOrderNor(PBTNode pRoot)
{
PBTNode pCur = pRoot;
PBTNode pPre = NULL;//标记最近访问过的节点
PBTNode pTop = NULL;//标记栈顶元素
Stack s;
if(NULL == pRoot)
return;
StackInit(&s);
while(pCur || !StackEmpty(&s))
{
while(pCur)
{
StackPush(&s,pCur);
pCur = pCur->_pLeft;
}
pTop = StackTop(&s);
if(NULL == pTop->_pRight || pPre == pTop->_pRight)
{
printf("%c",pTop->_data);
pPre = pTop;
StackPop(&s);
}
else
pCur = pTop->_pRight;
}
}
// 层序遍历
void LevelOrder(PBTNode pRoot)
{
PBTNode pCur = NULL;
SQueue q;
if(pRoot == NULL)
return;
//1.初始化一个队列,让根节点进队列
SQueueInit(&q);
//2.根节点指针入队列
SQueuePush(&q,pRoot);
//3.队列非空,循环执行
while(!SQueueEmpty(&q))
{
//a.取队头元素并访问
pCur = SQueueFrontData(&q);
printf("%c ",pCur->_data);
//b.左子树非空,将左子树入队列
if(pCur->_pLeft)
SQueuePush(&q,pCur->_pLeft);
//c.右子树非空,将右子树入队列
if(pCur->_pRight)
SQueuePush(&q,pCur->_pRight);
SQueuePop(&q);
}
}
// 二叉树的镜像递归
void MirrorBinTree(PBTNode pRoot)
{
if(NULL == pRoot)
return;
else
{
PBTNode tmp = pRoot->_pLeft;
pRoot->_pLeft = pRoot->_pRight;
pRoot->_pRight = tmp;
MirrorBinTree(pRoot->_pLeft);
MirrorBinTree(pRoot->_pRight);
}
}
void Swap(PBTNode *Left,PBTNode *Right)
{
PBTNode tmp = NULL;
assert(Left);
assert(Right);
tmp = *Left;
*Left = *Right;
*Right = tmp;
}
// 二叉树的镜像非递归
void MirrorBinTreeNor(PBTNode pRoot)
{
SQueue q;
if(NULL == pRoot)
return;
SQueueInit (&q);
SQueuePush(&q,pRoot);
while(!SQueueEmpty(&q))
{
PBTNode pCur = SQueueFrontData(&q);
Swap(&pRoot->_pLeft,&pRoot->_pRight);
if(pCur->_pLeft)
SQueuePush(&q,pCur->_pLeft);
if(pCur->_pRight)
SQueuePush(&q,pCur->_pRight);
SQueuePop(&q);
}
SQueueDestory(&q);
}
// 求二叉树中结点的个数
int BinTreeSize(PBTNode pRoot)
{
if(pRoot == NULL)
return 0;
return BinTreeSize(pRoot->_pLeft) + BinTreeSize(pRoot->_pRight) + 1;
}
// 获取二叉树中叶子结点的个数
int GetLeafCount(PBTNode pRoot)
{
if(NULL == pRoot)
return 0;
if( (NULL == (pRoot->_pLeft)) && (NULL == (pRoot->_pRight)) )
return 1;
return GetLeafCount(pRoot->_pLeft) + GetLeafCount(pRoot->_pRight);
}
// 求二叉树中K层结点的个数
int GetKLevelNode(PBTNode pRoot, int K)
{
if(NULL == pRoot)
return 0;
if(1 == K)
return 1;
return GetKLevelNode(pRoot->_pLeft,K-1) + GetKLevelNode(pRoot->_pRight,K-1);
}
// 求二叉树的高度
int Height(PBTNode pRoot)
{
if(NULL == pRoot)
return 0;
return Height(pRoot->_pLeft)>Height(pRoot->_pRight) ? (1+Height(pRoot->_pLeft)):(1+Height(pRoot->_pRight));
}
//判断一个结点是否在一颗二叉树中
int IsNodeInBinTree(PBTNode pRoot,PBTNode pNode)
{
int ret = 0;
if(NULL == pRoot || NULL == pNode)
return 0;
if(pRoot == pNode)
return 1;
if(ret = IsNodeInBinTree(pRoot->_pLeft,pNode))
return ret;
return IsNodeInBinTree(pRoot->_pRight,pNode);
}
//判断一棵二叉树是否是完全二叉树(层序遍历)
int IsCompeleteBinTree(PBTNode pRoot)
{
SQueue q;
int flag = 0;//标记仅有左孩子的结点
if(NULL == pRoot)
return 1;//空树也是一颗完全二叉树
SQueueInit(&q);
SQueuePush(&q,pRoot);
while(!SQueueEmpty(&q))
{
PBTNode pCur = SQueueFrontData(&q);
if(flag)//找到了左孩子的结点
{
if(pCur->_pLeft || pCur->_pRight)
return 0;//返回假
}
else
{
if(NULL == pCur->_pLeft && NULL != pCur->_pRight)//左孩子没有而右孩子存在,一定不为完全二叉树
return 0;//返回假
else if(NULL != pCur->_pLeft && NULL == pCur->_pRight)//只有左孩子
{
SQueuePush(&q,pCur->_pLeft);
flag = 1;//标记仅有左孩子的结点
}
else if(pCur->_pLeft && pCur->_pRight)
{
SQueuePush(&q,pCur->_pLeft);
SQueuePush(&q,pCur->_pRight);
}
else
flag = 1;
}
SQueuePop(&q);
}
return 1;
}
test.c
#define _CRT_SECURE_NO_WARNING 1
#include "BinTree.h"
int main()
{
PBTNode pRoot = NULL;
PBTNode pNewTree = NULL;
const char* str = "ABD###CE##F";
CreateBinTree(&pRoot,str,strlen(str),'#');
if(IsCompeleteBinTree(pRoot))
printf("是完全二叉树!!!\n");
else
printf("是完全二叉树!!!\n");
printf("PreOrder: ");
PreOrder(pRoot);
printf("\n");
MirrorBinTree(pRoot);
MirrorBinTreeNor(pRoot);
printf("PreOrder: ");
PreOrder(pRoot);
printf("\n");
printf("PreOrder: ");
PreOrderNor(pRoot);
printf("\n");
printf("InOrder: ");
InOrder(pRoot);
printf("\n");
printf("InOrderNor: ");
InOrderNor(pRoot);
printf("\n");
printf("PostOrder: ");
PostOrder(pRoot);
printf("\n");
printf("PostOrderNor: ");
PostOrderNor(pRoot);
printf("\n");
printf("LevelOrder: ");
LevelOrder(pRoot);
printf("\n");
pNewTree = CopyBinTree(pRoot);
printf("PreOrder: ");
PreOrder(pNewTree);
printf("\n");
printf("二叉树中结点的个数为:%d\n", BinTreeSize(pRoot));
printf("二叉树中叶子结点的个数为:%d\n", GetLeafCount(pRoot));
printf("二叉树中的高度为:%d\n", Height(pRoot));
printf("二叉树中第3层结点的个数为:%d\n",GetKLevelNode(pRoot, 3));
DestroyBinTree(&pRoot);
DestroyBinTree(&pNewTree);
return 0;
}
SQueue.h
#define _CRT_SECURE_NO_WARNING 1
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <malloc.h>
//链式队列(即队列的底层实现为链表),链表头结点为队列的对头
//typedef int DataType;
extern struct BinTreeNode;
typedef struct BinTreeNode* DataType;
typedef struct ListNode
{
struct ListNode* _pNext;
DataType _data;
}Node,*PNode;
typedef struct SQueue
{
PNode _front;
PNode _rear;
}SQueue,*PSQueue;
//初始化队列
void SQueueInit(PSQueue q);
//入队列
void SQueuePush(PSQueue q,DataType data);
//出队列
void SQueuePop(PSQueue q);
//判空
int SQueueEmpty(PSQueue q);
//获得队头元素
DataType SQueueFrontData(PSQueue q);
//获得队尾元素
DataType SQueueRearData(PSQueue q);
//查看队列长度
int SQueueSize(PSQueue q);
//销毁队列
void SQueueDestory(PSQueue q);
SQueue.c
#include "SQueue.h"
//初始化队列
void SQueueInit(PSQueue q)
{
assert(q);
q->_front = NULL;
q->_rear = NULL;
}
PNode BuyNewNode(DataType data)
{
PNode pNewNode = NULL;
pNewNode = (PNode)malloc(sizeof(Node));
if(pNewNode == NULL)
{
printf("创建失败!!!\n");
return NULL;
}
pNewNode->_pNext = NULL;
pNewNode->_data = data;
return pNewNode;
}
//入队列
void SQueuePush(PSQueue q,DataType data)
{
assert(q);
if(NULL == q->_front)
q->_front = q->_rear = BuyNewNode(data);
else
{
q->_rear->_pNext = BuyNewNode(data);
q->_rear = q->_rear->_pNext;
}
}
//出队列
void SQueuePop(PSQueue q)
{
PNode pDel = NULL;
assert(q);
if(q->_front == NULL)
return;
pDel = q->_front;
q->_front = q->_front->_pNext;
free(pDel);
pDel = NULL;
}
//判空
int SQueueEmpty(PSQueue q)
{
assert(q);
if(q->_front == NULL)
return 1;
return 0;
}
//获得队头元素
DataType SQueueFrontData(PSQueue q)
{
assert(q);
if(NULL == q->_front)
return 0;
return q->_front->_data;
}
//获得队尾元素
DataType SQueueRearData(PSQueue q)
{
assert(q);
if(NULL == q->_front)
return 0;
return q->_rear->_data;
}
//查看队列长度
int SQueueSize(PSQueue q)
{
int count = 0;
PNode pCur = q->_front;
assert(q);
if(q->_front)
{
while(pCur)
{
count++;
pCur = pCur->_pNext;
}
}
return count;
}
//销毁队列
void SQueueDestory(PSQueue q)
{
PNode pCur = NULL;
PNode pDel = NULL;
assert(q);
if(q->_front)
{
pCur = q->_front;
while(pCur)
{
pDel = pCur;
pCur = pCur->_pNext;
free(pDel);
}
}
}
Stack.h
#pragma once
#include <stdio.h>
#include <assert.h>
#include <malloc.h>
#include <stdlib.h>
#include <string.h>
extern struct BinTreeNode;
typedef struct BinTreeNode* DataType;
#define MAX_SIZE 12
//typedef int DataType;
typedef struct Stack
{
DataType _array[MAX_SIZE];//
int _top;
}Stack;
//栈的初始化
void StackInit(Stack* s);
//入栈
void StackPush(Stack* s,DataType data);
//出栈
void StackPop(Stack* s);
//获取栈顶元素
DataType StackTop(Stack* s);
//获取栈中元素个数
int StackSize(Stack* s);
//检测栈是否为空
int StackEmpty(Stack* s);
//打印栈中的元素
void StackPrint(Stack* s);
Stack.c
#define _CRT_SECURE_NO_WARNING 1
#include "Stack.h"
//栈的初始化
void StackInit(Stack* s)
{
if(NULL == s)
return;
s->_top = 0;
}
//入栈
void StackPush(Stack* s,DataType data)
{
assert(s);
if(MAX_SIZE == s->_top)
return;
s->_array[s->_top] = data;
s->_top++;
}
//出栈
void StackPop(Stack* s)
{
assert(s);
if(0 == s->_top)
{
printf("栈已空!!!\n");
return;
}
s->_top--;
}
//获取栈中元素个数
int StackSize(Stack* s)
{
if(NULL == s)
{
printf("栈为空!!!\n");
return 0;
}
return s->_top;
}
//检测栈是否为空
int StackEmpty(Stack* s)
{
if(s->_top == 0)
return 1;
return 0;
}
//获取栈顶元素
DataType StackTop(Stack* s)
{
assert(s);
if(0 == s->_top)
{
printf("栈为空没有元素!!!\n");
return 0;
}
return s->_array[s->_top-1];
}
//打印栈中的元素
void StackPrint(Stack* s)
{
int i = 0;
assert(s);
for( ; i < s->_top ;i++)
{
printf("%d--->", s->_array[i]);
}
printf("NULL\n");
}