二叉排序树的定义:二叉排序树或者是空树,或者是满足如下性质的二叉树:
①若它的左子树非空,则左子树上所有结点的值均小于根结点的值;
②若它的右子树非空,则右子树上所有结点的值均大于根结点的值;
③左、右子树本身又各是一棵二叉排序树。
上述性质简称二叉排序树性质(BST性质),故二叉排序树实际上是满足BST性质的二叉树。
如果一开始输入的序列是有序序列,则建立的类似一个单链表。
一个非常重要的性质是二叉排序树的中序遍历为从小到大的有序序列。
#define _CRT_SECURE_NO_DEPRECATE #include<stdio.h> #include<stdlib.h> #include<windows.h> #define DataType int typedef struct BSTNode{ DataType data; struct BSTNode *lchild, *rchild; }BSTNode, *BSTree; bool SearchBST(BSTree &T, DataType x)//递归查找是否存在某元素 { if (!T) return false; if (T->data == x) return true; else if (T->data > x)//转到左分支 return SearchBST(T->lchild, x); else //转到右分支 return SearchBST(T->rchild, x); } bool SearchBST1(BSTree &T, DataType x)//非递归查找是否存在 { BSTree p = T; while (T) { if (T->data == x) return true; else if (p->data > x) p = p->lchild; else p = p->rchild; } return false; } bool SearchBST2(BSTree &T,DataType x,BSTree &result, BSTree &parent)//递归查找并返回结果,所在位置 { if (!T) { result = parent;//不成功就返回其双亲位置,为随后添加作铺垫 return false; } if (T->data == x)//查找成功就返回其位置指针 { result = T; return true; } else if (T->data > x) return SearchBST2(T->lchild, x, result, T);//parent=T,根结点T位置赋值给参量parent else return SearchBST2(T->rchild, x, result, T); } bool InsertBST(BSTree &T,DataType x)//插入元素 { BSTree parent = NULL, result = NULL,s;//初始化参量 if (!SearchBST2(T, x, result, parent))//如果不存在 { s = (BSTree)malloc(sizeof(BSTNode)); s->data = x; s->lchild = s->rchild = NULL; if (!result)//第一种情况空树,则根结点加入此元素 T=s; else//否则利用返回的双亲结点进行添加新结点 { if (result->data > x) result->lchild = s; else result->rchild = s; } return true; } else return false; } void CreatBST(BSTree &T,int n)//创建二叉排序树,用到了插入函数 { printf("请输入%d个数据:\n", n); int a; for (int i = 0; i < n; i++) { scanf("%d", &a); InsertBST(T, a); } } void InOrder(BSTree &T)//中序遍历 { if (T) { InOrder(T->lchild); printf("%3d", T->data); InOrder(T->rchild); } } void Delete(BSTree &p)//删除某结点,注意是直接改这个指针,“引用&”类型 {//分为几种情况,对照图来看代码 BSTree 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为此结点双亲指针 { q = s; s = s->rchild; } p->data = s->data;//最左下结点数据代替要删数据 if (p == q)//关键特殊情况!p就是左分支最右下结点的双亲 q->lchild = s->lchild; else q->rchild = s->lchild;//因为s所指的结点为最右下,显然其无右孩子,直接把左分支给其双亲的 delete(s);//释放最左下结点空间 } } bool DeleteBST(BSTree &T, DataType x)//递归删除结点 { if (!T) return false; if (T->data == x) { Delete(T); return true; } else if (T->data >x) return DeleteBST(T->lchild,x); else return DeleteBST(T->rchild, x); } int main()//测试代码 { BSTree mytree=NULL; DataType x = 4; CreatBST(mytree, 10); InOrder(mytree); printf("\n"); DeleteBST(mytree,x); InOrder(mytree); printf("\n"); system("pause"); return 0; }
时间: 2024-11-09 08:07:28