日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

查找算法总结

發布時間:2025/3/20 编程问答 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 查找算法总结 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

只要打開電腦,就會涉及查找技術。如硬盤中文件搜索,瀏覽器中的搜索“關鍵字key”等,無論是數據庫,還是普通的ERP系統,查找功能數據處理的一個基本,同時也是一個非常重要的功能。所有這些需要被查找數據的集合,統稱為“查找表”。數據查找并不復雜,但是如何實現數據又快又好地查找呢?前人在實踐中積累的一些方法,值得我們好好學些一下。我們假定查找的數據唯一存在,數組中沒有重復的數據存在。
我們如何在查找表里面找到我們想要的那個數據。此時數據本身沒有特征,所以我們需要的那個數據可能出現在數組的各個位置,可能在數據的開頭位置,也可能在數據的結束位置。這種性質要求我們必須對數據進行遍歷之后才能獲取到對應的數據。

(1) 普通的順序查找(無序查找)

順序查找(Sequential Search)又叫線型查找,是基本的查找技術。其基本過程是:從查找表中的第一個(或者最后一個)記錄開始,逐個進行給定值與關鍵字的比較,若相等則查找成功;如果直到最后一個(或者第一個)記錄,關鍵字和給定值不等,則查找不成功.

[cpp] view plain copy int find(int array[], int length, int value) { if(NULL == array || 0 == length) return -1; for(int index = 0; index < length; index++){ if(value == array[index]) return index; } return -1; }

由于每次循環時都要對index是否越界,即是否小于等于length做判斷,因此我們可以通過設置哨兵進行改進。

int find(int array[], int length, int value) { if(NULL == array || 0 == length) return -1; int i = length;array[0] = value; //注意此時數組存儲在array[1]到array[length]中while(array[i]!= key)//循環從尾部開始i--;return i; //返回0則說明查找失敗 }

此時代碼從尾部開始查找,由于array[0] = value,也就是說如果在array[i]有key則返回i值,查找成功,否則一定在最終的array[0]處等于value,此時返回的是0,即說明array[1]-array[length]中沒有關鍵字value,查找失敗。

分析:對于順序查找而言,最好的情況是要查找的值在第一個位置就找到了,算法時間復雜度為O(1),最壞的情況是遍歷所有元素,需要n次,時間復雜度為O(n),由于關鍵字出現在任何一個位置上的概率是相等的,因此平均查找次數為(n+1)/2,所以時間復雜度是O(n)。當n很大時,查找效率極為低下,由于這個算法簡單,對靜態查找表的記錄沒有任何要求,在一些小型數據的查找時,可以使用。

(2)有序表查找

如果數據排列地非常整齊,那結果會是什么樣的呢?就像在生活中,如果平時 不注意收拾整齊,那么找東西的時候非常麻煩,效率很低;但是一旦東西放的位置固定下來,所有東西都歸類放好,那么結果就不一樣了,我們就會形成思維定勢,這樣查找東西的效率就會非常高。下面我們介紹幾種方法:

二分法查找: int binary_searcht(int array[], int length, int value) { if(NULL == array || 0 == length) return -1; int start = 0; int end = length -1; while(start <= end){ int middle = start + ((end - start) >> 1); if(value == array[middle]) return middle; else if(value > array[middle]){ start = middle + 1; }else{ end = middle -1; } } return -1; }

分析::查找最好情況是1次,最壞情況是需要log(n+1)/log(2),即時間復雜度為O(logn),理論證明見《算法導論》.

  • 插值查找
    其思想與折半查找較為相似,根據要查找的關鍵字value與查找表中最大最小記錄的關鍵字比較后的查找方法,由于是在有序表中查找,例如是在升序的表中查找,對于一個較小的值我們自然想到在查找表前面部分進行查找,因此我們將上述middle語句更改為:
    middle = start+(end - start)*(value-array[start])/(array[end] - array[start]);即可,這里不再贅述。
  • 斐波那契額查找
    相對于折半查找,一般將待比較的value值與第mid=(low+high)/2位置的元素比較,比較結果分三種情況
    1)相等,mid位置的元素即為所求
    2)> ,low=mid+1;
    3) < ,high=mid-1;
    斐波那契查找與折半查找很相似,他是根據斐波那契序列的特點對有序表進行分割的。他要求開始表中記錄的個數為某個斐波那契數小1,即
    n=F(m)-1;開始將k值與第F(k-1)位置的記錄進行比較(mid=low+F(k-1)-1),比較結果也分為三種:
    1)相等,mid位置的元素即為所求
    2)> ,low=mid+1,k-=2;
    (說明:low=mid+1說明待查找的元素在[mid+1,hign]范圍內,k-=2 說明范圍[mid+1,high]內的元素個數為n-(F(k-1)) = Fk-1-F(k-1) =Fk-F(k-1)-1=F(k-2)-1個,所以可以遞歸的應用斐波那契查找)
    3)< ,high=mid-1,k-=1;
    說明:low=mid+1說明待查找的元素在[low,mid-1]范圍內,k-=1 說明范圍[low,mid-1]內的元素個數為F(k-1)-1 個,所以可以遞歸 的應用斐波那契查找
    斐波那契查找的核心是:
    1)當key=a[mid]時,查找成功;
    2)當key
  • // 斐波那契查找.cpp #include "stdafx.h" #include <memory> #include <iostream> using namespace std; const int max_size=20;//斐波那契數組的長度 /*構造一個斐波那契數組*/ void Fibonacci(int * F) { F[0]=0; F[1]=1; for(int i=2;i<max_size;++i) F[i]=F[i-1]+F[i-2]; } /*定義斐波那契查找法*/ int Fibonacci_Search(int *a, int n, int key) //a為要查找的數組,n為要查找的數組長度,key為要查找的關鍵字 { int low=0; int high=n-1; int F[max_size]; Fibonacci(F);//構造一個斐波那契數組F int k=0; while(n>F[k]-1)//計算n位于斐波那契數列的位置 ++k; int * temp;//將數組a擴展到F[k]-1的長度 temp=new int [F[k]-1]; memcpy(temp,a,n*sizeof(int)); for(int i=n;i<F[k]-1;++i) temp[i]=a[n-1]; while(low<=high) { int mid=low+F[k-1]-1; if(key<temp[mid]) { high=mid-1; k-=1; } else if(key>temp[mid]) { low=mid+1; k-=2; } else { if(mid<n) return mid; //若相等則說明mid即為查找到的位置 else return n-1; //若mid>=n則說明是擴展的數值,返回n-1 } } delete [] temp; return -1; } int _tmain(int argc, _TCHAR* argv[]) { int a[] = {0,16,24,35,47,59,62,73,88,99}; int key=100; int index=Fibonacci_Search(a,sizeof(a)/sizeof(int),key); cout<<key<<" is located at:"<<index; system("PAUSE"); return 0; }

    分析:關于斐波那契查找, 如果要查找的記錄在右側,則左側的數據都不用再判斷了,不斷反復進行下去,對處于當眾的大部分數據,其工作效率要高一些。所以盡管斐波那契查找的時間復雜度也為O(logn),但就平均性能來說,斐波那契查找要優于折半查找。可惜如果是最壞的情況,比如這里key=1,那么始終都處于左側在查找,則查找效率低于折半查找。
    還有關鍵一點,折半查找是進行加法與除法運算的(mid=(low+high)/2),插值查找則進行更復雜的四則運算(mid = low + (high - low) * ((key - a[low]) / (a[high] - a[low]))),而斐波那契查找只進行最簡單的加減法運算(mid = low + F[k-1] - 1),在海量數據的查找過程中,這種細微的差別可能會影響最終的效率。

    (3)二叉搜索樹

    二叉搜索樹或者是一棵空樹或者有下列性質:
    1.若左子樹不為空,則左子樹上的所有結點的值均小于根節點的值
    2.若右子樹不為空,則右子樹上的所有結點的值均大于根節點的值
    3.它的左右子樹也分別為二叉搜索樹

    二叉樹定義: typedef struct _NODE { int data; struct _NODE* left; struct _NODE* right; }NODE; 查找過程如下: const NODE* find_data(const NODE* pNode, int data){ if(NULL == pNode) return NULL; if(data == pNode->data) return pNode; else if(data < pNode->data) return find_data(pNode->left, data); else return find_data(pNode->right, data); }

    分析:若果二叉樹是比較平衡的,即其深度與完全二叉樹相同,那么查找的時間復雜度為O(logn),近似于折半查找,最壞的情況下是斜樹,查找時間復雜度是O(n),對于二叉搜索樹的其它諸如插入(insert),刪除(delete)操作,在其它博客中有,可自行查找。
    另外還有AVL樹,多路查找樹(B樹),以及散列表查找(哈希表)另有單獨博客講解。

    總結

    以上是生活随笔為你收集整理的查找算法总结的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。