前言:
二叉树这一章的内容实现相对于上一章难多了,不仅仅是想明白就一定能立刻写出来,实现的时候会遇上许多没有考虑周到的问题,需要在实现的时候再选择一个合适的解法。并且在编码完之后,进行调试的时候,同样会遇到许多问题,比如树断裂了,对NULL指针进行了访问,等等。这些问题都需要细心的好好检查,调试,解决。这一章的博客本来上一周就该更新,不过为了实现这些头疼的树,让我拖到了现在。
我的github:
我实现的代码全部贴在我的github中,欢迎大家去参观。
https://github.com/YinWenAtBIT
原理:
二叉树:
二叉树(Binary Tree)的特点是每个结点至多具有两棵子树(即在二叉树中不存在度大于2的结点),并且子树之间有左右之分。
(1)、在二叉树的第i层上至多有2i-1个结点(i≥1)。
(2)、深度为k的二叉树至多有2k-1个结点(k≥1)。
(3)、对任何一棵二叉树,如果其终端结点数为n0,度为2的结点数为n2,则n0=n2+1。
二叉查找树:
BinarySearchTree,也叫二叉搜索树,或称二叉排序树(Binary Sort Tree),是具有下列性质的二叉树:
(1)、若它的左子树不为空,则左子树上所有结点的值均小于它的根结点的值;
(2)、若它的右子树不为空,则右子树上所有结点的值均大于它的根结点的值;
(3)、它的左、右子树也分别为二叉查找树
操作:
插入:
二叉查找树的插入过程如下:1.若当前的二叉查找树为空,则插入的元素为根节点,2.若插入的元素值小于根节点值,则将元素插入到左子树中,3.若插入的元素值不小于根节点值,则将元素插入到右子树中。
SearchTree Insert(ElementType X, SearchTree T)
{
if(T ==NULL)
{
T = (SearchTree)malloc(sizeof(TreeNode));
T->Element = X;
T->lchild = T->rchild = NULL;
}
else if(X< T->Element)
{
T->lchild = Insert(X, T->lchild);
}
else if(X>T->Element)
{
T->rchild = Insert(X, T->rchild);
}
return T;
}
删除:
删除的操作也是需要先找到节点,1.当前节点小于要删除的数据时则走向右子树;2.当前节点大于要删除的数据则走向左子树3.找到数据后删除。
我的实现方式为递归删除,找到的节点若有左右两个子树,则拿右子树的最小值代替该节点,再删除又子树的最小值。
/*递归删除*/
SearchTree Delete(ElementType X, SearchTree T)
{
Position tempCell;
if(T ==NULL)
{
perror("Element not Found");
return NULL;
}
if(X< T->Element)
T->lchild = Delete(X, T->lchild);
else if(X> T->Element)
T->rchild = Delete(X, T->rchild);
else
{
/*找到的树节点如果有两个孩子的话就用它右子树的最大值代替该点,再删去右子数上的最大值*/
if(T->lchild && T->rchild)
{
tempCell = FindMin(T->rchild);
T->Element = tempCell ->Element;
T->rchild = Delete(T->Element, T->rchild);
}
else
{
tempCell = T;
if(T->lchild ==NULL)
T = T->rchild;
else
T = T->lchild;
free(tempCell);
}
}
return T;
}
寻找:
寻找操作利用查找二叉树左小右大的性质,非常容易实现,我使用递归的方式实现查找,非递归的方式实现寻找最大最小值
Position Find(ElementType X, SearchTree T)
{
if(T == NULL)
return NULL;
if(T->Element == X)
return T;
else if(X <T->Element)
return Find(X, T->lchild);
else
return Find(X, T->rchild);
}
/*非递归查找最小值*/
Position FindMin(SearchTree T)
{
if(T!=NULL)
{
while(T->lchild !=NULL)
T = T->lchild;
return T;
}
return NULL;
}
/*非递归查找最大值*/
Position FindMax(SearchTree T)
{
if(T!= NULL)
{
while(T->rchild !=NULL)
T= T->rchild;
return T;
}
return NULL;
}
总结:
二叉查找树是树结构中最基础的一种,只有完全理解并且能实现它之后,才能做好之后的更难的树的实现。该树由于不能保持左右的平衡,所以实际上不能直接拿来使用,需要进一步改进。