一、简单的创建、销毁
.h
# pragma once
# include<assert.h>
# include<malloc.h>
# include<stdio.h>
# include<stdlib.h>
# include<string.h>
typedef char DataType;
typedef struct BinTreeNode
{
struct BinTreeNode* _pLeft;
struct BinTreeNode* _pRight;
DataType _data;
}Node,*PNode;
PNode BuyBinTreeNode(DataType data);
void _CreateBinTree(PNode* pRoot, DataType array[], int size, int* index, DataType invalid);
void CreateBinTree(PNode* pRoot, DataType array[], int size, DataType invalid);
//拷贝一棵树,根加左子树加右子树
PNode CopyBinTree(PNode pRoot);
//二叉树的前需遍历:根+左子树+右子树
void PreOrder(PNode pRoot);
//中序遍历:左子树+根节点+右子树
void InOrder(PNode pRoot);
//后序遍历:左子树+右子树+根节点
void PostOrder(PNode pRoot);
void DestroyBinTree(PNode* pRoot);
.c
# include"BinaryTree.h"
# pragma once
# include<assert.h>
# include<malloc.h>
# include<stdio.h>
# include<stdlib.h>
# include<string.h>
PNode BuyBinTreeNode(DataType data)
{
PNode pNewNode = (PNode)malloc(sizeof(Node));
if (NULL == pNewNode)
{
assert(0);
return NULL;
}
pNewNode->_data = data;
pNewNode->_pLeft = NULL;
pNewNode->_pRight = NULL;
return pNewNode;
}
void _CreateBinTree(PNode* pRoot, DataType array[], int size, int* index, DataType invalid)
{
assert(pRoot);//此时pRoot代表外部实参的地址,可以改变指向
assert(index);
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(PNode* pRoot, DataType array[], int size, DataType invalid)
{
int index = 0;
_CreateBinTree(pRoot, array, size, &index, invalid);
}
//拷贝一棵树,根加左子树加右子树
PNode CopyBinTree(PNode pRoot){
PNode pNewRoot = NULL;
if (pRoot){
//拷贝根节点
pNewRoot = BuyBinTreeNode(pRoot->_data);
//拷贝根节点的左子树
if (pRoot->_pLeft)
pNewRoot->_pLeft = CopyBinTree(pRoot->_pLeft);
//拷贝根节点的右子树
if (pRoot->_pRight)
pNewRoot->_pRight = CopyBinTree(pRoot->_pRight);
}
return pNewRoot;
}
//二叉树的前需遍历:根+左子树+右子树
void PreOrder(PNode pRoot)
{
if (pRoot)
{
printf("%c ", pRoot->_data);
PreOrder(pRoot->_pLeft);
PreOrder(pRoot->_pRight);
}
}
//中序遍历:左子树+根节点+右子树
void InOrder(PNode pRoot)
{
if (pRoot)
{
InOrder(pRoot->_pLeft);
printf("%c ", pRoot->_data);
InOrder(pRoot->_pRight);
}
}
//后序遍历:左子树+右子树+根节点
void PostOrder(PNode pRoot)
{
if (pRoot)
{
PostOrder(pRoot->_pLeft);
PostOrder(pRoot->_pRight);
printf("%c ", pRoot->_data);
}
}
void DestroyBinTree(PNode* pRoot)
{
assert(pRoot);
if (*pRoot){
//销毁左子树
DestroyBinTree(&(*pRoot)->_pLeft);
//销毁右子树
DestroyBinTree(&(*pRoot)->_pRight);
//销毁根节点
free(*pRoot);
*pRoot = NULL;
}
}
void TestBinTree()
{
char* str = "ABD###CE##F";
PNode pRoot = NULL, pNewRoot;
CreateBinTree(&pRoot, str, strlen(str), '#');
pNewRoot = CopyBinTree(pRoot);
printf("前序遍历:");
PreOrder(pRoot);
printf("\n");
printf("中序遍历:");
InOrder(pRoot);
printf("\n");
printf("后序遍历:");
PostOrder(pRoot);
printf("\n");
}
//A B D # # # C E #
test.c
# include"Tree.h"
int main()
{
TestBinTree();
system("pause");
return 0;
}
结果:
二、层序遍历1、将当前节点遍历后,并且保存起来(加到队列中去)
.h
# pragma once
# include<assert.h>
# include<malloc.h>
# include<stdio.h>
# include<stdlib.h>
# include<string.h>
# include"Queue.h"
typedef char BTDataType;
typedef struct BinTreeBTNode
{
struct BinTreeBTNode* _pLeft;
struct BinTreeBTNode* _pRight;
BTDataType _data;
}BTNode,*PBTNode;
PBTNode BuyBinTreeBTNode(BTDataType data);
void _CreateBinTree(PBTNode* pRoot, BTDataType array[], int size, int* index, BTDataType invalid);
void CreateBinTree(PBTNode* pRoot, BTDataType array[], int size, BTDataType invalid);
//拷贝一棵树,根加左子树加右子树
PBTNode CopyBinTree(PBTNode pRoot);
//二叉树的前需遍历:根+左子树+右子树
void PreOrder(PBTNode pRoot);
//中序遍历:左子树+根节点+右子树
void InOrder(PBTNode pRoot);
//后序遍历:左子树+右子树+根节点
void PostOrder(PBTNode pRoot);
queue.h
# pragma once
# include<stdio.h>
# include<stdlib.h>
# include<string.h>
# include<assert.h>
//实现链式队列的以下操作:
//typedef int DataType
extern struct BTNode;//相当于把类型在文件中声明了
//声明后,编译器检测后发现有这种类型的存在。
//这种类型是存在的,没在当前文件中进行了定义,可能在其他的文件中进行了定义
//链接的时候直接到其他文件中去找,找到了即可,没找到就会报错
typedef struct BTNode* DataType;
typedef struct Node
{
DataType _data;
struct Node* _pNext;
}Node, *PNode;
typedef struct Queue
{
PNode _pHead;
PNode _pTail;
}Queue;
// 队列的初始化
void QueueInit(Queue* q);
// 入队列
void QueuePush(Queue* q, DataType data);
// 出队列
void QueuePop(Queue* q);
// 取队头元素
DataType QueueFront(Queue* q);
// 取队尾元素
DataType QueueBack(Queue* q);
// 获取队列中元素的个数
int QueueSize(Queue* q);
// 检测队列是否为空
int QueueEmpty(Queue* q);
PNode BuyNode(DataType data)
{
PNode pNewNode = (PNode)malloc(sizeof(Node));
if (NULL == pNewNode)
{
assert(0);
return NULL;
}
pNewNode->_data = data;
pNewNode->_pNext = NULL;
return pNewNode;
}
.c
# include"BinaryTree.h"
//#define NULL 0
PBTNode BuyBinTreeNode(DataType data)
{
PBTNode pNewNode = (PBTNode)malloc(sizeof(Node));
if (NULL == pNewNode)
{
assert(0);
return NULL;
}
pNewNode->_data = data;
pNewNode->_pLeft = NULL;
pNewNode->_pRight = NULL;
return pNewNode;
}
void _CreateBinTree(PBTNode* pRoot, DataType array[], int size, int* index, DataType invalid)
{
assert(pRoot);//此时pRoot代表外部实参的地址,可以改变指向
assert(index);
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, DataType array[], int size, DataType invalid)
{
int index = 0;
_CreateBinTree(pRoot, array, size, &index, invalid);
}
//拷贝一棵树,根加左子树加右子树
PBTNode CopyBinTree(PBTNode pRoot){
PBTNode pNewRoot = NULL;
if (pRoot){
//拷贝根节点
pNewRoot = BuyBinTreeNode(pRoot->_data);
//拷贝根节点的左子树
if (pRoot->_pLeft)
pNewRoot->_pLeft = CopyBinTree(pRoot->_pLeft);
//拷贝根节点的右子树
if (pRoot->_pRight)
pNewRoot->_pRight = CopyBinTree(pRoot->_pRight);
}
return pNewRoot;
}
//二叉树的前需遍历:根+左子树+右子树
void PreOrder(PBTNode pRoot)
{
if (pRoot)
{
printf("%c ", pRoot->_data);
PreOrder(pRoot->_pLeft);
PreOrder(pRoot->_pRight);
}
}
//中序遍历:左子树+根节点+右子树
void InOrder(PBTNode pRoot)
{
if (pRoot)
{
InOrder(pRoot->_pLeft);
printf("%c ", pRoot->_data);
InOrder(pRoot->_pRight);
}
}
//后序遍历:左子树+右子树+根节点
void PostOrder(PBTNode pRoot)
{
if (pRoot)
{
PostOrder(pRoot->_pLeft);
PostOrder(pRoot->_pRight);
printf("%c ", pRoot->_data);
}
}
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 DestroyBinTree(PBTNode* pRoot)
{
assert(pRoot);
if (*pRoot){
//销毁左子树
DestroyBinTree(&(*pRoot)->_pLeft);
//销毁右子树
DestroyBinTree(&(*pRoot)->_pRight);
//销毁根节点
free(*pRoot);
*pRoot = NULL;
}
}
void TestBinTree()
{
char* str = "ABD###CE##F";
PBTNode pRoot = NULL, pNewRoot;
CreateBinTree(&pRoot, str, strlen(str), '#');
pNewRoot = CopyBinTree(pRoot);
printf("前序遍历:");
PreOrder(pRoot);
printf("\n");
printf("中序遍历:");
InOrder(pRoot);
printf("\n");
printf("后序遍历:");
PostOrder(pRoot);
printf("\n");
printf("层序遍历:");
LevelOrder(pRoot);
}
//A B D # # # C E #
test.c
# include"BinaryTree.h"
int main()
{
TestBinTree();
system("pause");
return 0;
}