[二叉排序树] 又称为二叉查找树;它或者是一棵空树,或者是具有下列性质的二叉树:
若它的左子树不空,则左子树上所有结点的值均小于它的根结构的值;
若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
它的左、右子树也分别为二叉排序树。
/* 二叉排序树存储结构 */ typedef struct BiTNode { int data; struct BiTNode *lchild, *rchild; } BiTNode, *BiTree;
[查找操作]
/* 递归查找二叉排序树T中是否存在key, */ /* 指针f指向T的双亲,其初始调用值为NULL */ /* 若查找成功,则指针p指向该数据元素结点,并返回TRUE */ /* 否则指针p指向查找路径上访问的最后一个结点并返回FALSE */ Status SearchBST(BiTree T, int key, BiTree f, BiTree *p) { if (!T) /* 查找不成功 */ { *p = f; return FALSE; } else if (key == T->data) /* 查找成功 */ { *p = T; return TRUE; } else if (key < T->data) return SearchBST(T->lchild, key, T, p); /* 在左子树继续查找 */ else return SearchBST(T->rchild, key, T, p); /* 在右子树继续查找 */ }
[插入操作]
/* 当二叉排序树T中不存在关键字等于key的数据元素时 */ /* 插入key并返回TRUE,否则返回FALSE */ Status InsertBST(BiTree *T, int key) { BiTree p, s; if (!SearchBST(*T, key, NULL, &p)) /* 查找不成功 */ { s = (BiTree)malloc(sizeof(BiTNode)); s->data = key; s->lchild = s->rchild = NULL; if (!p) *T = s; /* 插入s为新的根结点 */ else if (key < p->data) p->lchild = s; /* 插入s为左孩子 */ else p->rchild = s; /* 插入s为右孩子 */ return TRUE; } else return FALSE; /* 树中已有关键字相同的结点,不再插入 */ }
[构造二叉排序树]
Status InitTree(BiTree *p) { int i; int a[10] = { 62, 88, 58, 47, 35, 73, 51,99, 37, 93}; BiTree T = NULL; for (i = 0; i < 10; i++) { InsertBST(&T, a[i]); } }
[删除操作]
/* 从二叉排序树中删除结点p,并重接它的左或右子树。 */ Status Delete(BiTree *p) { BiTree q, s; if ((*p)->rchild == NULL) /* 右子树空则只需重接它的左子树 */ { q = *p; *p = (*p)->lchild; free(q); } else if ((*p)->lchild == NULL) /* 左子树空则只需重接它的右子树 */ { q = *p; *p = (*p)->rchild; free(q); } else /* 左右子树均不空 */ { q = *p; s = (*p)->lchild; while (s->rchild) /* 转左,然后向右到尽头(找待删结点的前驱) */ { q = s; s = s->rchild; } (*p)->data = s->data; /* s指向被删结点的直接前驱 */ if (q != *p) q->rchild = s->lchild; /* 重接q的右子树 */ else q->lchild = s->lchild; /* 重接q的左子树 */ free(s); } return TRUE; } /* 若二叉排序树T中存在关键字等于key的数据元素时,则删除该数据元素结点 */ /* 并返回TRUE;否则返回FALSE */ Status DeleteBST(BiTree *T, int key) { if (!*T) /* 不存在关键字等于key的数据元素 */ return FALSE; else { if (key == (*T)->data) return Delete(T); else if (key < (*T)->data) return DeleteBST(&(*T)->lchild, key); else return DeleteBST(&(*T)->rchild, key); } }