一、基于线性表的查找
1、顺序查找:对关键字没有排序的线性表来说,用所给的关键字与线性表中的所有记录逐个进行比较,直到成功或是失败。
int seqlistsearch(seqlist L, int k){ int len = L.len; if (len <= 0){ cout << "没有该元素,无法查找!" << endl; } else{ while (len > 0 && L.Arry[len].key != k){ len--; } return len; } }
显然上述算法的时间消耗主要是while,if判断处。有实验表明,当查询记录超过1000条的时候,i>0这条语句的消费时间是整个算法的60%,所以我们将之改进。
int seqlistsearch2(seqlist L, int k){ L.Arry[0].key = k;//设置监视哨 int i = L.len; while (L.Arry[i].key!=k) { i--; } return i; }
这样以来,从后往前查找时候,省去了边界的判断,无论查找失败与否都能找到该条记录在查找表中的位置,如果i>0表明查找成功,i=0查找失败。
2、折半查找:(1)若果k=key,查找成功(2)若果k<key,查找元素在关键字key的前面(3)若果k>key,查找元素在关键字key的后面
int zbcz(seqlist* L,int k){
int low = 1;
int high = L->len,mid;
while (low < high){
mid = (high+ low) / 2;
if (k==L->Arry[mid].key)return mid;
else if (L->Arry[mid].key < k)low = mid + 1;
else high = mid - 1;
}
return 0;
}
折半查找是典型的分治类算法,所以算法也可以使用递归来实现。
int zbcz2(seqlist* L,int low,int high, int k){ if (low < high){ int mid = (high + low) / 2; if (L->Arry[mid].key == k){ return mid; } else if (L->Arry[mid].key < k){ return zbcz2(L, mid + 1, L->len, k); } else{ return zbcz2(L, low, mid-1, k); } } }
3、索引查找:
如果线性查找希望有较快的查找苏都,有需要动态的变化,可以使用索引查找。
索引查找分为3种:
1、稠密、稀疏索引,两者概念大体相同,只不过稠密索引是每个搜索码都对应一个索引值,稀疏一个搜索码可能对应多个索引值
2、分块索引,把数组分块,索引中记录每个块中最大的值,并把索引按max排序,块内部可无序
3、倒排索引,我代码中没有实现这个,因为这个太简单了,只需要分割文本中关键字,把关键字作为索引,数组中对应的index作为值,插到一个字符串中即可‘
1 #include<iostream> 2 #define INFINITY 65535 3 using namespace std; 4 5 struct Object{ 6 void* value; 7 int key; 8 }; 9 struct Index{ 10 int i; 11 12 13 //block index 14 int max; 15 int length; 16 void* value[5]; 17 18 //dense index 19 //int key; 20 //void* value; 21 }; 22 23 int main(){ 24 25 Object _obj[5]; 26 Index _index[5]; 27 28 //b1 29 _obj[0].key=12; 30 _obj[0].value=(void*)"i'm 12"; 31 32 //b2 33 _obj[1].key=107; 34 _obj[1].value=(void*)"i'm 107"; 35 36 _obj[2].key=36; 37 _obj[2].value=(void*)"i'm 36"; 38 39 //b3 40 _obj[3].key=18; 41 _obj[3].value=(void*)"i'm 18"; 42 43 _obj[4].key=72; 44 _obj[4].value=(void*)"i'm 72"; 45 46 //block index 47 for(int i=0;i<5;i++){ 48 _index[i].max=INFINITY; 49 } 50 51 _index[0].max=12; 52 _index[0].length=1; 53 _index[0].value[0]=&_obj[0]; 54 55 56 _index[1].max=107; 57 _index[1].length=2; 58 _index[1].value[0]=&_obj[1]; 59 _index[1].value[1]=&_obj[2]; 60 61 62 _index[2].max=72; 63 _index[2].length=2; 64 _index[2].value[0]=&_obj[3]; 65 _index[2].value[1]=&_obj[4]; 66 67 for(int i=0;i<3;i++){ 68 for(int j=1;j>=0;j--){ 69 if(_index[j].max>_index[j+1].max){ 70 swap(_index[j],_index[j+1]); 71 } 72 } 73 } 74 75 for(int i=0;i<5;i++){ 76 _index[i].i=i; 77 } 78 79 for(int i=0;i<5;i++){ 80 cout<<_index[i].i<<' '; 81 } 82 cout<<endl; 83 84 for(int i=0;i<5;i++){ 85 cout<<_index[i].max<<' '; 86 } 87 cout<<endl; 88 89 for(int i=0;i<5;i++){ 90 if(_index[i].max<INFINITY){ 91 for(int j=0;j<_index[i].length;j++){ 92 cout<<(char*)((Object*)_index[i].value[j])->value<<' '; 93 } 94 } 95 } 96 cout<<endl; 97 98 //dense index 99 /* 100 for(int i=0;i<5;i++){ 101 _index[i].key=_obj[i].key; 102 _index[i].value=&_obj[i]; 103 } 104 for(int i=0;i<5;i++){ 105 for(int j=3;j>=0;j--){ 106 if(_index[j].key>_index[j+1].key){ 107 swap(_index[j],_index[j+1]); 108 } 109 } 110 } 111 for(int i=0;i<5;i++){ 112 _index[i].i=i; 113 } 114 115 116 for(int i=0;i<5;i++){ 117 cout<<_index[i].i<<' '; 118 } 119 cout<<endl; 120 for(int i=0;i<5;i++){ 121 cout<<_index[i].key<<' '; 122 } 123 cout<<endl; 124 for(int i=0;i<5;i++){ 125 cout<<(char*)((Object*)_index[i].value)->value<<' '; 126 } 127 cout<<endl;*/ 128 129 return 0; 130 }