BinTree.h
#pragma once
typedef char BTDataType;
typedef struct BinTreeNode
{
struct BinTreeNode* _pLeft;
struct BinTreeNode* _pRight;
BTDataType _data;
}BTNode,*PBTNode;
#include<malloc.h>
#include<assert.h>
#include<stdio.h>
#include<string.h>
#include<LinkedStack.h>
#include<Queue.h>
PBTNode BuyBinTreeNode(BTDataType data)
{
PBTNode pNewNode = (PBTNode)malloc(sizeof(BTNode));
if(pNewNode == NULL)
{
assert(0);
return NULL;
}
pNewNode->_pLeft = NULL;
pNewNode->_pRight = NULL;
return pNewNode;
}
void _CreateBinTree(PBTNode* pRoot,const BTDataType* array, int size,int* index,BTDataType invalid)
//创建二叉树当他没有左子树或者右子树的时候用'#'代替
{
assert(pRoot);
assert(index);
if(*index < size && array[*index] != invalid)
//创建根节点
*pRoot = BuyBinTreeNode(array[*index]);
++(*index);
//创建根节点的左子树
_CreateBinTree(&(*pRoot)->_pLeft,array,size,index,invalid);
++(*index);
//创建根节点的右子树
_CreateBinTree(&(*pRoot)->_pRight,array,size,index,invalid);
}
void PreOrder(PBTNode pRoot)//前序遍历(递归)
{
if(pRoot)
{
printf("%c ",pRoot->_data);
PreOrder(pRoot->_pLeft);//递归走左子树
PreOrder(pRoot->_pRight);//递归走右子树
}
}
void PreOrderNor(BTNode* pRoot)//前序遍历(非递归)
{
LinkStack s;
if(NULL == pRoot)
return;
InitStack(&s);
PushStack(&s,pRoot);
while(!StackEmpty(&s))
{
PBTNode pCur = GetTop(&s);
printf("%c ",pCur->_data);
PopStack(&s);
if(pCur->_pRight)
PushStack(&s,pCur->_pRight);
if(pCur->_pLeft)
PushStack(&s,pCur->_pLeft);
}
}
void PostOrder(PBTNode pRoot)//后序遍历(递归)
{
if(pRoot)
{
PostOrder(pRoot->_pLeft);//递归走左子树
PostOrder(pRoot->_pRight);//递归走右子树
printf("%c ",pRoot->_data);
}
}
void PostOrderNor(BTNode* pRoot)//后序遍历(非递归)
{
BTNode* pCur = pRoot;
BTNode* pTop = NULL;
BTNode* pPrev = NULL;//标记最近访问过的结点
Stack s;
if(NULL == pRoot)
return;
InitStack(&s);
while(pCur || !StackEmpty(&s))
{
//找以pCur为根的树最左侧的结点,并保存所经过的所有结点。
while(pCur)
{
PushStack(&s,pCur);//保存到栈中
pCur = pCur->_pLeft;
}
pTop = GetTop(&s);//取栈顶元素
if(pTop->_pRight == NULL || pPrev == pTop->_pRight)//如果右子树为空
{
printf("%c",pTop->_data);
pPrev = pTop;
PopStack(&s);//让栈顶元素出栈
}
else//如果右子树存在
pCur = pTop->_pRight;
}
}
void LevelOrder(PBTNode pRoot)//层序遍历
{
Queue q;
if(NULL == pRoot)
return;
QueueInit(&q);
QueuePush(&q,pRoot);
while(!QueueEmpty(&q))
{
PBTNode pCur = QueueFront(&q);
printf("%c ",pCur->_data);
QueuePop(&q);
if(pCur->_pLeft)
QueuePush(&q,pCur->_pLeft);
if(pCur->_pRight)
QueuePush(&q,pCur->_pRight);
//QueuePop(&q);
}
}
void InOrder(PBTNode pRoot)//中序遍历(递归)
{
if(pRoot)
{
InOrder(pRoot->_pLeft);//递归走左子树
printf("%c ",pRoot->_data);
InOrder(pRoot->_pRight);//递归走右子树
}
}
void InOrderNor(BTNode* pRoot)//中序遍历(非递归)
{
BTNode* pCur = pRoot;
Stack s;
if(NULL == pRoot)
return ;
InitStack(&s);
while(pCur || !StackEmpty(&s))
{
//找以pCur为根最左侧的结点,并保存路径中所遇到的所有的结点
while(pCur)
{
PushStack(&s,pCur);
pCur = pCur->_pLeft;
}
pCur = GetTop(&s);
printf("%c",pCur->_data);
PopStack(&s);
pCur = pCur->_pRight;
}
}
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 pNewRoot = NULL;
if(pRoot)
{
//拷贝根节点
pNewRoot = BuyBinTreeNode(pRoot->_data);
//拷贝根节点的左子树
if(pNewRoot->_pLeft)
pNewRoot->_pLeft = CopyBinTree(pRoot->_pLeft);
//拷贝根节点的右子树
if(pNewRoot->_pRight)
pNewRoot->_pRight = CopyBinTree(pRoot->_pRight);
}
return pNewRoot;
}
void DestroyBinTree(PBTNode *pRoot)//销毁树 用后序遍历
{
assert(pRoot);
if(*pRoot)
{
DestroyBinTree(&(*pRoot)->_pLeft);//销毁左子树
DestroyBinTree(&(*pRoot)->_pRight);//销毁右子树
free(*pRoot);
*pRoot = NULL;
}
}
void Swap(PBTNode* pLeft,PBTNode* pRight)
{
PBTNode pTemp = NULL;
assert(pLeft);
assert(pRight);
pTemp = *pLeft;
*pLeft = *pRight;
*pRight = pTemp;
}
void MirrorBinTree(PBTNode pRoot)//二叉树的镜像递归
{
if(pRoot)
{
Swap(&pRoot->_pLeft,&pRoot->_pRight);
MirrorBinTree(pRoot->_pLeft);
MirrorBinTree(pRoot->_pRight);
}
}
void MirrorBinTreeNor(PBTNode pRoot)//二叉树的镜像非递归(层序遍历解决)
{
Queue q;
if(NULL == pRoot)
return;
QueueInit(&q);
QueuePush(&q,pRoot);
while(!QueueEmpty(&q))
{
PBTNode pCur = QueueFront(&q);
Swap(&pCur->_pLeft,&pCur->_pRight);
if(pCur->_pLeft)
QueuePush(&q,pCur->_pLeft);
if(pCur->_pRight)
QueuePush(&q,pCur->_pRight);
QueuePop(&q);
}
}
int BinTreeSize(PBTNode pRoot)// 求二叉树中结点的个数
{
if(NULL == pRoot)
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);
}
int Height(PBTNode pRoot)// 求二叉树的高度
{
int leftHeight, rightHeight;
if(NULL == pRoot)
return 0;
leftHeight = Height(pRoot->_pLeft);
rightHeight = Height(pRoot->_pRight);
return leftHeight > rightHeight? leftHeight + 1:rightHeight + 1;
}
int GetKLevelNode(PBTNode pRoot, int K)// 求二叉树中K层结点的个数
{
if(NULL == pRoot || K < 1)
return 0;
if(K == 1)
return 1;
return GetKLevelNode(pRoot->_pLeft,K-1)+GetKLevelNode(pRoot->_pRight,K-1);
}
BTNode* Find(BTNode* pRoot,BTDataType data)//在二叉树中找数据
{
BTNode* pRet = NULL;
if(NULL == pRoot)
return NULL;
if(data == pRoot->_data)
return pRoot;
if(pRet = Find(pRoot->_pLeft,data))
return pRet;
return Find(pRoot->_pRight,data);
}
int IsNodeInBinTree(BTNode* pRoot,BTNode* 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 IsCompleteBinTree(BTNode* pRoot)//判断一个二叉树是不是完全二叉树
{
//用层序遍历去找
Queue q;
int flag = 0;
if(NULL == pRoot)//空数是完全二叉树
return 1;
QueueInit(&q);//初始化队列
QueuePush(&q,pRoot)//把根节点放到队列
while(!QueueEmpty(&q))//当队列不为空时
{
//取头交给pCur
BinTreeNode* pCur = QueueFront(&q);
if(flag)
{
if(pCur->_pLeft || pCur->_pRight)
return 0;
}
else
{
if(pCur->_pLeft && pCur->pRight)//左孩子和右孩子都存在
{
QueuePush(&q,pCur->_pLeft);
QueuePush(&q,pCur->_pRight);
}
else if(pCur->_pLeft)//左孩子存在右孩子不存在
{
QueuePush(&q,pCur->_pLeft);
flag = 1;
}
else if(pCur->_pRight)//右孩子存在,左孩子不存在.肯定不是完全二叉树
{
return 0;
}
else
flag = 1;//说明是叶子节点
}
QueuePop(&q);
}
return 1;
}
void TestBinTree()
{
const char* str = "ABD###CE##F";
PBTNode pRoot = NULL;
PBTNode pNewTree = NULL;
CreateBinTree(&pRoot, str, strlen(str),'#');
if(IsCompleteBinTree(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");
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("二叉树中第三层节点的个数:%d\n",GetKLevelNode(pRoot,3));
DestroyBinTree(&pRoot);
DestroyBinTree(&pNewTree);
}
Test.c
#include"BinTree.h"
int main()
{
TestBinTree();
return 0;
}