查找

线性表的查找

<1>顺序查找

<2>二分查找

递归算法
typedef struct
{
    KeyType key;
    InfoType otherinfo; //此类型依赖于应用
}NodeType;
typedef NodeType SeqList[n]; 
int BinSearch(SeqList R, int low, int high, KeyType K)
{     //在有序表R[low,high]中进行二分查找,成功时返回结点的位置,失败时返回零
    int min;
    if(low<=high){   //当前查找区间R[low..high]非空
    {
        mid=(low+high)/2;//置当前查找区间上、下界的中值
        if(R[mid].key==K) return mid; //查找成功返回
        else if(R[mid].kdy>K)
            return BinSearch(R,low,mid-1,K); //继续在R[low..mid-1]中查找
        else
            return BinSearch(R,low,mid-1,K); //继续在R[mid+1..high]中查找
     }
     return -1; //当low>high时表示查找区间为空,查找失败
} //BinSeareh

非递归查找法
int BinSearch(SeqList R,KeyType K)
{ //在有序表R[1..n]中进行二分查找,成功时返回结点的位置,失败时返回零
    int low=1,high=n,mid; //置当前查找区间上、下界的初值
    while(low<=high)
    { //当前查找区间R[low..high]非空
        mid=(low+high)/2;
        if(R[mid].key==K) return mid; //查找成功返回
        if(R[mid].kdy>K)    high=mid-1; //继续在R[low..mid-1]中查找
        else    low=mid+1; //继续在R[mid+1..high]中查找
    }
    return 0; //当low>high时表示查找区间为空,查找失败
} //BinSeareh

 

二叉排序树

<1>二叉排序树的定义(其中的关键字不重复)

要么是空树,要么满足如下条件(BST性质):每个节点的左子树上所有节点的值均小于该节点的值,右子树上所有节点的值均大于等于该节点的值; 

typedef int KeyType;      //假定关键字类型为整数
typedef struct BiTNode
{
    KeyType key;          //关键字项
    InfoType otherinfo;   //其它数据域,InfoType视应用情况而定,下面不处理它
    struct BiTNode *lchild, *rchild;
}BiTNode, *BiTree;

 

<2>二叉排序树的查找

/* 递归查找二叉排序树T中是否存在key, */
/* 指针f指向T的双亲,其初始调用值为NULL */
/* 若查找成功,则指针p指向该数据元素结点,并返回TRUE;*/
/* 若查找不成功,指针p指向查找路径上访问的最后一个结点并返回FALSE,这样方便后续插入节点,若p为null则表示该树为空。
*/ Status SearchBST(BiTree T, KeyType key, BiTree f, BiTree *p) { if (T == NULL) /* 若输入的节点为空,则查找不成功 */ { *p = f; return FALSE; } else if (key == T->key) /* 查找成功 */ { *p = T; return TRUE; } else if (key < T->key) return SearchBST(T->lchild, key, T, p); /* 在左子树中继续查找 */ else return SearchBST(T->rchild, key, T, p); /* 在右子树中继续查找 */ }

 

<3>二叉排序树的插入插入算法:查找关键字key,若查找成功,则不用插入。若查找失败,p为null,或则为要插入的节点的双亲节点。 

/*  当二叉排序树T中不存在关键字等于key的数据元素时,插入key并返回TRUE,否则返回FALSE */
Status InsertBST(BiTree *T, KeyType key) 
{  
    BiTree p,s;

    if (SearchBST(*T, key, NULL, &p)) /*  查找成功,则树中已有关键字相同的结点,不再插入 */
        return FALSE;  
    
    /* 查找不成功 */
    s = (BiTree)malloc(sizeof(BiTNode));
    s->data = key;  
    s->lchild = s->rchild = NULL;  
    if (!p) 
        *T = s;            /*  插入s为新的根结点 */
    else if (key < p->key) 
        p->lchild = s;    /*  插入s为左孩子 */
    else 
        p->rchild = s;  /*  插入s为右孩子 */
    
    return TRUE;         
}

 

<4>删除节点(不改变二叉排序树的BST性质),分三种情况:
a,*p是叶子节点,无须连接*p的子树,只需将*p的双亲*parent中指向*p的指针域置空即可。
b,*p只有一个孩子*child只需将*child和*p的双亲直接连接后,即可删去*p。有四种情况,*p是否为根节点,*child为左或右孩子。具体【参见动画演示

c,*p有两个孩子,先令q=p,将被删结点的地址保存在q中;然后找*q的中序后继*p,并在查找过程中仍用parent记住*p的双亲位置。*q的中序后继*p一定是*q的右子树中最左下的结点,它无左子树。因此,可以将删去*q的操作转换为删去的*p的操作,即在释放结点*p之前将其数据复制到*q中,就相当于删去了*q。具体【参见动画演示】。

/*在二叉排序树*Tptr中删去关键字为key的结点*/
Status DeleteBST(BiTree *T, KeyType key)
{
    BiTree parent=NULL, p=*T;   //用p指向要删除的节点,parent指向*p的双亲
    BiTree q, child;            
    while(p)                   //从根开始查找关键字为key的待删结点
    { 
        if(p->key == key)     
            break;
        parent = p;           
        p = (key < p->key)? p->lchild:p->rchild;   //在p的左或右子树中继续找
    }

    if(p == NULL)     //找不到被删结点则返回FALSE
        return FALSE;   
    
    /*  将情况(3)转换为情况(2),而情况(1)相当于是情况(2)中child=NULL的状况,
    q保存被删节点的地址,找到*q的中序后继*p(或中序前继),
    *p属于(1)(2)情况,然后将后继节点的数据复制到*q节点,接上后继节点的子树后删除该节点*/
    q = p;              
    if(q->lchild && q->rchild)   
      for(parent=p, p=p->rchild; p->lchild; parent=p, p=p->lchild);
         
    child = (p->rchild)? p->rchild:p->lchild;       //若是情况(2),则child非空;否则child为空
    
    if(parent == NULL)  //说明*p属于(1)(2),且*p为根节点,删除*p后应修改根指针
        *T = child; 
    else                //属于(1)(2)且p不是根节点或属于情况(3),删除后不用修改根指针
    { 
        /*  删除*p,*p的孩子和*p的双亲进行连接  */
        if(p == parent->lchild) 
            parent->lchild=child; 
        else 
            parent->rchild = child; 
        
        /*  情况(3)需将*p的数据复制到*q,若还有其它数据域亦需复制  */
        if(p != q) 
            q->key = p->key;    
    } //endif

    free(p); 
    return TURE;
} 

 

 

posted @ 2014-11-11 08:45  suo_suo  阅读(257)  评论(0编辑  收藏  举报