854计算机基础——《数据结构与算法》考点汇总(一) 查找

一、基本概念:

1、  列表:待搜索的数据集合。

2、  关键字:要查找的那个数据。

3、  查找,检索:一种算法过程。给出一个key值(关键字),在含有若干个结点的序列中找出它。

4、  查找表:同一类型的数据元素的集合。

5、  静态查找表:查询某个元素、检索指定元素的属性。

6、  动态查找表:查找后插入、删除。

7、  查找成功:当某个元素的key值等于给定值k,返回该元素的位置。

8、  查找失败:所有元素的key值均不等于给定的值k,返回表示失败的标识。

二、基于线性表的查找:

1、  顺序查找:<适合对象:无序或有序队列>

(1)思想:逐个比较,直到找到或者查找失败。

(2)时间复杂度:T(n) = O(n)。

(3)空间复杂度:S(n) = O(n)。

(4)程序:

    Int SeqSearch(RecordList l, KeyType key)  
    {  
             l.r[0].key = k;  
             I = l.length;  
             while(l.r[i].key != k)  
                       i--;  
             return  I;  
    }  

(5)缺点:当n较大时,平均查找长度较大,效率低

2、  折半查找:<适合对象:只是适用于有序表,且限于顺序存储结构(线性链表无法进行折半查找)>

(1)思想:又称二分查找,对于已经按照一定顺序排列好的列表,每次都用关键字和中间的元素对比,然后判断是在前部分还是后部分还是就是中间的元素,然后继续用关键字和中间的元素对比。

(2)时间复杂度:T(n) =O(logn)

(3)程序:

    Int BinSrch(RecordList l, KeyType k)  
    {  
             low = 1;  
             high = l.length;  
             while(low <= high)  
             {  
                  mid = (low + high) / 2;  
                  if(k == l.r[mid].key)  
                       return mid;  
                  else if(k < l.r[mid].key)  
                       high = mid -1;  
                  else  
                       low = mid + 1;  
             }  
             return 0;  
    }  

3、  分块查找:<适合对象:块内的元素可以无序,但块之间是有序的>

(1)思想:把无序的列表分成若干子块(子表),然后建立一个索引表,记录每个子块中的某个关键字(最大的数或是最小的数),然后用关键字和这个索引表进行对比。该索引表还存储子块的起始位置,所以可以使用折半查找或者顺序查找确定关键字所在的子块位置。进入子块后,使用顺序查找查找。

(2)时间复杂度:O(logn)

(3)程序:

/**
     * 分块查找
     *
     * @param index 索引表,其中放的是各块的最大值
     * @param st 顺序表,
     * @param key 要查找的值
     * @param m 顺序表中各块的长度相等,为m
     * @return
     */
  private int BlockSearch(int[ ] index, int[ ] st, int key, int m)
    {
          //  在序列st数组中,用分块查找方法查找关键字为key的记录
         // 1.在index[ ] 中折半查找,确定要查找的key属于哪个块中 
          int i = partSearch(index, key);            
          if(i >= 0)
          {
              int j = i > 0 ? i * m : i;
              int len = (i + 1) * m;
              // 在确定的块中用顺序查找方法查找key
              for(int k = j; k < len; k++) 
              {
                  if(key == st[k])
                  {
                      System.out.println("查询成功");
                      return k;
                  }
              }
           }
          System.out.println("查找失败");
          return -1;
    }
   
    public int partSearchs(int[] data, int tmpData)
    {
        int mid;
        int low = 0;
        int high = data.length - 1;
        while(low <= high)
        {
            mid = (low + high) / 2;     // 中间位置
            if(tmpData == data[mid])
            {
                return mid;            
            }
            else if(tmpData < data[mid])    
            {
                high = mid - 1;
            }
            else
            {
                low = mid + 1;
                return low;
            }
        }
        return -1;                // 没有查找到
  }

三、基于树的查找:

1、  二叉排序树:

(1)思想:二叉排序树:①若它的左子树非空,则左子树上所有节点的值均小于它的根节点的值;②若它的右子树非空,则右子树上所有结点的值均大于(或大于等于)它的根节点的值;③它的左、右子树也分别为二叉排序树。查找的时候,中序遍历二叉树,得到一个递增有序序列。查找思路类似于折半查找。

(2)时间复杂度:插入一个节点算法的O(㏒n),插入n个的总复杂度为O(n㏒n)。

(4)程序:

BSTree SearchBST(BSTree bst, KeyType key)//递归算法  
{  
         If(!bst)  
                   return NULL;  
         else if(bst->key == key)  
                   return bst;  
         else if(bst->key > key)  
                   return SearchBST(bst->lchild, key);  
         else  
                   return SearchBST(bst->rchild, key);  
}  
BSTree SearchBST(BSTree bst, KeyType key)//非递归算法  
{  
         BSTree q;  
         q = bst;  
         while(q)  
         {  
                   If(q->key == key)  
                            return q;  
                   else if(q->key > key)  
                            q = q->lchild;  
                   else  
                            q = q->rchild;  
         }  
         return NULL;  
} 
2、  平衡二叉排序树:(略)

3、  B_树:(略)

四、计算式查找:

1、  哈希查找:

(1)思想:首先在元素的关键字k和元素的存储位置p之间建立一个对应关系H,使得p=H(k),H称为哈希函数。创建哈希表时,把关键字为k的元素直接存入地址为H(k)的单元;以后当查找关键字为k的元素时,再利用哈希函数计算出该元素的存储位置p=H(k),从而达到按关键字直接存取元素的目的。难点在于处理冲突的方式:①开放定址法②再哈希法③链地址法④建立公共溢出区。

(2)时间复杂度:O(1)

(3)程序:

#define m <哈希表长度>  
#define NULLKEY <代表空记录的关键字值>  
   
typedef int KeyType;  
typedef struct  
{  
         KeyType key;  
}RecordType;  
   
typedef RecordType HashTable[m];  
   
int HashSearch(HashTable ht, KeyType K)  
{  
         h0 = hash(K);  
         if(ht[h0].key == NULLKEY)  
                   return -1;  
         else if(ht[h0].key == K)  
                   return h0;  
         else  
         {  
                   for(i = 1; i <= m - 1; i++)  
                   {  
                            hi = (h0 + 1) % m;  
                            if(ht[hi].key == NULLKEY)  
                                     return -1;  
                            else if(ht[hi].key == K)  
                                     return hi;  
                   }  
                   return -1;  
         }  
} 







你可能感兴趣的:(查找算法)