查找树是一种支持包括查找、插入、找最小值、找出最大值、找出前趋、找出后继、删除动态集合操作的数据结构。
基本操作的时间与树的高度成正比,对于一棵含有n个结点的完全二叉树,基本操作的最坏情况运行时间为Θ(lgn),对于含有n个结点的树(不是完全二叉树),最坏的情况(线性链)运行时间为Θ(n)。
二叉查找树的性质:x为二叉查找树的一个结点,x_l 为x的左子树中的一个结点,那么x_l存储的关键字小于或者等于x存储的关键字;x_r为x的右子树中的一个结点,那么x_r存储的关键字大于或者等于x存储的关键字。
如下图所示:
二叉树可以用链表结构来表示,每个结点除了关键字和卫星数据外,还有3个指针,分别指向左右儿子结点和父结点。
关于树结点的插入:
1、树为空;这时候要插入到树的结点为树根。
2、树不为空;从根结点开始,不断与插入结点的关键字比较,如果插入结点比较大,那么就往根结点的右子树走,否则就往左子树走;然后继续与子树的根结点比较,直到为空结点,将要插入的结点插到该位置,并将其父指针指向正确的结点。
1 /* 2 * 插入函数,注意插入结点与其在树中对应的父结点的链接(需要记录父结点)。 3 * 从根结点出发,不停用当前结点与插入的值比较,如果当前结点的值比较大就往当前结点的左儿子走,相反就往右儿子走,直到当前结点为空, 4 * 在过程中记录当前结点的父结点。 5 * 运行时间为O(h),h为树的高度。因为整个过程是一条沿着根结点下降的路径。 6 */ 7 void Tree_Insert(Tree *T, int key){ 8 TreeNode *x; 9 x = (TreeNode *)malloc(sizeof(TreeNode)); //新建结点,并将key值付给结点的数据 10 x->value = key; 11 x->parent = x->left = x->right = NULL; 12 13 if(T->root == NULL) 14 T->root = x; //如果树为空,x结点为根 15 else{ 16 TreeNode *y = T->root; //y结点用来记录当前结点 17 TreeNode *z = NULL; //z结点用来记录当前结点的父结点 18 while(y != NULL){ 19 z = y; 20 if(y->value > x->value) 21 y = y->left; 22 else 23 y = y->right; 24 } 25 x->parent = z; //将x结点与其父结点链接 26 if(z->value > x->value) 27 z->left = x; 28 else 29 z->right = x; //x结点的父节点与x结点链接 30 } 31 }