前言:
二叉树这一章的内容实现相对于上一章难多了,不仅仅是想明白就一定能立刻写出来,实现的时候会遇上许多没有考虑周到的问题,需要在实现的时候再选择一个合适的解法。并且在编码完之后,进行调试的时候,同样会遇到许多问题,比如树断裂了,对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; }
二叉查找树是树结构中最基础的一种,只有完全理解并且能实现它之后,才能做好之后的更难的树的实现。该树由于不能保持左右的平衡,所以实际上不能直接拿来使用,需要进一步改进。