查找的基本方法可以分为两大类:即比较式查找法和计算式查找法。其中比较式查找法根据数据元素的组织结构又可以分为:基于线性表的查找法和基于树的查找法;计算式查找法也称为哈希查找法。
1.基于线性表的查找法
1)顺序查找
顺序查找法的特点:用所给关键字与线性表中的各元素的关键字比较,直到查找成功或者失败。存储结构:顺序结构或者链式结构。
顺序结构数据类型的定义:
#define LIST_SIZE 20
typedef struct {
KyeType key;
OtherType other_data;
} RecordType;
typedef struct {
RecordType r[LIST_SIZE + 1];
int length;
} RecordList;
算法思想:
在表的一端设置一个称为“监视哨”的附加单元,存放要查找的关键字。从表的另一端开始查找,如果在“监视哨”找到要查找的关键字,那么返回失败信息,否则返回相应的下标。
算法:
int SeqSearch(RecordList l, KeyType k) {
l.r[0].key = k;
int i = l.length;
while (l.r[i].key != k) i--;
return i;
}
运行测试实例代码:
#import <Foundation/Foundation.h>
#define LIST_SIZE 5
typedef struct {
char *key;
int data;
} RecordType;
typedef struct {
RecordType r[LIST_SIZE + 1];
int length;
} RecordList;
int SeqSearch(RecordList l, char *k) {
l.r[0].key = k;
int i = l.length;
while (l.r[i].key != k) i--;
return i;
}
int main(int argc, const char * argv[]) {
@autoreleasepool {
RecordType rt0, rt1, rt2, rt3, rt4, rt5;
rt0.key = "key";rt0.data = 0;
rt1.key = "BB";rt1.data = 2;
rt2.key = "AA";rt2.data = 1;
rt3.key = "CC";rt3.data = 3;
rt4.key = "EE";rt4.data = 5;
rt5.key = "DD";rt5.data = 4;
RecordList rl;
RecordType rts[6] = {rt0, rt1, rt2, rt3, rt4, rt5};
//拷贝数组到RecordList的数组中
memcpy(rl.r, rts, 6 * sizeof(RecordType));
rl.length = 5;
int position = SeqSearch(rl, "CC");
NSLog(@"test the result :%d", position);
}
return 0;
}
输出结果:
算法分析:平均查找长度 :1/2(n + 1);
2)折半查找
折半查找法又称为二分查找法,这种方法要求待查表要满足两个要求:(1)必须采用顺序存储结构;(2)必须按关键字大小有序排列。
算法思想:将表中间位置纪录的关键字与要查找的关键字比较,如果两者相等,则查找成功;否则利用中间位置纪录奖表分为前后两个子表,如果中间位置纪录的关键字大于查找关键字,则进一步查找查找前一子表,否则,查找后一子表。
重复上面的过程,直到找到满足条件的纪录,查找成功,或则直到子表不存在为止,查找失败。
运行测试实例代码:
int BinSearch (int array[], int key, int arrayLength) {
int low = 0;
int high = arrayLength - 1;
int mid = (low + high) / 2;
while (low <= high) {
if (array[mid] == key) {
return mid;
} else if (array[mid] > key) {//在前一子表中查找
high = mid - 1;
mid = (low + high) / 2;
} else {//在后一子表中查找
low = mid + 1;
mid = (low + high) / 2;
}
}
return 0;
}
int main(int argc, const char * argv[]) {
@autoreleasepool {
// insert code here...
int searchArray[7] = {1, 3, 5, 6, 8, 10, 11};
int searchArrayLength = 7;
int result1 = BinSearch(searchArray, 3, searchArrayLength);
NSLog(@"the key is 3, and the position of search result is %d", result1);
int result2 = BinSearch(searchArray, 6, searchArrayLength);
NSLog(@"the key is 6, and the position of search result is %d", result2);
int result3 = BinSearch(searchArray, 7, searchArrayLength);
NSLog(@"the key is 7, and the position of search result is %d", result3);
}
return 0;
}
运行结果:
折半查找方法的优点:比较次数少,查找速度快,平均性能好,其缺点是要求待查找的表为有序表,并且插入和删除比较困难。因此折半查找适用于不经常变动,查找频繁的有序表。