1、順序查找c++
按索引順序查找,可用於查找無序序列性能
int SequenceSearch(vector<int> seq, int key) { const int c_len = seq.size(); for(int i=0; i<c_len; ++i) if(seq[i] == key) return i; // 找到key = seq[i] return -1; // key不在表中,查找失敗 }
時間複雜度:T(n) = θ(n)code
2、二分查找排序
待查找序列必須有序索引
過程:table
經過將待查找的值key與序列中位數比較,判斷key在左半序列仍是右半序列;而後在新的序列(左半序列或右半序列)中繼續作二分查找,直到找到或序列查找完畢class
int BinarySearch(vector<int> seq, int key) { const int c_len = seq.size(); int left = 0, right = c_len, middle; while(left < right) { middle = (left + right) / 2; if(seq[middle] == key) return middle; // 找到key = seq[middle] else if(seq[middle] > key) right = middle; // key 不會等於 seq[right] else if(seq[middle] < key) left = middle + 1; //key 可能等於 seq[left] } return -1; // key不在表中,查找失敗 }
時間複雜度:while循環次數最大爲lgn(向上取整)(以2爲底)循環
T(n) <= lgn x 常數 = O(lgn)
map
3、分塊查找tab
性能位於順序查找和二分查找中間
除了存儲待排序序列以外,還須要存儲一個索引表(鍵爲序列中的元素,對應的值爲元素所在的塊)
假設待排序序列有n個元素,將待排序序列分紅k個塊,每塊中的元素爲n/k+1(最後一塊的元素小於等於n/k+1);
這k個塊整體是有序的,即第i塊中的任意元素必定小於第i+1塊中的任意元素;
每一個塊中的元素是無序的。
步驟:先找到待查找元素key的塊索引,再在相應的塊中查找key
因爲k個塊整體有序,因此能夠使用順序查找或者二分查找來查找塊索引;
因爲塊中元素是無序的,因此只能經過順序查找在相應塊中查找key。
c++代碼:
//在seq[p~q]中順序查找key int SequenceSearch1(vector<int> seq, int key, int p, int q); // IndexSearch中使用 int BinarySearch1(vector<int> seq, int key); // IndexSearch中使用 int IndexSearch(vector<int> seq, int key, const int k) { const int c_len = seq.size(); const int max_n = c_len / k + 1; map<int, int> block_table; // black_min[i], block_index vector<int> block_min; for(int i=0; i<k; ++i) { block_table[seq[max_n*i]] = i; // 爲了方便,比第i塊最小值大,比第i+1塊最小值小的元素塊索引爲i block_min.push_back(seq[max_n*i]); //爲了方便,這裏的seq排過序了,因此每塊的最小值就是每一個塊的第一個元素 } int min_index = BinarySearch1(block_min, key); if(min_index == -1) // key<min(seq) return -1; else { int block_index = block_table[block_min[min_index]]; int index_left = block_index*max_n; int index_right = index_left + max_n; if (index_right > c_len) index_right = c_len; return SequenceSearch1(seq, key, index_left, index_right); } } int SequenceSearch1(vector<int> seq, int key, int p, int q) { for(int i=p; i<q; ++i) if(seq[i] == key) return i; return -1; } int BinarySearch1(vector<int> seq, int key) { const int c_len = seq.size(); int left = 0, right = c_len, middle; while(left < right) { middle = (left + right) / 2; if(seq[middle] <= key) if((seq[middle+1] > key) || (middle + 1 >= c_len)) return middle; else left = middle + 1; else right = middle; } return -1; }
時間複雜度:
若查找塊索引時使用二分查找,則塊索引的時間複雜度爲θ(lgk) (假設分紅k塊);若採用順序查找,則塊索引時間複雜度爲θ(k)
在塊中使用順序查找的時間複雜度爲θ(n/k)
因此T(n) = θ(n/k+lgk) 或θ(n/k+k)