各种排序相关题目的实现
来源:互联网 发布:网络语列表是什么意思 编辑:程序博客网 时间:2024/06/15 06:23
1. 冒泡排序
循环n次, 每次将最大值交换到最后的一个位置
class BubbleSort {public: int* bubbleSort(int* A, int n) { // write code here for (int i = 0; i != n - 1; i++){ for (int j = 0; j != n - i - 1; j++){ if (A[j] > A[j + 1]) swap(A[j], A[j + 1]); } } return A; }};
2. 选择排序
每次从剩余部分中, 挑选出最小的值, 并与相应位置上的数值进行交换
class SelectionSort {public: int* selectionSort(int* A, int n) { // write code here for (int i = 0; i != n; i++){ int minid = i; for (int j = i; j != n; j++){ if (A[j] < A[minid]){ minid = j; } } if (minid != i) swap(A[minid], A[i]); } return A; }};
3. 插入排序
每次向已经排序的序列中插入一个值, 保证插入后的数组还是排序的
class InsertionSort {public: int* insertionSort(int* A, int n) { // write code here for (int i = 0; i != n; i++){ int tmp = A[i]; for (int j = i - 1; j != -2; j--){ if (j == -1){ A[j + 1] = tmp; continue; } if (A[j] > tmp) A[j + 1] = A[j]; else{ A[j + 1] = tmp; break; } } } return A; }};
4. 归并排序
对两个子数组分别归并排序, 然后对这两个数组合并
class MergeSort {public: int* mergeSort(int* A, int n) { // write code here if (n <= 1) return A; int lenA1 = n >> 1, lenA2 = n - (n >> 1); int * A1 = mergeSort(A, lenA1); int * A2 = mergeSort(A + lenA1, lenA2); // merge int * B = new int[n]; int id1 = 0, id2 = 0, id = 0; while (id1 < lenA1 && id2 < lenA2){ if (A1[id1] < A2[id2]){ B[id++] = A1[id1++]; } else{ B[id++] = A2[id2++]; } } while (id1 < lenA1){ B[id++] = A1[id1++]; } while (id2 < lenA2){ B[id++] = A2[id2++]; } for (int i = 0; i != n; i++){ A[i] = B[i]; } return A; }};
5. 快速排序
先对原数据进行分割, 划分成 比 privot 大的和比 privot 小的部分, 然后对这两个部分分别进行快速排序
class QuickSort {public: int* quickSort(int* A, int n) { // write code here if (n <= 1) return A; int tmp = A[0]; int start = 0; int stop = n - 1; while (start < stop){ while (start < stop && A[stop] >= tmp) stop--; if (start < stop) A[start] = A[stop]; while (start < stop && A[start] < tmp) start++; if (start < stop) A[stop] = A[start]; } A[stop] = tmp; quickSort(A, stop); quickSort(A + stop + 1, n - stop - 1); return A; }};
6. 堆排序
建立一个堆, 然后对堆依次做调整
class HeapSort {public: int* heapSort(int* A, int n) { // write code here for (int i = n - 1; i != -1; i--){ modify(A, i); swap(A[i], A[0]); } return A; }private: void modify(int * A, int n){ for (int i = n; i != -1; i--){ if (A[i] > A[i / 2]) swap(A[i], A[i / 2]); } }};
7. 希尔排序
实际上就是步长因子不断减小的插入排序
class ShellSort {public: int* shellSort(int* A, int n) { // write code here for (int gap = n / 2; gap > 0; gap /= 2){ // insert sort for (int i = gap; i != n; i++){ int tmp = A[i]; for (int j = i - gap; j >= -gap; j -= gap){ if (j < 0){ A[j + gap] = tmp; continue; } if (A[j] > tmp){ A[j + gap] = A[j]; } else{ A[j + gap] = tmp; break; } } } } return A; }};
8. 计数排序
计算元素出现的次数, 然后排序
class CountingSort {public: int* countingSort(int* A, int n) { // write code here int mymax = INT_MIN, mymin = INT_MAX; for (int i = 0; i != n; i++){ if (mymax < A[i]) mymax = A[i]; if (mymin > A[i]) mymin = A[i]; } int size = mymax - mymin + 1; int * B = new int[size]; memset(B, 0, size * sizeof(int)); for (int i = 0; i != n; i++) B[A[i] - mymin]++; int id = 0; for (int i = 0; i != size; i++){ for (int j = 0; j != B[i]; j++){ A[id++] = i + mymin; } } return A; }};
9. 基数排序
基数排序内部需要用到一个稳定的排序算法, 这里偷懒, 直接使用了STL 的 stable_sort
class RadixSort{public: int* radixSort(int* A, int n) { // write code here using namespace std::placeholders; vector<int> arr(A, A + n); int mymax = *max_element(arr.begin(), arr.end()); int N = 0; while (mymax){ mymax /= 10; N++; } cout << N << endl; for (int i = 0; i != N; i++){ stable_sort(arr.begin(), arr.end(), bind(cmp, _1, _2, i)); for_each(arr.begin(), arr.end(), [](int a){cout << a << " "; }); cout << endl; } for (int i = 0; i != n; i++) A[i] = arr[i]; return A; }private: static bool cmp(int a, int b, int id){ int aa = int(a / pow(10, id)) % 10; int bb = int(b / pow(10, id)) % 10; return aa < bb; }};
10. 小范围排序
实际上是堆排序的一种应用
/*已知一个几乎有序的数组,几乎有序是指,如果把数组排好顺序的话,每个元素移动的距离可以不超过k,并且k相对于数组来说比较小。请选择一个合适的排序算法针对这个数据进行排序。给定一个int数组A,同时给定A的大小n和题意中的k,请返回排序后的数组。*/class ScaleSort {public: vector<int> sortElement(vector<int> A, int n, int k) { // write code here vector<int> myheap(A.begin(), A.begin() + k); buildHeap(myheap, k); for (int i = 0; i != n - k; i++){ A[i] = myheap[0]; myheap[0] = A[i + k]; modifyHeap(myheap, k, 0); } for (int i = 0; i != k; i++){ A[i + n - k] = myheap[0]; myheap[0] = myheap[k - 1 - i]; modifyHeap(myheap, k - i, 0); } return A; }private: void buildHeap(vector<int> & myheap, int k){ for (int i = k / 2; i >= 0; i--){ modifyHeap(myheap, k, i); } } void modifyHeap(vector<int> & myheap, int k, int pos){ while (true){ int targetid = 2 * pos + 1; if (targetid >= k) break; if (2 * pos + 2 < k && myheap[targetid] > myheap[2 * pos + 2]){ targetid = 2 * pos + 2; } if (myheap[pos] < myheap[targetid]) break; swap(myheap[targetid], myheap[pos]); pos = targetid; } }// // 递归版本的modifyHeap// void modifyHeap(vector<int> & myheap, int k, int pos){// int targetid = 2 * pos + 1;// if (targetid >= k)// return;//// if (2 * pos + 2 < k && myheap[targetid] > myheap[2 * pos + 2]){// targetid = 2 * pos + 2;// }//// if (myheap[pos] < myheap[targetid])// return;//// swap(myheap[targetid], myheap[pos]);// modifyHeap(myheap, k, targetid);// }};
11. 重复值判断
/*请设计一个高效算法,判断数组中是否有重复值。必须保证额外空间复杂度为O(1)。给定一个int数组A及它的大小n,请返回它是否有重复值。*/class Checker {public: bool checkDuplicate(vector<int> & a, int n) { // write code here buildHeap(a, n); for (int i = 0; i != n; i++){ swap(a[n - i - 1], a[0]); modifyHeap(a, n - i - 1, 0); } for (int i = 0; i != n; i++){ if (i > 0 && a[i - 1] == a[i]) return true; } return false; }private: void buildHeap(vector<int> & myheap, int k){ for (int i = k / 2; i >= 0; i--){ modifyHeap(myheap, k, i); } } void modifyHeap(vector<int> & myheap, int k, int pos){ while (true){ int targetid = 2 * pos + 1; if (targetid >= k) break; if (2 * pos + 2 < k && myheap[targetid] > myheap[2 * pos + 2]){ targetid = 2 * pos + 2; } if (myheap[pos] < myheap[targetid]) break; swap(myheap[targetid], myheap[pos]); pos = targetid; } }};
12. 有序数合并
从数组的尾部开始操作
/* 有两个从小到大排序以后的数组A和B,其中A的末端有足够的缓冲空容纳B。请编写一个方法,将B合并入A并排序。给定两个有序int数组A和B,A中的缓冲空用0填充,同时给定A和B的真实大小int n和int m,请返回合并后的数组。*/class Merge {public: int* mergeAB(int* A, int* B, int n, int m) { // write code here int ia = n - 1, ib = m - 1, id = n + m - 1; while (ib >= 0){ if (ia >= 0){ if (A[ia] >= B[ib]) A[id--] = A[ia--]; else A[id--] = B[ib--]; } else A[id--] = B[ib--]; } return A; }};
13. 三色排序
荷兰国旗问题, 三个指针区分三个数据范围{0}{1}{2}
class ThreeColor {public: vector<int> sortThreeColor(vector<int> A, int n) { // write code here int low = 0, high = n - 1, cur = 0; while (cur <= high){ if (A[cur] == 1) cur++; else if (A[cur] == 0){ if (cur != low) swap(A[cur], A[low]); cur++; low++; } else if (A[cur] == 2){ swap(A[cur], A[high]); high--; } } return A; }};
14. 有序矩阵查找
典型的杨氏矩阵查找问题, 从左上角入手
/*现在有一个行和列都排好序的矩阵,请设计一个高效算法,快速查找矩阵中是否含有值x。给定一个int矩阵mat,同时给定矩阵大小nxm及待查找的数x,请返回一个bool值,代表矩阵中是否存在x。所有矩阵中数字及x均为int范围内整数。保证n和m均小于等于1000。*/class Finder {public: bool findX(vector<vector<int> > mat, int n, int m, int x) { // write code here int i = 0, j = m - 1; while (true){ if (i >= n || j < 0) return false; if (mat[i][j] == x) return true; else if (mat[i][j] > x) j--; else i++; } return false; }};
15. 最短子数组
从左边开始找第一个下降的项位置, 从右边开始找第一个上升的项的位置
/*对于一个数组,请设计一个高效算法计算需要排序的最短子数组的长度。给定一个int数组A和数组的大小n,请返回一个二元组,代表所求序列的长度。(原序列位置从0开始标号,若原序列有序,返回0)。保证A中元素均为正整数。*/class Subsequence {public: int shortestSubsequence(vector<int> A, int n) { // write code here int left = 0, right = 1; int mymax; for (int i = 0; i != n; i++){ if (i == 0){ mymax = A[0]; } else{ if (mymax <= A[i]){ mymax = A[i]; } else{ left = i; } } } int mymin; for (int i = n - 1; i != -1; i--){ if (i == n - 1){ mymin = A[n - 1]; } else{ if (mymin >= A[i]){ mymin = A[i]; } else{ right = i; } } } return left - right + 1; }};
16. 相邻两数最大差值
利用桶排序的思想 (鸽巢原理)
/*有一个整形数组A,请设计一个复杂度为O(n)的算法,算出排序后相邻两数的最大差值。给定一个int数组A和A的大小n,请返回最大的差值。保证数组元素多于1个。*/class Gap {public: int maxGap(vector<int> A, int n) { // write code here int mymax = INT_MIN, mymin = INT_MAX; for (int i = 0; i != n; i++){ if (A[i] > mymax) mymax = A[i]; if (A[i] < mymin) mymin = A[i]; } double gap = (mymax - mymin + 0.001) * 1.0 / (n + 1); vector<vector<int>> bucks(n + 1, vector<int>{INT_MIN, INT_MAX, 0}); for (int i = 0; i != n; i++){ int id = (A[i] - mymin) / gap; bucks[id][0] = max(bucks[id][0], A[i]); bucks[id][1] = min(bucks[id][1], A[i]); bucks[id][2]++; } int maxgap = 0; int id = 0; while (id < n){ while (!bucks[id][2]) id++; int low = bucks[id][0]; id++; while (!bucks[id][2]) id++; int high = bucks[id][1]; int tmp = high - low; maxgap = max(maxgap, tmp); } return maxgap; }};
0 0
- 各种排序相关题目的实现
- 各种排序的实现
- 各种排序的实现
- 各种排序算法的实现
- C++各种排序的实现
- 各种排序算法的实现
- 各种排序的Ruby实现
- 各种排序的C++实现
- 各种排序算法的实现
- 各种排序算法的实现
- c实现的各种排序
- 各种排序的实现Java
- java实现的各种排序~
- 各种排序算法的实现
- 各种排序算法的实现
- 各种排序算法的实现
- 各种排序算法的实现
- 排序查找相关题目
- CVPR 2013 录用论文(目标跟踪部分)
- 使用autoconf和automake生成Makefile文件
- 图像处理的一个简化的磨皮算法
- java发送地址(url)如何隐藏.action
- Android ADT 离线下载技巧(告别在线安装的麻烦)
- 各种排序相关题目的实现
- Java 线程基础
- java画出爱心
- 使用boost.asio时遇到的一个小问题
- sql事务概述
- ShareSDK集成第三方登录和分享的步骤
- ScrollView中的控件占据ScrollView的match_parent
- computer vision(计算机视觉)方面的期刊会议,学术必备
- Bootstrap 初级错误导致显示空白页