二叉排序树也称二叉查找树。是一种特殊的二叉树。
特点
二叉排序树中,如果其左子树非空,那么左子树上所有结点的值都小于根结点的值;
二叉排序树中,如果其右子树非空,那么右子树上所有结点的值都大于根结点的值;
二叉排序树的左右子树也要求都是二叉排序树。
定义二叉排序树的结构
typedef struct BSTNode{ TreeElem data; struct BSTNode* Lchild, * Rchild; //左右孩子指针}BSTNode, * BSTree;
查找操作
若二叉排序树为空,则返回false;
若二叉排序树不空,则判断给定值是否与结点数据值相等:
-
若相等,则记录此结点(定义一个指针p记录),并返回true;
若keydata,则继续调用函数比较左子树
若key>T->data, 则继续调用函数比较右子树
查找代码
bool SearchBST(BSTree T, TreeElem key,BSTree f,BSTree *p){ if (T == NULL) { *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);}
二叉树的遍历操作
二叉树的遍历方式有三种:前序、中序和后序,利用递归。//前序遍历void preordertraverse(BiTree t){ if (t == NULL) return; printf("%c", t->data); preordertraverse(t->Lchild); preordertraverse(t->Rchild);}//中序遍历void inordertraverse(BiTree t){ if (t == NULL) return; inordertraverse(t->Lchild); printf("%c ", t->Lchild); inordertraverse(t->Rchild);}//后序遍历void outordertraverse(BiTree t){ if (t == NULL) return; outordertraverse(t->Lchild); outordertraverse(t->Rchild); printf("%c ", t->data);}
二叉排序树的插入操作
进行插入操作时,可以通过调用查找函数判断要插入的元素是否已经存在,如果不存在则继续插入。注意:插入结点一定是叶子结点//插入操作--插入结点一定是叶子结点bool InsertBST(BSTree* T, int key){ BSTree p,s; if (SearchBST(*T, key, NULL, &p)) //如果查找成功 return false; else //如果查找不成功,插入的结点是此时p指向结点的子结点 { s = (BSTree)malloc(sizeof(BSTNode)); if (s == NULL) return false; s->data = key; s->Lchild =s->Rchild=NULL; if (p == NULL) *T = s; //此时s为根节点 else if (key < p->data) p->Lchild = s; else if (key > p->data) p->Rchild = s; return true; }}
有了插入操作,就可以利用插入函数创建一个二叉排序树。
全部代码(没写删除函数)
#include #include #define TreeElem int//定义结构体typedef struct BSTNode{ TreeElem data; struct BSTNode* Lchild, * Rchild;}BSTNode, * BSTree;//查找操作//f指向T的双亲,其初始值为NULL/*p是二重指针,若查找成功,p指向该数据所在的结点,若查找失败,则指向查找路径上访问的最后一个结点*/bool SearchBST(BSTree T, TreeElem key,BSTree f,BSTree *p){ if (T == NULL) { *p = f; //说明f是此条路径上的最后一个元素,当然f也可能为NULL 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);}//插入操作--插入结点一定是叶子结点bool InsertBST(BSTree* T, int key){ BSTree p,s; if (SearchBST(*T, key, NULL, &p)) //如果查找成功 return false; else //如果查找不成功,插入的结点是此时p指向结点的子结点 { s = (BSTree)malloc(sizeof(BSTNode)); if (s == NULL) return false; s->data = key; s->Lchild = NULL; s->Rchild = NULL; if (p == NULL) *T = s; //此时s为根节点 else if (key < p->data) p->Lchild = s; else if (key > p->data) p->Rchild = s; return true; }}//中序遍历void preordertraverse(BSTree T){ if (T == NULL)return; preordertraverse(T->Lchild); printf("%d\n", T->data); preordertraverse(T->Rchild);}int main(void){ BSTree t = NULL; //利用插入操作创建二叉排序树 int a[10] = { 62,88,58,47,35,73,51,99,37,93 }; int i; for (i = 0; i < 10; i++) { InsertBST(&t, a[i]); } preordertraverse(t); return 0;}