二叉排序树(Binary Sort Tree):或者是一颗空树,或者是具有下面性质的树:(1)若它的左子树不空,则左子树上所以结点的值均小于它的根节点的值;(2)若它的右子树不空,则右子树上的所以结点的值均大于它的根节点的值;(3)它的左、右子树也各自是二叉排序树。
二叉排序树的基本操作均能够在O(h)时间内完毕(算法导论p165)。
相关操作代码例如以下:
int InsertBST(BiTree &T, int key)//递归插入 { if (T == NULL) { T = new BiNode; T->data = key; T->lchild = T->rchild = NULL; return 1; } else { if (key == T->data) return 0; else if (key < T->data) return InsertBST(T->lchild, key); else return InsertBST(T->rchild, key); } } int InsertBST_(BiTree &T, int key)//迭代插入 { //find the insert position BiNode *f = T, *p = T; while (p != NULL) { if (key == p->data) return 0; f = p; //记录上一次訪问的结点 p = key < p->data ? p->lchild : p->rchild; } //分配新结点 BiNode *q = new BiNode; q->lchild = q->rchild = NULL; q->data = key; //插入 if (T == NULL) //若根为空 { T = q; return 1; } if (key < f->data) f->lchild = q; else f->rchild = q; return 1; } BiNode *SearchBST(BiTree T, int key)//递归搜索 { if (!T) return NULL; else { if (key == T->data) return T; else if (key < T->data) return SearchBST(T->lchild, key); else return SearchBST(T->rchild, key); } } BiNode* SearchBST_(BiTree T, int key)//迭代搜索 { while (T != NULL) { if (key == T->data) break; T = key < T->data ? T->lchild : T->rchild; } return T; } int DeleteNode(BiNode *&p) { BiNode *q; //从二叉排序树中删除结点p,并重接它的的左或右子树 if (p == NULL) return 0; if (p->lchild == NULL) //左子树空则仅仅需重接右子树 { q = p; p = p->rchild; delete q; } else if (p->rchild == NULL) //右子树空则仅仅需重接左子树 { q = p; p = p->lchild; delete q; } else //左右子树均不空 { BiNode *s; #if 0 //用p的直接前驱取代p,然后删除p的直接前驱 q = p; s = p->lchild;//转左,然后向右到尽头 while (s->rchild) { q = s; s = s->rchild; } p->data = s->data; //s指向被删除结点,q指向被删除结点的前驱 if (q != p) q->rchild = s->lchild; //重接q的右子树 else q->lchild = s->lchild; //重接q的左子树 #else //用p的直接后继取代p,然后删除p的直接后继 q = p; s = p->rchild; while (s->lchild) { q = s; s = s->lchild; } p->data = s->data; if (p != p) q->lchild = s->rchild; else q->rchild = s->rchild; #endif delete s; } return 1; } int DeleteBST(BiTree &T, int key) { if (T == NULL) return 0; else { if (key == T->data) return DeleteNode(T); else if (key < T->data) return DeleteBST(T->lchild, key); else return DeleteBST(T->rchild, key); } } void CreateBST(BiTree &T, int a[], int n) { T = NULL; for (int i = 0; i < n; i++) { InsertBST_(T, a[i]); } } void DestoryBST(BiTree &T) { if (T == NULL) return; DestoryBST(T->lchild); DestoryBST(T->rchild); delete T; T = NULL; } void InOrderTraverse(BiTree T)//=O(n)时间复杂度 { if (T == NULL) return; InOrderTraverse(T->lchild); cout << T->data << " "; InOrderTraverse(T->rchild); }測试代码:
int main() { const int n = 10; int a[n] = {3, 2, 8, 6, 1, 4, 5, 7, 1, 3}; BiTree T; CreateBST(T, a, n); InOrderTraverse(T); cout << endl; BiNode *p; for (int i = 1; i < 10; i++) { p = SearchBST_(T, i); if (p != NULL) cout << p->data << endl; } int b[5]={0, 2, 6, 1, 7}; int ret; for (int i = 0; i < 5; i++) { ret = DeleteBST(T, b[i]); if (ret == 0) cout << "删除 " << b[i] << " 失败" << endl; else { cout << "删除 " << b[i] << " 后: " ; InOrderTraverse(T); cout << endl; } } DestoryBST(T); getchar(); return 0; }
參考:数据结构C语言版、算法导论(关于删除结点操作,该书p173页有注记)