。
冒泡排序 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 #include "bits/stdc++.h" using namespace std;int bubbleSort (vector<int > &vec, int flag) { int temp; for (int i = vec.size ()-1 ; i > 0 ; i--){ for (int j = 0 ; j < i; j++){ if (vec[j] > vec[j+1 ] && flag == 1 ){ vec[j+1 ] = vec[j+1 ]^vec[j]; vec[j] = vec[j+1 ]^vec[j]; vec[j+1 ] = vec[j+1 ]^vec[j]; } else if (vec[j] < vec[j+1 ] && flag == 2 ){ vec[j+1 ] = vec[j+1 ]^vec[j]; vec[j] = vec[j+1 ]^vec[j]; vec[j+1 ] = vec[j+1 ]^vec[j]; } } } return 0 ; }
选择排序 1 2 3 4 5 6 7 8 9 10 11 12 13 14 int selectionSort (vector<int > &vec, int flag) { int index, j; for (int i = 0 ; i < vec.size () - 1 ; i++){ for (j = i+1 , index = i; j < vec.size (); j++){ if (vec[j] < vec[index] && 1 == flag) index = j; else if (vec[j] > vec[index] && 2 == flag) index = j; } if (i == index) continue ; vec[i] = vec[i] + vec[index]; vec[index] = vec[i] - vec[index]; vec[i] = vec[i] - vec[index]; } return 0 ; }
插入排序 1 2 3 4 5 6 7 8 9 10 int insertionSort(vector<int> &vec, int flag){//插入排序 int tmp = 0, j; for(int i = 1; i < vec.size(); i++){ tmp = vec[i]; if(1 == flag) for(j = i-1; j >= 0 && vec[j] > tmp; j--) vec[j+1] = vec[j]; else if(2 == flag) for(j = i-1; j >= 0 && vec[j] < tmp && 2 == flag; j--) vec[j+1] = vec[j]; vec[j+1] = tmp; } return 0; }
希尔排序 1 2 3 4 5 6 7 8 9 10 11 12 13 int shellSort(vector<int> &vec, int flag){ //希尔排序 int temp, j, startIndex; for(int gap = vec.size()/2; gap >= 1; gap /= 2){ for(startIndex = 0; startIndex < gap; startIndex++){ for(int i = startIndex + gap; i < vec.size(); i += gap){ if(1 == flag) for(temp = vec[i], j = i - gap; j >= 0 && vec[j] > temp; j -= gap) vec[j+gap] = vec[j]; else if(2 == flag) for(temp = vec[i], j = i - gap; j >= 0 && vec[j] < temp; j -= gap) vec[j+gap] = vec[j]; vec[j+gap] = temp; } } } return 0; }
快速排序 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 int quickSort(vector<int> &vec, int flag, int first, int end){ //快排 if(first >= end || first < 0 || end >= vec.size()) return 0; // 注意前面是 first >= end 不能是 first != end int mid_num = vec[first], i, j; for(i = first, j = end; i < j; ){ for(; i < j && vec[j] >= mid_num && 1 == flag; j--); // flag == 1 if(i < j && vec[j] < mid_num && 1 == flag) vec[i] = vec[j]; for(; i < j && vec[i] <= mid_num && 1 == flag; i++); if(i < j && vec[i] > mid_num && 1 == flag) vec[j] = vec[i]; for(; i < j && vec[j] <= mid_num && 2 == flag; j--); // flag == 2 if(i < j && vec[j] > mid_num && 2 == flag) vec[i] = vec[j]; for(; i < j && vec[i] > mid_num && 2 == flag; i++); if(i < j && vec[i] <= mid_num && 2 == flag) vec[j] = vec[i]; } vec[i] = mid_num; quickSort(vec, flag, first, i-1); quickSort(vec, flag, i+1, end); return 0; }
堆排序 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 /** * 堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。 * 左右子节点不需要满足大小关系。建好堆后,每取出堆顶值,需要重新排序一次,适合于大量数据中搜索top k */ int heapCreate(vector<int> &vec, int flag){ vec.insert(vec.begin(), 0); int temp; if(vec.size()%2 == 1){ // vec 数组包含偶数个数时(注意前面加了个0)//主要是为了把最后一个父节点处理了,他可能没有右节点 if(1 == flag && vec[vec.size()/2] > vec[(vec.size()/2)*2]){ temp = vec[(vec.size()/2)*2]; vec[(vec.size()/2)*2] = vec[vec.size()/2]; vec[vec.size()/2] = temp; } else if(2 == flag && vec[vec.size()/2] < vec[(vec.size()/2)*2]){ temp = vec[(vec.size()/2)*2]; vec[(vec.size()/2)*2] = vec[vec.size()/2]; vec[vec.size()/2] = temp; } } for(int j = vec.size() / 2 - 1; j >= 1; j--){ // 每个父节点都有左右子节点 int i = j; while(2*i < vec.size()){ if(1 == flag && (vec[i] > vec[2*i] || vec[i] > vec[2*i+1])){ if(vec[2*i] >= vec[2*i+1]){ temp = vec[2*i+1]; vec[2*i+1] = vec[i]; vec[i] = temp; i = 2*i+1; continue; } else{ temp = vec[2*i]; vec[2*i] = vec[i]; vec[i] = temp; i=2*i; continue; } } else if(2 == flag && (vec[i] < vec[2*i] || vec[i] < vec[2*i+1])){ if(vec[2*i] <= vec[2*i+1]){ temp = vec[2*i+1]; vec[2*i+1] = vec[i]; vec[i] = temp; i = 2*i+1; continue; } else{ temp = vec[2*i]; vec[2*i] = vec[i]; vec[i] = temp; i = 2*i; continue; } } break; } } return 0; } int heapGetMax(vector<int> &vec, int flag){ int res = vec[1]; int temp; vec[1] = vec[vec.size()-1]; vec.pop_back(); if(vec.size() == 1) return res; int i = 1; while(1 == flag && (2*i < vec.size()) && ((vec[i] > vec[2*i]) || ((2*i+1)>=vec.size()?0:(vec[i] > vec[2*i+1])))){ if((2*i+1)>=vec.size() || vec[2*i] < vec[2*i+1]){ temp = vec[2*i]; vec[2*i] = vec[i]; vec[i] = temp; i = 2*i; continue; } else{ temp = vec[2*i+1]; vec[2*i+1] = vec[i]; vec[i] = temp; i = 2*i + 1; continue; } break; } while(2 == flag && (2*i < vec.size()) && ((vec[i] < vec[2*i]) || ((2*i+1)>=vec.size()?0:(vec[i] < vec[2*i+1])))){ if((2*i+1)>=vec.size() || vec[2*i] > vec[2*i+1]){ temp = vec[2*i]; vec[2*i] = vec[i]; vec[i] = temp; i = 2*i; continue; } else{ temp = vec[2*i+1]; vec[2*i+1] = vec[i]; vec[i] = temp; i = 2*i+1; continue; } break; } return res; } int heapSort(vector<int> &vec, int flag){ //堆排序 vector<int> out; heapCreate(vec, flag); while(vec.size() >= 2){ out.push_back(heapGetMax(vec, flag)); } vec.swap(out); return 0; }
测试程序 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 int main(void){ vector<int> vec{7,5,9,6,4,12, 68,4,5,1,2,6,7}; //bubbleSort(vec, 2); //for(auto var : vec) cout << var << " "; //selectionSort(vec, 2); //for(auto var : vec) cout << var << " "; //insertionSort(vec, 2); //for(auto var : vec) cout << var << " "; //shellSort(vec, 2); //for(auto var : vec) cout << var << " "; //quickSort(vec, 2, 0, vec.size()-1); //for(auto var : vec) cout << var << " "; heapSort(vec, 2); for(auto var : vec) cout << var << " "; return 0; }
二分查找 可以参考这篇内容详解二分查找算法
码题集2072:
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 #include <bits/stdc++.h> using namespace std;int check (int interval, const vector<int > &pos, int target) { int pre = pos[0 ]; int cnt = 1 ; for (int i = 1 ; i < pos.size (); i++){ if (pos[i] - pre >= interval){ cnt++; pre = pos[i]; } } if (cnt == target) return 1 ; else if (cnt > target) return 2 ; else return -1 ; } int main ( ) { int N, M; cin >> N >> M; vector<int > pos (N) ; for (int i = 0 ; i < N; i++) cin>>pos[i]; sort (pos.begin (), pos.end ()); int l = 1 ; int r = (pos[pos.size ()-1 ] - pos[0 ]) / (M - 1 ) + 1 ; int mid; int res; while (l <= r){ mid = l + (r - l) / 2 ; int flag = check (mid, pos, M); if (flag == 1 ){ l = mid+1 ; res = mid; } else if (flag == 2 ){ l = mid+1 ; res = mid; } else { r = mid-1 ; } } cout<<r; return 0 ; }
链接中给出的一般二分查找是查找在数组中已有的值,拓展后可以找到左右边界。而本题中也不是找一个具体的值,而是找一个最大值,类似找右边界,代码也是类似的。
二分查找和排序有共同点,进行循环查找前,都需要先明确是左闭右闭或者是其他。根据这个,每次左边界,右边界变化情况不同,并且跳出循环后,左右边界代表的意义也不同。本代码中,是左闭右闭,while循环条件需要是等于,因为哪怕是l == r时,都还有个区间[l, r]的值没进行判断,跳出循环的条件是l = r+1(肯定不会是l = r+2之类的,不要钻牛角尖,仔细想想)。最后一次check值返回1,2时的mid就应该是最终的结果,可以用个res保存。最后l会被赋值为mid+1。故最终 l-1 即为结果。又因为l = r + 1,r也是最终结果。