代码实现
头文件
- BinTree.h
#pragma once
#ifndef _BINTREE_H_
#define _BINTREE_H_
typedef char BTDataType;
typedef struct BinTreeNode
{
struct BinTreeNode* _pLeft;
struct BinTreeNode* _pRight;
BTDataType _data;
}BTNode, *PBTNode;
/////////////////////////////////////////////////////
// 创建二叉树
void CreateBinTree(PBTNode* pRoot, BTDataType* array, int size, BTDataType invalid);
void _CreateBinTree(PBTNode* pRoot, BTDataType* array, int size, int* index, BTDataType invalid);
// 拷贝
PBTNode CopyBinTree(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);
// 求二叉树中结点的个数
int Size(PBTNode pRoot);
// 求二叉树中叶子结点的个数
int GetLeafCount(PBTNode pRoot);
// 获取第K层中结点个数
int GetKLevel(PBTNode pRoot, int K);
// 获取二叉树的高度
int Height(PBTNode pRoot);
// 二叉树层序遍历
void LevelOrder(PBTNode pRoot);
// 二叉树镜像递归
void Mirror(PBTNode pRoot);
// 二叉树镜像非递归
void Mirror_Nor(PBTNode pRoot);
// 判断一棵树是否是完全二叉树
int IsCompleteBinTree(PBTNode pRoot);
// 在二叉树中查找值为data的结点
PBTNode Find(PBTNode pRoot, BTDataType data);
// 判断一个节点是否在二叉树中
int IsNodeInBinTree(PBTNode pRoot, PBTNode pNode);
// 获取当前节点的左孩子
PBTNode LeftChild(PBTNode pNode);
// 获取当前节点的右孩子
PBTNode RightChild(PBTNode pNode);
//销毁二叉树
void DestroyBinTree(PBTNode* pRoot);
//新街结点
PBTNode BuyBinTreeNode(BTDataType data);
#endif // !_BINTREE_H_
- Stack.h
#pragma once
#include"BinTree.h"
#ifndef _STACK_H_
#define _STACK_H_
#define DataType PBTNode
#define MAX_SIZE 10
typedef struct Stack
{
DataType _array[MAX_SIZE];
int _size;
}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);
#endif //_STACK_H_
- Queue.h
#pragma once
#include"BinTree.h"
#ifndef _QUEUE_H_
#define _QUEUE_H_
#define DataType PBTNode
#define MAX_SIZE 10
typedef struct
{
DataType _array[MAX_SIZE];
int _size;
}Queue;
// 初始化队列
void QueueInit(Queue* s);
// 入队列
void QueuePush(Queue* s, DataType data);
// 出队列
void QueuePop(Queue* s);
// 获取队头元素
DataType QueueTop(Queue* s);
// 获取队列中元素个数
int QueueSize(Queue* s);
// 检测队列是否为空
int QueueEmpty(Queue* s);
#endif // !_QUEUE_H_
源文件
- BinTree.c
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include"BinTree.h"
#include"Stack.h"
#include"Queue.h"
// 创建二叉树
PBTNode BuyBinTreeNode(BTDataType data)
{
PBTNode pRoot = NULL;
pRoot = (PBTNode)malloc(sizeof(BTNode));
assert(pRoot);
pRoot->_data = data;
pRoot->_pLeft = NULL;
pRoot->_pRight = NULL;
return pRoot;
}
void CreateBinTree(PBTNode* pRoot, BTDataType* array, int size, BTDataType invalid)
{
int index = 0;
_CreateBinTree(pRoot, array, size, &index, invalid);
}
void _CreateBinTree(PBTNode* pRoot, BTDataType* array, int size, int* index, BTDataType invalid)
{
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);
}
}
// 拷贝
PBTNode CopyBinTree(PBTNode pRoot)
{
PBTNode pNew = NULL;
PBTNode pNew_Left = NULL;
PBTNode pNew_Right = NULL;
pNew = (PBTNode)malloc(sizeof(BTNode));
if (pNew == NULL)
{
return NULL;
}
pNew->_data = pRoot->_data;
if (pRoot->_pLeft != NULL)
{
pNew_Left = CopyBinTree(pRoot->_pLeft);
}
if (pRoot->_pRight != NULL)
{
pNew_Right = CopyBinTree(pRoot->_pRight);
}
pNew->_pLeft = pNew_Left;
pNew->_pRight = pNew_Right;
return pNew;
}
// 前序递归遍历
void PreOrder(PBTNode pRoot)
{
printf("%c ", pRoot->_data);
if (pRoot->_pLeft)
PreOrder(pRoot->_pLeft);
if (pRoot->_pRight)
PreOrder(pRoot->_pRight);
}
// 前序非递归
void PreOrderNor(PBTNode pRoot)
{
Stack stack;
StackInit(&stack);
PBTNode pCur = NULL;
StackPush(&stack, pRoot);
while (pCur || !StackEmpty(&stack))
{
pCur = StackTop(&stack);
StackPop(&stack);
if (pCur)
{
printf("%c ", pCur->_data);
StackPush(&stack, pCur->_pRight);
StackPush(&stack, pCur->_pLeft);
}
}
}
// 中序递归
void InOrder(PBTNode pRoot)
{
if (pRoot->_pLeft != NULL)
InOrder(pRoot->_pLeft);
printf("%c ", pRoot->_data);
if (pRoot->_pRight != NULL)
InOrder(pRoot->_pRight);
}
// 中序非递归
void InOrderNor(PBTNode pRoot)
{
Stack stack;
StackInit(&stack);
PBTNode pCur = pRoot;
while (pCur || !StackEmpty(&stack))
{
while (pCur)//将左边的节点全部入栈
{
StackPush(&stack, pCur);
pCur = pCur->_pLeft;
}
pCur = StackTop(&stack);//读取目前最左边的节点
StackPop(&stack);//出栈
printf("%c ", pCur->_data);//访问当前节点
pCur = pCur->_pRight;//开始读取右子树
}
}
// 后续递归
void PostOrder(PBTNode pRoot)
{
if (pRoot->_pLeft != NULL)
PostOrder(pRoot->_pLeft);
if (pRoot->_pRight != NULL)
PostOrder(pRoot->_pRight);
printf("%c ", pRoot->_data);
}
// 后序非递归
void PostOrderNor(PBTNode pRoot)
{
Stack stack;
StackInit(&stack);
PBTNode pCur = pRoot;
PBTNode pTop;
PBTNode pPer=NULL;
while (pCur || !StackEmpty(&stack))//节点全部读取完,且栈里面没有节点
{
while (pCur)//将左边的节点全部入栈
{
StackPush(&stack, pCur);
pCur = pCur->_pLeft;
}
pTop = StackTop(&stack);//
if (NULL == pTop->_pRight || pPer == pTop->_pRight)//判断是否有右子树,或者右子树已经被访问过
{
pPer = pTop;//记录当前节点,作为已访问的右子节点
printf("%c ", pTop->_data);//没有右子树,或者右子树被访问过,输出当前节点
StackPop(&stack);//出栈
}
else//如果右子树存在且没有访问
{
pCur = pTop->_pRight;//开始处理右子树
}
}
}
// 求二叉树中结点的个数
int Size(PBTNode pRoot)
{
if (pRoot == NULL)
{
return 0;
}
return 1 + Size(pRoot->_pLeft) + Size(pRoot->_pRight);
}
// 求二叉树中叶子结点的个数
int GetLeafCount(PBTNode pRoot)
{
int count = 0;
if (NULL == pRoot->_pLeft && NULL == pRoot->_pRight)
count++;
if (pRoot->_pLeft)
count += GetLeafCount(pRoot->_pLeft);
if(pRoot->_pRight)
count+= GetLeafCount(pRoot->_pRight);
return count;
}
// 获取第K层中结点个数
int GetKLevel(PBTNode pRoot, int K)
{
int count = 0;
if (pRoot == NULL || K <= 0)
return 0;
if (K == 1 )
return 1;
count += GetKLevel(pRoot->_pLeft, K - 1);
count += GetKLevel(pRoot->_pRight, K - 1);
return count;
}
// 获取二叉树的高度
int Height(PBTNode pRoot)
{
if (pRoot == NULL)
return 0;
return Height(pRoot->_pLeft) > Height(pRoot->_pRight) ? Height(pRoot->_pLeft) + 1 : Height(pRoot->_pRight) + 1;
}
// 二叉树层序遍历
void LevelOrder(PBTNode pRoot)
{
Queue q;
QueueInit(&q);
PBTNode pCur = pRoot;
QueuePush(&q, pRoot);
//while(!QueueEmpty(&q))
while (pCur || !QueueEmpty(&q))
{
pCur = QueueTop(&q);
QueuePop(&q);
if (pCur)
{
printf("%c ", pCur->_data);
//if (pCur->_pLeft)
QueuePush(&q, pCur->_pLeft);
//if (pCur->_pRight)
QueuePush(&q,pCur->_pRight);
}
}
}
// 二叉树镜像递归
void Mirror(PBTNode pRoot)
{
PBTNode pLeft = NULL;
PBTNode pRight = NULL;
if (pRoot)
{
pLeft = pRoot->_pLeft;
pRight = pRoot->_pRight;
Mirror(pLeft);
Mirror(pRight);
pRoot->_pLeft = pRight;
pRoot->_pRight = pLeft;
}
}
// 二叉树镜像非递归
void swap(PBTNode* pRoot)
{
assert(*pRoot);
PBTNode x = (*pRoot)->_pLeft;
(*pRoot)->_pLeft = (*pRoot)->_pRight;
(*pRoot)->_pRight = x;
}
void Mirror_Nor(PBTNode pRoot)
{
PBTNode pCur = NULL;
Queue q;
QueueInit(&q);
QueuePush(&q, pRoot);
while (!QueueEmpty(&q))
{
pCur = QueueTop(&q);
QueuePop(&q);
swap(&pCur);
if (pCur->_pLeft)
QueuePush(&q, pCur->_pLeft);
if (pCur->_pRight)
QueuePush(&q, pCur->_pRight);
}
}
// 判断一棵树是否是完全二叉树
int IsCompleteBinTree(PBTNode pRoot)
{
Queue q;
QueueInit(&q);
QueuePush(&q, pRoot);
int Tag = 1;
PBTNode pCur;
while (!QueueEmpty(&q))
{
pCur = QueueTop(&q);
QueuePop(&q);
if (Tag)
{
if (pCur->_pLeft && pCur->_pRight)
{
QueuePush(&q, pCur->_pLeft);
QueuePush(&q, pCur->_pRight);
}
else if (pCur->_pLeft && pCur->_pRight == NULL)
{
Tag = 0;
QueuePush(&q, pCur->_pLeft);
}
else if (NULL == pCur->_pLeft && pCur->_pRight)
{
return 0;
}
}
else
{
if (pCur->_pLeft || pCur->_pRight)
return 0;
}
}
return 1;
}
// 在二叉树中查找值为data的结点
PBTNode Find(PBTNode pRoot, BTDataType data)
{
//前序
Stack s;
StackInit(&s);
StackPush(&s,pRoot);
PBTNode pCur = NULL;
while (pCur || !StackEmpty(&s))
{
pCur = StackTop(&s);
StackPop(&s);
if (pCur)
{
if (pCur->_data == data)
{
return pCur;
}
StackPush(&s, pCur->_pRight);
StackPush(&s, pCur->_pLeft);
}
}
return NULL;
}
//判断一个节点是否在二叉树中前序非递归
int IsNodeInBinTree(PBTNode pRoot, PBTNode pNode)
{
//前序
Stack s;
StackInit(&s);
StackPush(&s, pRoot);
PBTNode pCur = NULL;
while (pCur || !StackEmpty(&s))
{
pCur = StackTop(&s);
StackPop(&s);
if (pCur)
{
if (pCur == pNode)
{
return 1;
}
StackPush(&s, pCur->_pRight);
StackPush(&s, pCur->_pLeft);
}
}
return 0;
}
// 获取当前节点的左孩子
PBTNode LeftChild(PBTNode pNode)
{
if (pNode)
return pNode->_pLeft;
}
// 获取当前节点的右孩子
PBTNode RightChild(PBTNode pNode)
{
if (pNode)
return pNode->_pRight;
}
//销毁二叉树-后续递归
void DestroyBinTree(PBTNode* pRoot)
{
if ((*pRoot)->_pLeft)
DestroyBinTree(&(*pRoot)->_pLeft);
if ((*pRoot)->_pRight)
DestroyBinTree(&(*pRoot)->_pRight);
free(*pRoot);
}
///
//test
void test()
{
char array[] = { 'A','B','D','#','#','#','C','E','#','#','F'};
//char array[] = { '1','2','4','q','#','#','#','5','#','#','3','6','#','#','7' };
PBTNode pRoot;
PBTNode pBT;
CreateBinTree(&pRoot, array, sizeof(array) / sizeof(array[0]), '#');
pBT = CopyBinTree(pRoot);//拷贝
printf("前序递归遍历:\t");
PreOrder(pRoot);
printf("\n");
printf("前序非递归遍历\t");
PreOrderNor(pRoot);
printf("\n");
printf("中序递归遍历:\t");
InOrder(pRoot);
printf("\n");
printf("中序非递归遍历\t");
InOrderNor(pRoot);
printf("\n");
printf("后续递归遍历:\t");
PostOrder(pRoot);
printf("\n");
printf("后续非递归遍历\t");
PostOrderNor(pRoot);
printf("\n");
printf("节点总数:%d\n",Size(pRoot));
// 求二叉树中叶子结点的个数
int count1 = GetLeafCount(pRoot);
printf("叶子结点个数:%d\n", count1);
// 获取第K层中结点个数
int count2 = GetKLevel(pRoot, 3);
printf("第K层中结点个数: %d\n",count2);
// 获取二叉树的高度
int H = Height(pRoot);
printf("二叉树的高度: %d\n", H);
// 二叉树层序遍历
printf("层序遍历:\t");
LevelOrder(pRoot);
printf("\n");
// 二叉树镜像递归
Mirror(pRoot);
printf("镜像递归 :\t");
LevelOrder(pRoot);
printf("\n");
// 二叉树镜像递归
Mirror_Nor(pRoot);
printf("镜像非递归 :\t");
LevelOrder(pRoot);
printf("\n");
// 判断一棵树是否是完全二叉树
printf("否是完全二叉树:%d\n", IsCompleteBinTree(pRoot));
// 在二叉树中查找值为data的结点
PBTNode F;
F = Find(pRoot, 'E');
printf("查找结果:");
if (F)
printf("%c\n", F->_data);
else
printf("无\n");
// 判断一个节点是否在二叉树中
if (IsNodeInBinTree(pRoot, Find(pRoot, 'E')))
{
printf("存在\n");
}
//销毁二叉树-后续递归
DestroyBinTree(&pRoot);
}
- Stack.c
#include <assert.h>
#include <windows.h>
#include <stdio.h>
#include "Stack.h"
// 初始化栈
void StackInit(Stack* s)
{
assert(s);
s->_size = 0;
}
// 压栈
void StackPush(Stack* s, DataType data)
{
assert(s);
if (s->_size >= 10)
{
return;
}
else
{
s->_array[s->_size] = data;
s->_size++;
}
}
// 出栈
void StackPop(Stack* s)
{
assert(s);
if (s->_size > 0)
{
s->_size--;
}
}
// 获取栈顶元素
DataType StackTop(Stack* s)
{
if (s->_size > 0)
{
return s->_array[(s->_size) - 1];
}
}
// 获取栈中元素个数
int StackSize(Stack* s)
{
return s->_size;
}
// 检测栈是否为空
int StackEmpty(Stack* s)
{
if (s->_size == 0)
{
return 1;
}
else return 0;
}
- Queue.c
#include <assert.h>
#include <stdio.h>
#include "Queue.h"
// 初始化栈队列
void QueueInit(Queue* s)
{
assert(s);
s->_size = 0;
}
// 入队列
void QueuePush(Queue* s, DataType data)
{
assert(s);
if (s->_size >= 10)
{
return;
}
else
{
s->_array[s->_size] = data;
s->_size++;
}
}
// 出队列
void QueuePop(Queue* s)
{
assert(s);
if (s->_size > 0)
{
s->_size--;
for (int i = 0; i < s->_size; i++)
{
s->_array[i] = s->_array[i + 1];
}
}
}
// 获取队头元素
DataType QueueTop(Queue* s)
{
if (s->_size > 0)
{
return s->_array[0];
}
}
// 获取队列中元素个数
int QueueSize(Queue* s)
{
return s->_size;
}
// 检测队列是否为空
int QueueEmpty(Queue* s)
{
if (s->_size == 0)
{
return 1;
}
else return 0;
}
//打印队列
void QueuePrint(Queue* q)
{
if (q->_size > 0 && q->_size < MAX_SIZE)
{
for (int i = 0; i < q->_size; i++)
{
printf("%c ", q->_array[i]);
}
printf("\n");
}
}
- test.c
#include<windows.h>
int main()
{
test();
system("pause");
return 0;
}