目录:
- 分析顺序存储二叉树的优缺点
- 使用孩子法实现二叉树
1.二叉树的顺序结构
普通的二叉树不适合用数组来存储,因为可能会造成大量的空间浪费。而完全二叉树更适合利用顺序结构存储。现实中我们通常把堆(一种二叉树)使用顺序结构的数组来存储,需要注意的是这里的堆操作和操作系统虚拟进程地址空间是两回事,一个是数据结构,一个是操作系统中管理内存的一块区域分段。
2.下面我们来看孩子法实现二叉树程序:
头文件BinTree.h代码如下:
#pragma once
//二叉树的链式存储方式--孩子表示法
typedef int BTDataType;
typedef struct BTNode{
struct BTNode* _pLeft;
struct BTNode* _pRight;
BTDataType _data;
}BTNode;
//获取二叉树
BTNode* BuyBinTreeNode(BTDataType data);
//二叉树的创建
BTNode* _CreatBinTree(BTDataType* array, int size, int* index, BTDataType invalid);
//重新包装
BTNode* CreatBinTree(BTDataType* array, int size, BTDataType invalid);
//二叉树的拷贝(查询概念)
void* CopyBinTree(BTNode* pRoot);
//前序遍历
void PreOrder(BTNode* pRoot);
//中序遍历
void InOrder(BTNode* pRoot);
//后序遍历
void PosOrder(BTNode* pRoot);
//获取二叉树中第k层结点的个数
void GetKLevelNodeCount(BTNode* pRoot, int K);
//获取二叉树中的结点
int GetBinTreeSize(BTNode* pRoot);
//叶子结点个数
int GetLeafCount(BTNode* pRoot);
//获取树的高度
void GetBinTreeHeight(BTNode* pRoot);
//元素在树中位置的查找
BTNode BinTreeFind(BTNode* pRoot, BTDataType x);
//销毁
void DestroyBinTree(BTNode** pRoot);
//测试
void TestBinTree();
源文件BinTree.c代码如下:
#include "BinTree.h"
#include <stdio.h>
#include <malloc.h>
#include <assert.h>
#include <string.h>
//获取二叉树
BTNode* BuyBinTreeNode(BTDataType data){
BTNode* pNewNode = (BTNode*)malloc(sizeof(BTNode));
if (NULL == pNewNode){
assert(0);
return NULL;
}
pNewNode->_data = data;
pNewNode->_pLeft = NULL;
pNewNode->_pRight = NULL;
return pNewNode;
}
//二叉树的创建
BTNode* _CreatBinTree(BTDataType* array, int size, int* index, BTDataType invalid){
BTNode* pRoot = NULL;
if (*index < size && invalid != array[*index]){
//创建根节点
pRoot = BuyBinTreeNode(array[*index]);
//创建根的左子树
++(*index);
pRoot->_pLeft = _CreatBinTree(array, size, index, invalid);
//创建根的右子树
++(*index);
pRoot->_pRight = _CreatBinTree(array, size, index, invalid);
}
return pRoot;
}
//重新包装
BTNode* CreatBinTree(BTDataType* array, int size,BTDataType invalid){
int index = 0;
return _CreatBinTree(array, size, &index, invalid);
}
//前序遍历
void PreOrder(BTNode* pRoot){
if (pRoot){
printf("%c ", pRoot->_data);
PreOrder(pRoot->_pLeft);
PreOrder(pRoot->_pRight);
}
}
//中序遍历
void InOrder(BTNode* pRoot){
if (pRoot){
InOrder(pRoot->_pLeft);
printf("%c ", pRoot->_data);
InOrder(pRoot->_pRight);
}
}
//后序遍历
void PosOrder(BTNode* pRoot){
if (pRoot){
PosOrder(pRoot->_pLeft);
PosOrder(pRoot->_pRight);
printf("%c ", pRoot->_data);
}
}
//叶子结点个数
int GetLeafCount(BTNode* pRoot){
if (NULL == pRoot){
return 0;
}
if (NULL == pRoot->_pLeft && NULL == pRoot->_pRight){
return 1;
}
return GetLeafCount(pRoot->_pLeft) + GetLeafCount(pRoot->_pRight);
}
//销毁(后序方法)
void DestroyBinTree(BTNode** pRoot){
if (*pRoot){
DestroyBinTree(&(*pRoot)->_pLeft);
DestroyBinTree(&(*pRoot)->_pRight);
free(*pRoot);
*pRoot = NULL;
}
}
//测试
void TestBinTree(){
char* str = "ABCDE#F##G#";
BTNode* pRoot = CreatBinTree(str, strlen(str),'#');
printf("前序遍历结果: ");
PreOrder(pRoot);
printf("\n");
printf("中序遍历结果: ");
InOrder(pRoot);
printf("\n");
printf("后序遍历结果: ");
PosOrder(pRoot);
printf("\n");
DestroyBinTree(&pRoot);
}
测试代码:
#include "BinTree.h"
int main(){
TestBinTree();
system("pause");
return 0;
}
~bye~