*个人学习笔记*
查 找
1. 顺序查找
int seqsearch(DataType R[], KeyType key)
{
R[0].key = key, i = n;
while (R[i].key != key) --i;
return i;
}
2. 折半查找
int BinarySearch(DataType SL[], KeyType key, int n)
{
int low = 1;
int high =1;
while (low <= high)
{
mid = (low + high)/2;
if (key == SL[mid].key) return mid;
else if (key > SL[mid].key) low = mid + 1;
else high = mid -1;
}
return 0;
}
3. 索引表的顺序查找算法
typedef struct IndexType
{
KeyType key;
int Link;
}IndexType;
int IndexSequelSearch(IndexType ls[], DataType s[], int m, KeyType key)
{
i = 0;
while (i < m && Key > ls[i].key) i++; //块间查找
if (i == m) return -1; //查找失败
else //在块内顺序查找
{
j = ls[i].Link;
while (Key != s[j].key && j < ls[i+1].Link) j++;
if (key == s[j].key) return j; //查找成功
else return -1; //查找失败
}
}
4. 哈希查找
(1)常见的哈希函数
- 直接哈希函数:线性函数
- 数字分析法:H(key) = “key中数字均匀分布的s位”
- 平方取中法:H(key) = “key^2的中间几位”
- 折叠法:关键字位数特别多
- 除留余数法:H(key) = “key MOD p (p<=m)”
- 随机数法:H(key) = random(key)
(2)处理冲突的方法
- 开放地址法:为产生冲突的地址H(key)求得一个地址序列。
H0, H1, H2, …, Hs
1≤ s≤m-1
其中:H0 = H(key) Hi = ( H(key) + di ) MOD m i=1, 2, …, s
其中: Hi 为第i次冲突的地址,i=1, 2, …, s H(key)为Hash函数值 m 为Hash表表长 di 为增量序列
对增量 di 有三种取法:
1) 线性探测再散列 di= c*i 最简单的情况 c=1
2) 平方探测再散列 di= 1^2, -1^2, 2^2, -2^2, …
或者di=1^2,2^2,3^2,…
3) 随机探测再散列 di是一组伪随机数列
再哈希法:
将n个不同哈希函数排成一个序列, 当发生冲突时, 由RHi确定 第i次冲突的地址Hi。即: Hi =RHi (key) i=1, 2, …, n
其中:RHi 为不同哈希函数 这种方法不会产生“聚类”,但会增加计算时间。链地址法:
将所有哈希地址相同的记录都链接在同一链表中。- 公共溢出法:
•假设某哈希函数的值域[0, m-1],
•向量HashTable[0, m-1]为基本表,每个分量存放一个记录,另设一 个向量OverTable[0, v]为溢出表。将与基本表中的关键字发生冲突的 所有记录都填入溢出表中。
(3)哈希查找过程
在哈希表上查找的过程和哈希造表的构造过程基本一致。
1)给定K值,根据构造表时所用的哈希函数求哈希地址j,
2)若此位置无记录, 则查找不成功; 否则比较关键字,若和给定的关键字相等则成功; 否则根据构造表时设定的冲突处理的方法计算“下一地址”,重复2)