您好,登錄后才能下訂單哦!
一、順序搜索法
由于不知道要查找元素的具體位置,只能一個元素一個元素的去判斷。
平均查找(n+1)/2
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;
}
二、折半查找
對于一個有序數(shù)組,我們就可以通過二分查找的方法來提高查找效率。時間復雜度O(lgn)
二分查找有兩種寫法,需要特別注意邊界。
(1)左閉右閉[left,right]
也就是left = 0, right = n-1。這時的判斷條件時left < right。并且當去一邊的時候要mid+1或mid-1
int search(int array[], int n, int v)
{
int left, right, middle;
left = 0, right = n - 1; //左閉右閉
while (left <= right){ //循環(huán)條件
middle = (left + right) / 2;
if (array[middle] > v){
right = middle - 1; //由于middle不符合,所有要middle-1滿足右閉
}
else if (array[middle] < v){
left = middle + 1; //同上,滿足左閉
}
else{
return middle;
}
}
return -1;
}
(2)左閉右開[left,right)
也就是left = 0,right = n。這時不相等時,有l(wèi)eft = mid+1 或 right = mid;
int search4(int array[], int n, int v)
{
int left, right, middle;
left = 0, right = n; //左閉右開
while (left < right){ //判斷條件,由于是開,就必須不能相等
middle = (left + right) / 2;
if (array[middle] > v){
right = middle; //滿足右開
}
else if (array[middle] < v){
left = middle + 1; //滿足左閉
}
else{
return middle;
}
}
return -1;
}
在循環(huán)體內(nèi),計算中間位置的時候,使用的是這個表達式:
middle = (left + right) / 2;
假如,left與right之和超過了所在類型的表示范圍的話,那么middle就不會得到正確的值.
所以,更穩(wěn)妥的做法應該是這樣的:
middle = left + (right - left) / 2;
三、搜索二叉樹
上面的查找是建立在連續(xù)內(nèi)存基礎之上的,那么如果是指針類型的數(shù)據(jù)呢?怎么辦呢?那么就需要引入排序二叉樹了。排序二叉樹的定義很簡單:(1)非葉子節(jié)點至少一邊的分支非NULL;(2)葉子節(jié)點左右分支都為NULL;(3)每一個節(jié)點記錄一個數(shù)據(jù),同時左分支的數(shù)據(jù)都小于右分支的數(shù)據(jù)??梢钥纯聪旅娴亩x:
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);
}
四、哈希表法-----鏈式查找,相同映射的,放在一個鏈表中
我們看到(2)、(3)都是建立在完全排序的基礎之上,那么有沒有建立在折中基礎之上的查找呢?有,那就是哈希表。哈希表的定義如下:1)每個數(shù)據(jù)按照某種聚類運算歸到某一大類,然后所有數(shù)據(jù)鏈成一個鏈表;2)所有鏈表的頭指針形成一個指針數(shù)組。這種方法因為不需要完整排序,所以在處理中等規(guī)模數(shù)據(jù)的時候很有效。其中節(jié)點的定義如下:
typedef struct _LINK_NODE
{
int data;
struct _LINK_NODE* next;
}LINK_NODE;
那么hash表下面的數(shù)據(jù)怎么查找呢?
LINK_NODE* hash_find(LINK_NODE* array[], int mod, int data)
{
int index = data % mod;
if(NULL == array[index])
return NULL;
LINK_NODE* pLinkNode = array[index];
while(pLinkNode){
if(data == pLinkNode->data)
return pLinkNode;
pLinkNode = pLinkNode->next;
}
return pLinkNode;
}
hash表因為不需要排序,只進行簡單的歸類,在數(shù)據(jù)查找的時候特別方便。查找時間的大小取決于mod的大小。mod越小,那么hash查找就越接近于普通查找;那么hash越大呢,那么hash一次查找成功的概率就大大增加。
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。