假定二叉排序树的根节点指针为root,给定的关键字值为key,则查找算法可描述为:
//BST的递归查找 void SearchBST( BiTree t, Elemtype key ) { BiTree p; p = t; if( p ) { if( key == p->data ) printf("查找成功!\n"); else if( (key < p->data) && (NULL != p->lchild) ) SearchBST( p->lchild , key ); else if( (key > p->data) && (NULL != p->rchild) ) SearchBST( p->rchild , key ); else printf("无此元素!\n"); } }
//BST的迭代查找 void _SearchBST( BiTree t, Elemtype key ) { BiTree p; p = t; while( NULL != p && key != p->data ) { if( key < p->data ) p = p->lchild ; else p = p->rchild ; } if( NULL != p ) printf("查找成功!\n"); else printf("无此元素!\n"); }
假设要删除的结点为 p ,结点 p 的双亲结点为 q ,下面分三种情况讨论:
//情况1:结点p的双亲结点为q,且p为叶子结点,则直接将其删除。 if( NULL == p->lchild && NULL == p->rchild ) { if( p == q->lchild ) q->lchild = NULL; if( p == q->rchild ) q->rchild = NULL; free(p); p = NULL; }
//情况2:结点p的双亲结点为q,且p只有左子树或只有右子树,则可将p的左子树或右子树直接改为其双亲结点q的左子树或右子树。 else if( (NULL == p->rchild && NULL != p->lchild) ) { //p只有左子树 if( p == q->lchild ) q->lchild = p->lchild ; else if( p == q->rchild ) q->rchild = p->lchild ; free(p); p = NULL; } else if( NULL == p->lchild && NULL != p->rchild ) { //p只有右子树 if( p == q->lchild ) q->lchild = p->rchild ; if( p == q->rchild ) q->rchild = p->rchild ; free(p); p = NULL; }
//情况3:结点p的双亲结点为q,且p既有左子树又有右子树。本代码使用直接前驱(也可以直接后继) else if( NULL != p->lchild && NULL != p->rchild ) { BiTree s, sParent; sParent = p; s = sParent->lchild ; while( NULL != s->rchild ) { //找到p的直接前驱 sParent = s; s = s->rchild ; } temp = s->data ; DelBSTNode( t, temp ); p->data = temp; }
/* 二叉排序树的查找算法的C代码实现 */ #include <stdio.h> #include <stdlib.h> typedef int Elemtype; typedef struct BiTNode{ Elemtype data; struct BiTNode *lchild, *rchild; }BiTNode, *BiTree; //在给定的BST中插入结点,其数据域为element void BSTInsert( BiTree *t, Elemtype element ) { if( NULL == *t ) { (*t) = (BiTree)malloc(sizeof(BiTNode)); (*t)->data = element; (*t)->lchild = (*t)->rchild = NULL; } if( element == (*t)->data ) return ; else if( element < (*t)->data ) BSTInsert( &(*t)->lchild, element ); else BSTInsert( &(*t)->rchild, element ); } //创建BST void CreateBST( BiTree *t, Elemtype *a, int n ) { (*t) = NULL; for( int i=0; i<n; i++ ) BSTInsert( t, a[i] ); } //BST的递归查找 void SearchBST( BiTree t, Elemtype key ) { BiTree p; p = t; if( p ) { if( key == p->data ) printf("查找成功!\n"); else if( (key < p->data) && (NULL != p->lchild) ) SearchBST( p->lchild , key ); else if( (key > p->data) && (NULL != p->rchild) ) SearchBST( p->rchild , key ); else printf("无此元素!\n"); } } //BST的迭代查找 void _SearchBST( BiTree t, Elemtype key ) { BiTree p; p = t; while( NULL != p && key != p->data ) { if( key < p->data ) p = p->lchild ; else p = p->rchild ; } if( NULL != p ) printf("查找成功!\n"); else printf("无此元素!\n"); } //BST结点的删除 void DelBSTNode( BiTree t, Elemtype key ) { BiTree p, q; p = t; Elemtype temp; while( NULL != p && key != p->data ) { q = p; if( key < p->data ) p = p->lchild ; else p = p->rchild ; } if( NULL == p ) printf("无此元素!\n"); else { //情况1:结点p的双亲结点为q,且p为叶子结点,则直接将其删除。 if( NULL == p->lchild && NULL == p->rchild ) { if( p == q->lchild ) q->lchild = NULL; if( p == q->rchild ) q->rchild = NULL; free(p); p = NULL; } //情况2:结点p的双亲结点为q,且p只有左子树或只有右子树,则可将p的左子树或右子树直接改为其双亲结点q的左子树或右子树。 else if( (NULL == p->rchild && NULL != p->lchild) ) { //p只有左子树 if( p == q->lchild ) q->lchild = p->lchild ; else if( p == q->rchild ) q->rchild = p->lchild ; free(p); p = NULL; } else if( NULL == p->lchild && NULL != p->rchild ) { //p只有右子树 if( p == q->lchild ) q->lchild = p->rchild ; if( p == q->rchild ) q->rchild = p->rchild ; free(p); p = NULL; } //情况3:结点p的双亲结点为q,且p既有左子树又有右子树。本代码使用直接前驱(也可以直接后继) else if( NULL != p->lchild && NULL != p->rchild ) { BiTree s, sParent; sParent = p; s = sParent->lchild ; while( NULL != s->rchild ) { //找到p的直接前驱 sParent = s; s = s->rchild ; } temp = s->data ; DelBSTNode( t, temp ); p->data = temp; } } } //中序遍历打印BST void PrintBST( BiTree t ) { if( t ) { PrintBST( t->lchild ); printf("%d ", t->data); PrintBST( t->rchild ); } } int main() { int n; int *a; Elemtype key; BiTree t; printf("请输入二叉查找树的结点数:\n"); scanf("%d", &n); a = (int *)malloc(sizeof(int)*n); printf("请输入二叉找树的结点数据:\n"); for( int i=0; i<n; i++ ) scanf("%d", &a[i]); CreateBST( &t, a, n ); printf("当前二叉查找树的中序遍历结果为:\n"); PrintBST( t ); printf("\n##############################################\n"); printf("请输入要查找的元素:\n"); scanf("%d", &key); printf("BST递归查找结果:\n"); SearchBST( t, key ); //递归查找 printf("##############################################\n"); printf("请输入要删除的元素:\n"); scanf("%d", &key); DelBSTNode( t, key ); printf("当前二叉查找树的中序遍历结果为:\n"); PrintBST( t ); printf("\n##############################################\n"); printf("请输入要查找的元素:\n"); scanf("%d", &key); printf("BST迭代查找结果:\n"); _SearchBST( t, key ); //迭代查找 return 0; }
9个元素:5 8 2 1 4 7 9 6 3
生成的BST:
测试结果:
测试通过。
原文地址:http://blog.csdn.net/u014488381/article/details/41719765