二叉查找树的定义以及几个基本操作

来源:互联网 发布:淘宝优惠券设置淘口令 编辑:程序博客网 时间:2024/06/05 16:47

二叉查找树是一种特殊的二叉树,一般数据域都是数值类型的元素,原因是二叉查找树基本性质决定了,在二叉查找树中的任意结点,其数据域的数值一定大于它的左子树的所有结点,也小于它的右子树的所有结点!!!所以,是可以比较的数据域才是二叉查找树的存在意义!


这里我写了几个二叉查找树的方法,前几个比较简单,唯一有点难度的是删除结点的操作!


如果待删除的结点是叶子结点,非常好办,删之即可!

如果待删除的结点是非叶子结点,就稍微麻烦一点。非叶子结点也分为两种:有一个子结点和有两个子结点的情况,她们也要分开讨论:


我直接用a代表待删除的结点,这样减少了很多文字叙述,还容易理解!

1、待删除的结点有一个子结点: 这个还是比较容易,用a的双亲结点直接指向a的子结点,然后释放a即可;

2、待删除的结点有两个子结点: 也就是左孩子和右孩子均存在,这才是比较麻烦的,一般的策略是:将a的数据域 = 右子树中的最小数据结点的数据域(设 b),

然后删除这个b结点,由于b是a右子树中的最小数据结点,所以b不可能有左孩子,只可能是有一个右孩子(利用1删之)或者b就是一片叶子,删之十分轻松加愉快,哈哈语病。

好了,上代码,删除结点的操作我会好好注释一下:

#include <stdio.h>#include <stdlib.h>/*数据域类型*/typedef int ElemType;/*二叉树的结点结构*/typedef struct _TreeNode{ElemType data;struct _TreeNode * lchild;struct _TreeNode * rchild;}TreeNode,*PTree;/*构造一颗空树*/void MakeEmpty(PTree * T){if(*T != NULL){MakeEmpty(&(*T)->lchild);MakeEmpty(&(*T)->rchild);free(*T);}*T = NULL;}/*查找结点*/PTree Find(PTree T,ElemType e){if (T->data == e){return T;}else if (T->data > e){return Find(T->lchild,e);} else if(T->data < e){return Find(T->rchild,e);}}/*非递归查找最大的结点*/PTree FindMax(PTree T){if (!T){return NULL;}while (T->rchild){T = T->rchild;}return T;}/*递归查找最小结点*/PTree FindMin(PTree T){if( !T ){return NULL;}if(T->lchild == NULL){return T;}else{return FindMin(T->lchild);}}/*插入结点*/PTree InsertNode(PTree T, ElemType e){if (!T){T = (PTree)malloc(sizeof(TreeNode));if(!T)abort();T->data = e;T->lchild = NULL;T->rchild = NULL;}if(e < T->data){T->lchild = InsertNode(T->lchild,e);}else if(e > T->data){T->rchild = InsertNode(T->rchild,e);}return T;}/*删除结点*/PTree DeleteNode(PTree T, ElemType e){PTree tmp;if(!T){exit(-1);/*空树删个JB*/}else if (e<T->data){T->lchild = DeleteNode(T->lchild,e);/*递归左子树*/} else if(e>T->data){T->rchild = DeleteNode(T->rchild,e);/*递归右子树*/}else if(T->lchild && T->rchild)/*如果待删除的结点左右孩子均存在*/{tmp = FindMin(T->rchild);/*找到其右子树中的最小结点*/T->data = tmp->data;T->rchild = DeleteNode(T->rchild,T->data);/*删除这个最小数据结点*/}else{/*这个条件里说明是只有一个结点的情况*/tmp = T;/*临时变量用于释放结点*/if (T->lchild == NULL)/*只有左孩子*/{T = T->rchild;}else if( T->rchild == NULL)/*只有右孩子*/{T = T->lchild;}free(tmp);}return T;}



0 0