二叉查找树的算法实现

二叉查找树又叫二叉排序树,属于二叉树的一种特例,是空树或具有如下特点的树:
1.若左子树非空,则左子树上的所有节点的关键字值都小于根节点的关键字。
2.若右子数非空,则右子树上的所有节点的关键字值都大于根节点的关键字。
3 .左右子树又是一个二叉搜索树。
由二叉查找树的定义可知,在一棵非空的二叉查找树中,其结点的关键字是按照左子树、根和右子树有序的,所以对它进行中序遍历得到的结点序列是一个有序序列。
二叉查找树的这种特殊性质使得它在查找元素的时候特别的方便,每一次查找都可以去掉一半的元素,因此查找的时间是O(logN).

 

以下是二叉查找树的相关操作的算法实现:

 

  1 struct Node{
  2     int data;
  3     Node *lchild, *rchild, *parent;    
  4 };
  5 
  6 /*在以t为树根的二叉查找树中,递归查找关键字key */
  7 Node* recursion_tree_search(Node *t, int key){
  8     if(t!=NULL || key==t->data)
  9         return t;
 10     if(key<t->data)
 11         return recursion_tree_search(t->lchild, key);
 12     else
 13         return recursion_tree_search(t->rchild, key);
 14 }
 15 
 16 /*在以t为树根的二叉查找树中,非递归查找关键字key */
 17 Node* iterative_tree_search(Node *t, int key){
 18     while(t!=NULL && key!=t->data){
 19         t = (key<t->data)?t->lchild:t->rchild;
 20     }
 21     return t;
 22 }
 23 
 24 /*在以t为树根的二叉查找树中,查找最小元素,返回其指针 */
 25 Node* tree_minimum(Node *t){
 26     while(t->lchild!=NULL){
 27         t = t->lchild;
 28     }
 29     return t;
 30 }
 31 
 32 /*在以t为树根的二叉查找树中,查找最大元素,返回其指针 */
 33 Node* tree_maximum(Node *t){
 34     while(t->rchild!=NULL){
 35         t = t->rchild;
 36     }
 37     return t;
 38 }
 39 
 40 /*查找x结点的直接后继,返回其指针 */
 41 Node* tree_successor(Node *x){
 42     if(x->rchild!=NULL){//如果右子树非空,那么直接后继为右子树的最小元素 
 43         return tree_minimum(x->rchild); 
 44     } else{//否则直接后继为x的最低祖先结点,且其直接后继的左孩子也是x的祖先 
 45         Node *p = x->parent; 
 46         while(p!=NULL && x==p->rchild){
 47             x = p;
 48             p = p->parent;
 49         } 
 50         return p;
 51     }
 52 }
 53 
 54 /*查找x结点的直接前驱,返回其指针 */
 55 Node* tree_predecessor(Node *x){
 56     if(x->lchild!=NULL){//如果左子树非空,那么直接后继为左子树的最大元素
 57         return tree_maximum(x->lchild);
 58     } else{//否则直接前驱为x的最低祖先几点,且其直接前驱的右孩子也是x的祖先 
 59         Node *p = x->parent;
 60         while(p!=NULL && x==p->lchild){
 61             x = p;
 62             p = p->parent;
 63         } 
 64         return p;
 65     }
 66 }
 67 
 68 /*在以t为树根的二叉查找树中,插入结点x*/
 69 void tree_insert(Node *t, Node *x){
 70     Node *p = NULL;
 71     while(t!=NULL){
 72         p = t;
 73         if(x->data < t->data){//插到左子树 
 74             t = t->lchild; 
 75         } else{//插到右子树     
 76             t = t->rchild;
 77         }
 78     }
 79     if(p==NULL){//树为空,直接插入到根结点
 80          t = x;
 81     } else if(x->data < p->data){//插入到左结点 
 82         p->lchild = x;
 83         x->parent = p;
 84     } else{//插入到右结点 
 85         p->rchild = x;
 86         x->parent = p;
 87     }
 88 } 
 89 
 90 /*在以t为树根的二叉查找树中,删除关键字为key的结点。包含三种情况,1.如果x结点
 91 没有子女,直接将其删除。2.如果x结点只有一个子女,则删除x,并将x的子女置为x的
 92 位置。3.如果x结点有两个子女,则删除其后继结点(它至多有一个子女),接着替换x
 93 和x后继结点的关键字*/
 94 Node* tree_delete(Node *t, int key){
 95     Node *x = iterative_tree_search(t, key);//查找关键字key的结点 
 96     Node *y, *z;
 97     if(x->lchild==NULL || x->rchild==NULL){//如果x结点不是同时有左右孩子,将其存到临时变量y 
 98         y = x;
 99     } else{//否则临时变量存x的后继结点; 
100         y = tree_successor(x);
101     }
102     //z存y的孩子结点 
103     if(y->lchild!=NULL){
104         z = y->lchild;
105     }else{
106         z = y->rchild;
107     }
108     
109     if(z!=NULL){
110         z->parent = y->parent;
111     } 
112     if(y==NULL){
113         t = z;
114     } else if(y==y->parent->lchild){
115         y->parent->lchild = z;
116     } else{
117         y->parent->rchild = z;
118     }
119     
120     if(y != x){
121         x->data = y->data;
122     }
123     return y;
124 }

 




posted @ 2013-08-26 10:19  Sharkd  阅读(295)  评论(0编辑  收藏  举报