数据结构与算法(查找)1

1 线性表的查找

1.1顺序查找法

算法如下:
# define LISTSZE 20
typedef struct
{
KetType key;     //关键字域
.......                  //其他域
}ElemType;
typedef struct
{
        ElemType r[LISTSIZE+1];
        int length;
}STable;
查找过程:
int SearchSeq(STable st,KeyType k)
//在顺序表中查找关键字等于k的元素,若找到则函数值为该元素在表中的位置,否则为0
{
     int i;
     st.[0].key=k;
     i=st.length;
     while(st.r[i].key!=k) i--;
     return 0;
}

ASL=1/2(n+1)

1.2 折半查找法

算法:
int Binsearch(Stable st,KeyType)
//在有序表中st中折半查找器关键字等于key的元素,若找到则函数值为该元素在表中的位置
{
   int low,high,mid;
   low=1;high=st.length;
   while(low<=high)
       {
             mid=(low+high)/2;
             if(key==st.r[mid].key) return(mid);
             else
                 if(key<st.r[mid].key)
                       high=mid-1;
                 else 
                       low=mid+1;
       }
     return(0);
}
ASL=log 2 (n+1)-1


2 树的查找

2.1 二叉排序树
typedef struct node
{
          KeyType key;
          struct node*lchild,*rchild;
}BSTNode,*BSTee;

查找算法:
BSTree SearchBST(BSTree bt, KeyType key)
//在根指针bt所指二叉树排列数中,查找关键字等于key的元素,若查找成功则返回指向该元素的指针,否则则返回空指针
{
     if(!bt) return NULL;
     else if(bt->key==key) return bt;
           else
           if(key<bt->key)
                return SearchBST(bt->lchild,key);
           else
                return SearchBST(bt->rchild,key);
}
2.2二叉排序树的插入
算法:
void InsertBST(BSTree*bt,KeyType key)
{
     BSTree s;
     if(*bt==NULL)
     {
         s=(BSTree)malloc(sizeof)(BSTNode));
         s->key=key;
         s->lchild=NULL;s->rchild=NULL;
          *bt=s;
     }
     else
       if(key<(*bt)->key)
               InsertBST(&((*bt)->lchild),key);
       else if(key>(*bt)->key)
               InsertBST(&((*bt)->rchild),key);
}

      如果给定一个元素序列,可以利用二叉树排序的插入算法,动态构造一棵二叉排序树。
首先,将二叉排序树初始化为一棵空树,然后逐个读入元素,每读入一个元素,就建立一
个新的结点,并插入到当前已生成的二叉排序树中,即调用上述二叉排序树的插入算法将
新结点插入。假设KeyType为整型,构造二叉排序树的算法如下:

void CreateBST(BSTree *bt)
//从键盘输入元素值,建立相应二叉排序树
{
      KeyType key;
      *bt=NULL;
      scanf("%d",&key);
      while(key!=ENDKEY)
          {
               InsertBST(bt,key);
               scanf("%d",&key);
          }
}

 2.3二叉排序树的删除

在二叉排序树中删除一个结点,不能将该结点为根的子树全部删除,只能删除该结点并使得二叉树依然满足二叉排序树的性质。
设删除的结点为p,结点p的双亲为f,并假设p是f的左孩子(右孩子)可分三种情况:
(1)p为叶结点,则可直接将其删除:
f->lchild=NULL;free(p);
(2)p结点只有左子树或右子树,则p的左子树或右子树直接改为其双亲结点f的左子树
f->lchild=p->lchild或f->lchild=p->rchild;
free(p);
(3)p既有左子树也有右子树
1>首先找到p结点在二叉排序树中序遍历序列中的直接前驱s结点(无右子树),然后将p的左子树改为f的左子树,而将p的右子树改为s的右子树。
2>首先找到p结点在二叉排序树中序遍历序列中的直接前驱s结点,q为s结点的双亲。利用s结点的值代替p结点的值,原s结点的左子树改为s结点
的双亲q的右子树,再将s结点删除。

三种方法综合算法如下:
<pre name="code" class="cpp">BSTree DelBST(BSTree bt,KeyType k)
{
     BSTree p,f,s,q;
     p=bt; f=NULL;
     while(p)
          {
              if(p->key==k) break;
                   f=p;
                   if(p->key>k) p=p->lchild;
                   else p=p->rchild;
           }
        if(p==NULL)  return bt;
        if(p->lchild&&p->rchild)   //左右子树不为空
        {
            q=p; s=p->lchild;
             while(s->rchild)
             {
                 q=s;
                  s=s->rchild;
              }
            p->key=s->key;
            if(q!=p) q->rchild=s->lchlid;
            else q->lchild=s->lchild;
            free(s);
          else
             {
                if(!p->rchild)
                     {q=p;p=p->lchild;}
                else
                     {q=p;p=p->rchild;}
                if(!f) bt=p;
                else
                if(q==f->lchild) f->lchild=p;
                else f->rchild=p;
                  free(q);
                 }
        return bt;
}

                  
                        


 
 










                




















  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值