BinTree.h
#pragma once//防止头文件被重复引用
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<malloc.h>
#include "BinTree.h"
#include"stack.h"
#include"Queue.h"
//typedef int QDataType;
//extern struct BinTreeNode;
//typedef struct BinTreeNode BTNode;
#define QDataType pBTNode
typedef struct Node
{
QDataType _data;//队列的数据类型
struct Node* _pNext;//指向下一个结点
}Node,*pNode;
typedef struct Queue
{
pNode _pHead;//指向队头的指针
pNode _pTail;//指向队尾的指针
}Queue;
void QueueInit(Queue* q);//队列的初始化
pNode BuyNode(QDataType data);//创建新队列
void QueuePush(Queue* q, QDataType data);//入队列
void QueuePop(Queue* q);//出队列
QDataType QueueFront(Queue* q);//取队头元素
QDataType Queueback(Queue* q);//取队尾元素
int QueueSize(Queue* q);//获取队列中元素的个数
int QueueEmpty(Queue* q);//检测队列是否为空
//stack.h
stack.h
#pragma once
#include<stdio.h>
#include<assert.h>
#include<malloc.h>
#include<stdlib.h>
#include<string.h>
#include "BinTree.h"
#include"stack.h"
#include"Queue.h"
//typedef int DataType;//栈:后进先出
//typedef char DataType;
//extern struct BinTreeNode;
//typedef struct BinTreeNode BTNode;
//typedef pBTNode DataType;
#define DataType pBTNode
typedef struct stack
{
DataType *_array;
int _top; // 表示有效元素个数 栈顶位置
int _capacity; // 底层空间的总大小 栈底位置
}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);//输出
void stackBracket(stack* s, char *str); //括号匹配
void stackRPN(stack* s, char *str);//后缀表达式
//Queue.h
Queue.h
#pragma once//防止头文件被重复引用
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<malloc.h>
#include "BinTree.h"
#include"stack.h"
#include"Queue.h"
//typedef int QDataType;
//extern struct BinTreeNode;
//typedef struct BinTreeNode BTNode;
#define QDataType pBTNode
typedef struct Node
{
QDataType _data;//队列的数据类型
struct Node* _pNext;//指向下一个结点
}Node,*pNode;
typedef struct Queue
{
pNode _pHead;//指向队头的指针
pNode _pTail;//指向队尾的指针
}Queue;
void QueueInit(Queue* q);//队列的初始化
pNode BuyNode(QDataType data);//创建新队列
void QueuePush(Queue* q, QDataType data);//入队列
void QueuePop(Queue* q);//出队列
QDataType QueueFront(Queue* q);//取队头元素
QDataType Queueback(Queue* q);//取队尾元素
int QueueSize(Queue* q);//获取队列中元素的个数
int QueueEmpty(Queue* q);//检测队列是否为空
//BinTree.c
BinTree.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"BinTree.h"
#include "stack.h"
#include"Queue.h"
pBTNode BuyBTNode(BTDataType data)
{
pBTNode pRoot = NULL;
pRoot = (pBTNode)malloc(sizeof(BTNode));
if (NULL == pRoot)
{
return NULL;
}
pRoot->_data = data;
pRoot->_pLeft = NULL;
pRoot->_pRight = NULL;
return pRoot;
}
//二叉树的创建
void _CreatNode(pBTNode* pRoot, BTDataType array[], int size, int* index, BTDataType invaild)
{
assert(pRoot);
if (*index < size && array[*index] != invaild)
{
//根
*pRoot = BuyBTNode(array[*index]);
//左孩子
++(*index);
_CreatNode(&(*pRoot)->_pLeft, array, size, index, invaild);
//右孩子
++(*index);
_CreatNode(&(*pRoot)->_pRight, array, size, index, invaild);
}
}
void CreatNode(pBTNode* pRoot, BTDataType array[], int size, BTDataType invaild)
{
int index = 0;
_CreatNode(pRoot, array, size, &index, invaild);
}
//二叉树的拷贝
pBTNode CopyBinTree(pBTNode pRoot)
{
pBTNode pNewNode = NULL;
pNewNode = (pBTNode)malloc(sizeof(BTNode));
if (NULL == pNewNode)
{
return NULL;
}
//拷贝根
pNewNode = BuyBTNode(pRoot->_data);
//拷贝左子树
if (pRoot->_pLeft)
{
pNewNode->_pLeft = CopyBinTree(pRoot->_pLeft);
}
//拷贝右子树
if (pRoot->_pRight)
{
pNewNode->_pRight = CopyBinTree(pRoot->_pRight);
}
return pNewNode;
}
//二叉树的打印
void printBinTree(pBTNode pRoot)
{
//assert(pRoot);
if (NULL == pRoot)
{
return;
}
if (pRoot)
{
printf("%c", pRoot->_data);
printBinTree(pRoot->_pLeft);
printBinTree(pRoot->_pRight);
}
}
//二叉树的前序
void PreOrder(pBTNode pRoot)
{
if (NULL == pRoot)
{
return;
}
if (pRoot)
{
printf("%c", pRoot->_data);
PreOrder(pRoot->_pLeft);
PreOrder(pRoot->_pRight);
}
}
//二叉树的前序--非递归 根-左-右
void PreOrderNor(pBTNode pRoot)
{
//二叉树为空返回空
if (NULL == pRoot)
{
return;
}
//不为空
stack s;
stackInit(&s);
pBTNode pCur = NULL;
//先入根,再入右,后入左
stackPush(&s, pRoot);
pCur = pRoot;
while (stackEmpty(&s))
{
//取出栈顶元素
pCur = stackTop(&s);
printf("%c", pCur->_data);
stackPop(&s);
//如果有右孩子,入栈
if (pCur->_pRight)
{
stackPush(&s, pCur->_pRight);
}
//如果有左孩子,入栈
if (pCur->_pLeft)
{
stackPush(&s, pCur->_pLeft);
}
}
}
//二叉树的中序
void InOrder(pBTNode pRoot)
{
//assert(pRoot);
if (NULL == pRoot)
{
return;
}
if (pRoot)
{
InOrder(pRoot->_pLeft);
printf("%c", pRoot->_data);
InOrder(pRoot->_pRight);
}
}
//二叉树的中序--非递归 左-根-右
void InOrderNor(pBTNode pRoot)
{
if (NULL == pRoot)
{
return;
}
stack s;
stackInit(&s);
pBTNode pCur = pRoot;
//找当前树的最左边的结点,并保存所经过的路径中所有结点
while (pCur || stackEmpty(&s))
{
while (pCur)
{
stackPush(&s, pCur);
pCur = pCur->_pLeft;
}
//取栈顶元素
pCur = stackTop(&s);//读取目前最左边的结点
printf("%c", pCur->_data);
//出栈
stackPop(&s);
//取右元素
pCur = pCur->_pRight;
}
}
//二叉树的后序
void PostOrder(pBTNode pRoot)
{
//assert(pRoot);
if (NULL == pRoot)
{
return;
}
if (pRoot)
{
PostOrder(pRoot->_pLeft);
PostOrder(pRoot->_pRight);
printf("%c", pRoot->_data);
}
}
//二叉树的后序--非递归
void PostOrderNor(pBTNode pRoot)
{
if (NULL == pRoot)
{
return;
}
stack s;
stackInit(&s);
pBTNode pCur = pRoot;
pBTNode pTop = NULL;
pBTNode pPer = NULL;
while (pCur || stackEmpty(&s))
{
while (pCur)//将左边的结点全部入栈
{
stackPush(&s, pCur);
pCur = pCur->_pLeft;
}
pTop = stackTop(&s);
if (NULL == pTop->_pRight || pPer == pTop->_pRight)//判断是否有右子树,或者右子树已经访问过
{
pPer = pTop;//记录当前结点,作为已访问的右子树
printf("%c", pTop->_data);//输出当前结点
stackPop(&s);
}
else//如果右子树存在且没有访问过
{
pCur = pTop->_pRight;
}
}
}
//二叉树的销毁
void DestoyBinTree(pBTNode* pRoot)
{
assert(pRoot);
if (*pRoot)
{
//销毁左子树
DestoyBinTree(&(*pRoot)->_pLeft);
//销毁右子树
DestoyBinTree(&(*pRoot)->_pRight);
//销毁根
free(*pRoot);
*pRoot = NULL;
}
}
//层序遍历
void LevelOrder(pBTNode pRoot)
{
//Queue q;
//QueueInit(&q);
//pBTNode pCur = pRoot;
//QueuePush(&q, pRoot);
//while (pCur || QueueEmpty(&q))
//{
// pCur = QueueFront(&q);
// //pCur = q._pHead->_data;
// QueuePop(&q);
// if (pCur)
// {
// printf("%c", pCur->_data);
// QueuePush(&q, pCur->_pLeft);
// QueuePush(&q, pCur->_pRight);
// }
//}
Queue q;
QueueInit(&q);
if (pRoot)
{
QueuePush(&q, pRoot);
while (pRoot && QueueEmpty(&q))
{
pRoot = QueueFront(&q);
QueuePop(&q);
printf("%c", pRoot->_data);
if (pRoot->_pLeft)
QueuePush(&q, pRoot->_pLeft);
if (pRoot->_pRight)
QueuePush(&q, pRoot->_pRight);
}
}
}
//二叉树的镜像--递归
void MirrorBinTree(pBTNode pRoot)
{
pBTNode pLeft = NULL;
pBTNode pRight = NULL;
if (pRoot)
{
pLeft = pRoot->_pLeft;
pRight = pRoot->_pRight;
MirrorBinTree(pLeft);
MirrorBinTree(pRight);
pRoot->_pLeft = pRight;
pRoot->_pRight = pLeft;
}
}
//二叉树的镜像--非递归
void swap(pBTNode* pRoot)
{
assert(*pRoot);
pBTNode tmp = (*pRoot)->_pLeft;
(*pRoot)->_pLeft = (*pRoot)->_pRight;
(*pRoot)->_pRight = tmp;
}
void MirrorBinTreeNor(pBTNode pRoot)
{
pBTNode pCur = NULL;
Queue q;
QueueInit(&q);
QueuePush(&q, pRoot);
while (!QueueEmpty(&q))
{
pCur = QueueFront(&q);
QueuePop(&q);
swap(&pCur);
if (pCur->_pLeft)
QueuePush(&q, pCur->_pLeft);
if (pCur->_pRight)
QueuePush(&q, pCur->_pRight);
}
}
// 求二叉树中结点的个数
int BinTreeSize(pBTNode pRoot)
{
if (NULL == pRoot)
{
return 0;
}
return 1 + BinTreeSize(pRoot->_pLeft) + BinTreeSize(pRoot->_pRight);
}
// 求二叉树中叶子结点的个数
int BinTreeLeaf(pBTNode pRoot)
{
if (NULL == pRoot)
{
return 0;
}
if (NULL == pRoot->_pLeft && NULL == pRoot->_pRight)
{
return 1;
}
return BinTreeLeaf(pRoot->_pLeft) + BinTreeLeaf(pRoot->_pRight);
}
// 求二叉树中第K层结点的个数
int BinTreeKLevelNode(pBTNode pRoot, int k)
{
if (NULL == pRoot || k<=0)
{
return 0;
}
if (1 == k)
{
return 1;
}
return BinTreeKLevelNode(pRoot->_pLeft,k-1) + BinTreeKLevelNode(pRoot->_pRight,k-1);
}
// 求二叉树的高度(高度就是层数)
int BinTreeHeight(pBTNode pRoot)
{
//空树
if (NULL == pRoot)
{
return 0;
}
if (NULL == pRoot->_pLeft && NULL == pRoot->_pRight)
{
return 1;
}
//存在(如果左高>右高,返回左+1(1为根),否则返回右+1)
return BinTreeHeight(pRoot->_pLeft) > BinTreeHeight(pRoot->_pRight) ? BinTreeHeight(pRoot->_pLeft) + 1 : BinTreeHeight(pRoot->_pRight) + 1;
}
// 在二叉树中查找值为data的结点,找到返回该结点,否则返回空
pBTNode Find(pBTNode pRoot, BTDataType data)
{
pBTNode pCur = NULL;
if (NULL == pRoot)
{
return NULL;
}
if (data == pRoot->_data)
{
return pRoot;
}
//先找左子树
if ((pCur = Find(pRoot->_pLeft, data)))
{
return pCur;
}
else
{
return Find(pRoot->_pRight, data);
}
}
// 检测一个节点是否在二叉树中
int IsNodeInBinTree(pBTNode pRoot, pBTNode pNode)
{
if (NULL == pRoot || NULL == pNode)
{
return 0;
}
if (pRoot == pNode)
{
return 1;
}
if (IsNodeInBinTree(pRoot->_pLeft, pNode))
{
return 1;
}
return IsNodeInBinTree(pRoot->_pRight, pNode);
}
// 检测一棵树是否为完全二叉树
int IsCompleteBinTree(pBTNode pRoot)
{
Queue q;
QueueInit(&q);
QueuePush(&q, pRoot);
int flag = 1;
pBTNode pCur = NULL;
while (!QueueEmpty(&q))
{
pCur = QueueFront(&q);
QueuePop(&q);
if (flag)
{
if (pCur->_pLeft && pCur->_pRight)
{
QueuePush(&q, pCur->_pLeft);
QueuePush(&q, pCur->_pRight);
}
else if (pCur->_pLeft && NULL== pCur->_pRight)
{
flag = 0;
QueuePush(&q, pCur->_pLeft);
}
else if (NULL == pCur->_pLeft && pCur->_pRight)
{
return 0;
}
}
else
{
if (pCur->_pLeft || pCur->_pRight)
{
return 0;
}
}
}
return 1;
}
//stack.c
stack.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"stack.h"
#include "BinTree.h"
//#include"Queue.h"
void stackInit(stack* s)//初始化
{
if (NULL == s)
{
return;
}
s->_capacity =3;
s->_array = (DataType*)malloc(sizeof(DataType)*(s->_capacity));
//malloc函数原型 void *malloc(size_t size);
//malloc()在内存的动态存储区中分配一块长度为size字节的连续区域,参数size为需要的内存空间的长度,返回该区域的地址。
//sizeof(DataType)*(s->_capacity)为需要的内存空间的长度,
//_capacity; 底层空间的总大小 栈底位置
s->_top =0;
}
void stackPush(stack* s, DataType data)//入栈
{
if (NULL == s)
{
return ;
}
if (s->_top == s->_capacity)//栈中只有一个元素
{
//开辟空间
s->_capacity = (s->_capacity)*2;//_capacity; 底层空间的总大小 栈底位置
DataType* pCur = (DataType*)realloc(s->_array, sizeof(DataType)*(s->_capacity));
s->_array = pCur;
//realloc函数原型void *realloc(void *ptr, size_t size);
//realloc()是给一个已经分配了地址的指针重新分配空间,参数ptr为原有的空间地址,newsize是重新申请的地址空间。
//realloc可以对给定的指针所指向的空间进行扩大或缩小,原有的内存中的内容将保持不变。
//realloc并不保持调整后的内存空间和原来的内存空间保持同一内存地址,返回的指针很可能指向新的地址。
//realloc是从堆空间上分配内存,当扩大一块内存空间时,realloc试图直接从现存的数据后面的哪些字节中获得附加的字节,
//如果能够满足需求,自然天下太平,如果后面的字节不够,那么就使用堆上第一个足够满足要求的自由空间块,
//现存的数据然后就被拷贝到新的位置上,而老块则放回堆空间,这句话传递的一个很重要的信息就是数据可能被移动。
}
s->_array[s->_top++] = data;
}
void stackPop(stack* s)//出栈
{
if (NULL == s)
{
return ;
}
s->_top--;
}
DataType stackTop(stack* s) 获取栈顶元素
{
if (NULL == s)
{
return 0;
}
return s->_array[s->_top-1];
}
int stackSize(stack* s)//有效元素的个数
{
if (NULL == s)
{
return 0;
}
return s->_top;
}
int stackEmpty(stack* s)// 检测栈是否为空
{
if (NULL == s)
{
return 0;
}
if (s->_top == 0)
{
return 0;
}
else
{
return 1;
}
}
void stackPrint(stack *s)
{
assert(s);
while (stackEmpty(s))
{
printf("%d ", stackTop(s));
stackPop(s);
}
}
//Queue.c
Queue.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"Queue.h"
#include "BinTree.h"
//#include "stack.h"
//队列的初始化
void QueueInit(Queue* q)
{
assert(q);
q->_pHead = NULL;
q->_pTail = NULL;
}
//创建新队列
pNode BuyNode(QDataType data)
{
pNode pNewNode = malloc(sizeof(Node));
if (NULL == pNewNode)
{
printf("开辟内存失败\n");
assert(0);
}
pNewNode->_data = data;
pNewNode->_pNext = NULL;
return pNewNode;
}
//入队列(相当于尾插)
void QueuePush(Queue* q, QDataType data)
{
pNode pNewNode = NULL;
pNewNode = BuyNode(data);
if (NULL == q->_pHead)//若链队为空,则新结点是队头又是队尾
{
q->_pHead = q->_pTail = pNewNode;
q->_pTail = pNewNode;
}
//非空
else
{
q->_pTail->_pNext=pNewNode;
q->_pTail = pNewNode;
}
}
//检测队列是否为空
int QueueEmpty(Queue* q)
{
if (NULL == q)
{
return 0;
}
return 1;
}
//出队列
void QueuePop(Queue* q)
{
assert(q);
if (NULL == q)
{
return;
}
//一个元素
if (q->_pHead==q->_pTail)
{
free(q->_pHead);
q->_pHead = q->_pTail= NULL;
return;
}
//多个元素
else
{
q->_pHead = q->_pHead->_pNext;
}
free(q->_pTail);
q->_pTail = q->_pHead;
q->_pHead->_pNext = NULL;
}
//取队头元素
QDataType QueueFront(Queue* q)
{
assert(q);
if (!QueueEmpty(q))
{
printf("队列为空\n");
exit(1);
}
return q->_pHead->_data;
}
//取队尾元素
QDataType Queueback(Queue* q)
{
assert(q);
if (!QueueEmpty(q))
{
printf("队列为空\n");
exit(1);
}
return q->_pTail->_data;
}
//获取队列中元素的个数
int QueueSize(Queue* q)
{
assert(q);
int count = 0;
while (q->_pHead)
{
count++;
q->_pHead = q->_pHead->_pNext;
}
return count;
}
//testbintree.c
testbintree.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"BinTree.h"
#include"stack.h"
#include"Queue.h"
void testBinTree()
{
BTDataType* str = "ABD###CE##F";
pBTNode pRoot=NULL;
pBTNode pCur = NULL;
CreatNode(&pRoot, str, strlen(str), '#');
pCur = CopyBinTree(pRoot);
printf("原序列:");
printBinTree(pRoot);
printf("\n");
//printf("层序遍历:");
//LevelOrder(pRoot);
//printf("\n");
//printf("拷贝:");
//printBinTree(pCur);
//printf("\n");
//printf("前序:");
//PreOrder(pRoot);
//printf("\n");
//printf("前序非递归:");
//PreOrderNor(pRoot);
//printf("\n");
//printf("中序:");
//InOrder(pRoot);
//printf("\n");
//printf("中序非递归:");
//InOrderNor(pRoot);
//printf("\n");
//printf("后序:");
//PostOrder(pRoot);
//printf("\n");
//printf("后序非递归:");
//PostOrderNor(pRoot);
//printf("\n");
//printf("销毁:");
//DestoyBinTree(&pRoot);
//printf("\n");
/*printf("镜像递归:");
MirrorBinTree(pRoot);
PreOrder(pRoot);
printf("\n");
printf("镜像非递归:");
MirrorBinTreeNor(pRoot);
PreOrder(pRoot);
printf("\n");*/
//printf("结点个数:%d\n", BinTreeSize(pRoot));
//printf("叶子结点个数:%d\n", BinTreeLeaf(pRoot));
//printf("k层结点个数:%d\n", BinTreeKLevelNode(pRoot,2));
//printf("二叉树的高度:%d\n", BinTreeHeight(pRoot));
/*pCur = Find(pRoot, 'E');
printf("查找结果:%c\n",pCur);*/
//if (IsNodeInBinTree(pRoot, Find(pRoot, 'E')))
//{
// printf("存在\n");
//}
printf("是否为完全二叉树 :%d\n", IsCompleteBinTree(pRoot));
}
int main()
{
testBinTree();
system("pause");
return 0;
}