1. 分析顺序存储二叉树的优缺点
二叉树的顺序存储,寻找后代节点和祖先节点都非常方便,但对于普通的二叉树,顺序存储浪费大量的存储空间,同样也不利于节点的插入和删除。因此顺序存储一般用于存储完全二叉树。
链式存储相对顺序存储节省存储空间,插入删除节点时只需修改指针,但寻找指定节点时很不方便。不过普通的二叉树一般是用链式存储结构。
2. 使用孩子表示法实现二叉树的以下操作:
typedef char BTDataType;
typedef struct BTNode
{
struct BTNode* _pLeft;
struct BTNode* _pRight;
BTDataType _data;
}BTNode;
// 二叉树的创建
BTNode* CreateBinTree(BTDataType* array, int size, BTDataType invalid);
BTNode* _CreateBinTree(char* array, int size,int* index) {
BTNode* pRoot = NULL;
//根节点
if ((*index) < size&&'#' != array[*index]) {
pRoot = BuyBinTeeNode(array[*index]);
//根的左子树
++*index;
pRoot->_pLeft=_CreateBinTree(array, size, index);
//根的右子树
++*index;
pRoot->_pRight= _CreateBinTree(array, size, index);
}
return pRoot;
}
// 二叉树的拷贝
BTNode* CopyBinTree(BTNode* pRoot);
BTNode* CopyBinTree(BTNode* pRoot) {
BTNode* newNode = NULL;
if (pRoot == NULL)
{
return NULL;
}
else {
newNode = (BTNode*)malloc(sizeof(BTNode));
newNode->_data = pRoot->_data;
newNode->_pLeft = CopyBinTree(pRoot->_pLeft);
newNode->_pRight = CopyBinTree(pRoot->_pRight);
return newNode;
}
}
// 二叉树的销毁
void DestroyBinTree(BTNode** pRoot);
void DestroyBinTree(BTNode** pRoot) {
assert(pRoot);
if (*pRoot) {
DestroyBinTree(&((*pRoot)->_pLeft));
DestroyBinTree(&((*pRoot)->_pRight));
free(*pRoot);
*pRoot = NULL;
}
}
// 递归:前序遍历
void PreOrder(BTNode* pRoot);
void PreOrder(BTNode* pRoot) {
if (pRoot) {
printf("%c", pRoot->_data);
PreOrder(pRoot->_pLeft);
PreOrder(pRoot->_pRight);
}
}
// 递归:中序遍历
void InOrder(BTNode* pRoot);
void InOrder(BTNode* pRoot) {
if (pRoot) {
InOrder(pRoot->_pLeft);
printf("%c", pRoot->_data);
InOrder(pRoot->_pRight);
}
}
// 递归:后序遍历
void PostOrder(BTNode* pRoot);
void PostOrder(BTNode* pRoot) {
if (pRoot) {
PostOrder(pRoot->_pLeft);
PostOrder(pRoot->_pRight);
printf("%c", pRoot->_data);
}
}
// 层序遍历
void LevelOrder(BTNode* pRoot);
在二叉树的层序遍历中,会用到队列,需要构建队列。队列的实现参考链接:https://blog.csdn.net/weixin_41826018/article/details/90493222
void LevelOrder(BTNode* pRoot) {
if (NULL == pRoot)
return;
Queue q;
QueueInit(&q);
QueuePush(&q, pRoot);
while (!QueueEmpty(&q)) {
BTNode* pCur = QueueFront(&q);
printf("%c", pCur->_data);
if (pCur->_pLeft)
QueuePush(&q, pCur->_pLeft);
if (pCur->_pRight)
QueuePush(&q, pCur->_pRight);
QueuePop(&q);
}
QueueDestroy(&q);
printf("\n");
}
// 获取二叉树中节点个数
int GetBinTreeSize(BTNode* pRoot);
int GetBinTreeSize(BTNode* pRoot) {
if (NULL == pRoot)
return 0;
else if ((pRoot->_pLeft == NULL)&&(pRoot->_pRight == NULL))
return 1;
else {
return GetBinTreeSize(pRoot->_pLeft) + GetBinTreeSize(pRoot->_pRight);
}
}
// 获取二叉树中第K层节点个数
int GetKLevelNodeCount(BTNode* pRoot, int K);
int GetKLevelNodeCount(BTNode* pRoot, int K) {
if (NULL == pRoot || K <= 0)
return 0;
if (K == 1)
return 1;
return GetKLevelNodeCount(pRoot->_pLeft, K - 1) +
GetKLevelNodeCount(pRoot->_pRight, K - 1);
}
// 获取二叉树中叶子节点个数
int GetLeafCount(BTNode* pRoot);
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);
}
// 获取二叉树深度(高度)
int GetBinTreeHeight(BTNode* pRoot);
int GetBinTreeHeight(BTNode* pRoot) {
int hl, hr, max;
if (pRoot != NULL) {
hl = GetBinTreeHeight(pRoot->_pLeft);
hr = GetBinTreeHeight(pRoot->_pRight);
max = hl > hr ? hl: hr;
return max + 1;
}
else {
return 0;
}
}
// 检测值为x的元素是否在二叉树中,在返回该节点的地址,否则返回NULL
BTNode* BinaryTreeFind(BTNode* root, BTDataType x);
BTNode* BinaryTreeFind(BTNode* pRoot, BTDataType x) {
BTNode* pRet = NULL;
if (NULL == pRoot)
return NULL;
if (x == pRoot->_data)
return pRoot;
if (pRet==BinaryTreeFind(pRoot->_pLeft, x))
return pRet;
else {
pRet == BinaryTreeFind(pRoot->_pRight, x);
return pRet;
}
}
// 二叉树的镜像
void Mirror(BTNode* pRoot);
void Mirror(BTNode* pRoot) {
Queue q;
if (NULL == pRoot)
return;
QueueInit(&q);
QueuePush(&q, pRoot);
while (!QueueEmpty(&q)) {
BTNode* pCur = QueueFront(&q);
Swap(&pCur->_pLeft, &pCur->_pRight);
if (pCur->_pLeft)
QueuePush(&q, pCur->_pLeft);
if (pCur->_pRight)
QueuePush(&q, pCur->_pRight);
QueuePop(&q);
}
}void Swap(BTNode** pLeft, BTNode** pRight) {
BTNode* temp = *pLeft;
*pLeft = *pRight;
*pRight = temp;
}
// 判断二叉树是否是完全二叉树
int BinaryTreeComplete(BTNode* root);