二分查找
定義
對已經(jīng)排好序的數(shù)組進行查找
對數(shù)組進行操作
在查找失敗最多次數(shù)(向下取整加一)
二分查找的時間復(fù)雜度:
由于簡書不可以讀取latex公式,這里推薦到我的主頁去看。請點擊!
二分查找的代碼
int BinaryChop(int Num[],int nCount,int nValue)
{
int max_index = nCount-1;
int min_index = 0;
int Mid = 0;
while (min_index<=max_index)
{
Mid = (max_index+min_index)/2;
if(Num[Mid] == nValue)
return Mid;
if(Num[Mid]>nValue)
{
max_index = Mid-1;
}else
{
min_index = Mid+1;
}
}
return -1;
}
HashChop(哈希查找)
定義:對已經(jīng)建好散列表的數(shù)據(jù)進行查找。
哈希是查找速度最快的算法。
缺點:空間消耗非常大。
步驟
- 分析數(shù)據(jù)并定散列函數(shù)。
- 決定哈希沖突的解決辦法。
- 根據(jù)散列函數(shù)建散列表。
- 對已經(jīng)建好的散列表進行查找。
對于以上步驟第一步到第三步是建立散列表的過程。
散列函數(shù)
我們一般用求整取余法。
- 首先我們選取一個數(shù)M,這個數(shù)最好是質(zhì)數(shù)(非硬性要求),但一定比數(shù)據(jù)元素個數(shù)小,因為在同時間復(fù)雜度下占用空間最小為宜,后面會提及。
- 當M數(shù)確定下來后,我們定桶,桶為數(shù)據(jù)元素除以質(zhì)數(shù)M的各個余數(shù),也就是從0到M-1,元素除以質(zhì)數(shù)M得桶所代表的余數(shù),我們就把這個數(shù)據(jù)元素放入桶內(nèi),而且每個桶里只能放一個元素。
- 而當數(shù)據(jù)元素除以質(zhì)數(shù)M得余數(shù)相同時,由于桶內(nèi)只能放一個元素,所以當出現(xiàn)余數(shù)相同的元素時而不能放入桶內(nèi)時,就產(chǎn)生了哈希沖突。當我們解決完哈希沖突后,也就建完散列表,就可以查找了!
解決哈希沖突
- 開放地址法
- 線性探測法:在沖突位置順次后延一位放入桶內(nèi)。也就是說同為余數(shù)4的話,后來的數(shù)據(jù)就放入余數(shù)5的桶里。
- 線性補償法:首先定一個步長,遇到?jīng)_突時,按步長順次后延步長的長度放入桶內(nèi)。
- 隨機探測法:找個隨機數(shù)來當步長,解決沖突如上個辦法。
- 拉鏈法:
- 在每個桶內(nèi)建立一個頭添加的鏈表,每個桶內(nèi)裝的是相應(yīng)鏈表的頭指針,將后來的元素依次頭添加在鏈表上。
舉例圖示
例如數(shù)組{19,27,55,41,82,89,16,9,22,98,104,1,2,205,46}
HashChop
代碼
typedef struct node
{
int nValue;
int nIndex;
struct node *pNext;
}MyHash;
#define M 7
MyHash **CreateHashTable(int arr[],int nLength)
{
MyHash **pHash = NULL;
MyHash *pTemp = NULL;
int i;
int nIndex;
//申請哈希表表頭
pHash = (MyHash**)malloc(sizeof(MyHash*) * M);
memset(pHash,NULL,sizeof(MyHash*) * M);
//拉鏈法
for(i = 0;i<nLength;i++)
{
nIndex = arr[i]%M;
pTemp = (MyHash*)malloc(sizeof(MyHash));
pTemp->nIndex = i;
pTemp->nValue = arr[i];
//頭添加
pTemp->pNext = pHash[nIndex];
pHash[nIndex] = pTemp;
}
return pHash;
}
int HashChop(int arr[],int nLength,int nNum)
{
MyHash **pHash = NULL;
int nIndex;
MyHash *pMark = NULL;
if(arr == NULL || nLength <=0)
abort();
//建哈希表
pHash = CreateHashTable(arr,nLength);
//查詢
nIndex = nNum%M;
pMark = pHash[nIndex];
//遍歷鏈表
while(pMark)
{
if(pMark->nValue == nNum)
{
return pMark->nIndex;
}
else
{
pMark = pMark->pNext;
}
}
return -1;
}