排序算法习题汇总
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了排序算法习题汇总相关的知识,希望对你有一定的参考价值。
1.冒泡排序
对于一个int数组,请编写一个冒泡排序算法,对数组元素排序。
给定一个int数组A及数组的大小n,请返回排序后的数组。
[1,2,3,5,2,3],6
[1,2,2,3,3,5]
class BubbleSort { public: int* bubbleSort(int* A, int n) { // write code here for(int i=0;i<n-1;i++){ int k=0; for(int j=0;j<n-i-1;j++){ if(A[j]>A[j+1]){ k=A[j]; A[j]=A[j+1]; A[j+1]=k; } } } return A; } };
2.选择排序
对于一个int数组,请编写一个选择排序算法,对数组元素排序。
给定一个int数组A及数组的大小n,请返回排序后的数组。
[1,2,3,5,2,3],6
[1,2,2,3,3,5]
class SelectionSort { public: int* selectionSort(int* A, int n) { // write code here for(int i=0;i<n;i++){ int min=A[i]; for(int j=i+1;j<n;j++){ if(A[j]<A[i]){min=A[i];A[i]=A[j];A[j]=min;} } } return A; } };
3.插入排序
对于一个int数组,请编写一个插入排序算法,对数组元素排序。
给定一个int数组A及数组的大小n,请返回排序后的数组。
[1,2,3,5,2,3],6
[1,2,2,3,3,5]
class InsertionSort { public: int* insertionSort(int* A, int n) { // write code here for(int i=1;i<n;i++) { int min=0; for(int j=i;j>0;j--){ if(A[j]<A[j-1]){ min=A[j]; A[j]=A[j-1]; A[j-1]=min; } } } return A; } };
4.归并排序
对于一个int数组,请编写一个归并排序算法,对数组元素排序。
给定一个int数组A及数组的大小n,请返回排序后的数组。
[1,2,3,5,2,3],6
[1,2,2,3,3,5]
class MergeSort { public: int* mergeSort(int* A, int n) { // write code here mergeSort(A,0,n-1); return A; }
//划分区间 void mergeSort(int* &A,int start,int end) { if(start==end)return; int mid=(start+end)/2; mergeSort(A,start,mid); mergeSort(A,mid+1,end); Sort(A,start,mid,mid+1,end); }
//排序 void Sort(int* &A,int a,int b,int c,int d) { int i=b,j=d; int len=d-a; int k=d-a+1; int temp[k]; while(i>=a&&j>=c) { if(A[i]>A[j]) {temp[len--]=A[i--];} else{temp[len--]=A[j--];} } while(i>=a)temp[len--]=A[i--]; while(j>=c)temp[len--]=A[j--]; for(int f=0;f<k;f++) A[a+f]=temp[f]; } };
5.快速排序
对于一个int数组,请编写一个快速排序算法,对数组元素排序。
给定一个int数组A及数组的大小n,请返回排序后的数组。
[1,2,3,5,2,3],6
[1,2,2,3,3,5]
class QuickSort { public: int* quickSort(int* A, int n) { // write code here Sort(A,0,n-1); return A; }
//不断的把大的往右,小的往左,小划分,嵌入递归小排 void Sort(int* &A,int start,int end) { if(start>=end)return; int i=start; int j=end; int k=A[i]; while(i<j) { while(i<j&&A[j]>k){j--;} if(i<j){A[i]=A[j];i++;} while(i<j&&A[i]<k){i++;} if(i<j){A[j]=A[i];} A[i]=k; Sort(A,start,i-1); Sort(A,i+1,end); } } };
6.堆排序
对于一个int数组,请编写一个堆排序算法,对数组元素排序。
给定一个int数组A及数组的大小n,请返回排序后的数组。
[1,2,3,5,2,3],6
[1,2,2,3,3,5]
class HeapSort { public: void swap(int* A,int a,int b) { int temp = A[a]; A[a] = A[b]; A[b] = temp; } public: void adjust_heap(int* A, int i, int n) { int left = 2*i+1; int right = 2*i+2; int max_id = i; if (i>n)return; if ((left<n)&&(A[left]>A[max_id]))max_id = left; if ((right<n)&&(A[right]>A[max_id]))max_id = right; if (max_id !=i) { swap(A, max_id,i); adjust_heap(A,max_id, n); } } public: void build_heap(int* A,int n) { for (int i=(n-2)/2;i>=0;i--) { adjust_heap(A, i, n); } } public: int* heapSort(int* A,int n) { // write code here build_heap(A, n); for (int i=n-1;i>0;i--) { swap(A, 0, i); adjust_heap(A,0,i); } return A; } };
7.希尔排序
对于一个int数组,请编写一个希尔排序算法,对数组元素排序。
给定一个int数组A及数组的大小n,请返回排序后的数组。保证元素小于等于2000。
[1,2,3,5,2,3],6
[1,2,2,3,3,5]
class ShellSort { public: void swap(int* A,int a,int b){ int temp=A[a]; A[a]=A[b]; A[b]=temp; } public: void shell_sort(int *A,int step,int n){ for(int i=0;i<n-step;i+=step){ for(int j=0;j<n-step;j+=step){ if(A[j]>A[j+step])swap(A,j,j+step); } } } int* shellSort(int* A, int n) { // write code here for(int i=n-1;i>0;i--){ shell_sort(A,i,n); } return A; } };
8.计数排序
对于一个int数组,请编写一个计数排序算法,对数组元素排序。
给定一个int数组A及数组的大小n,请返回排序后的数组。
[1,2,3,5,2,3],6
[1,2,2,3,3,5]
class CountingSort { public: int* countingSort(int* A, int n) { // write code here int temp[1000]={0}; for(int i=0;i<n;i++){ temp[A[i]]++; } int count_index=0; for(int j=0;j<1000;j++){ if(temp[j]!=0){ for(int i=0;i<temp[j];i++){ A[count_index]=j; count_index++;} } } return A; } };
9.基数排序
对于一个int数组,请编写一个基数排序算法,对数组元素排序。
给定一个int数组A及数组的大小n,请返回排序后的数组。保证元素均小于等于2000。
[1,2,3,5,2,3],6
[1,2,2,3,3,5]
class RadixSort { public: int data_dot(int data,int dot_position){ return (int)(data/pow(10,dot_position-1))%10; } void Radix_sort(int* A,int dot_position,int n){ int temp[10][2000]={0}; int index=0; for(int i=0;i<n;i++){ int test= data_dot(A[i],dot_position); temp[test][A[i]]++; } int new_index=0; for(int j=0;j<10;j++){ for(int k=0;k<2000;k++){ if(temp[j][k]!=0){ for(int q=0;q<temp[j][k];q++){A[new_index++]=k;} } } } } int* radixSort(int* A, int n) { // write code here for(int i=1;i<5;i++){ Radix_sort(A,i,n); } return A; } };
综合排序练习:
1.(小范围排序)
已知一个几乎有序的数组,几乎有序是指,如果把数组排好顺序的话,每个元素移动的距离可以不超过k,并且k相对于数组来说比较小。请选择一个合适的排序算法针对这个数据进行排序。
给定一个int数组A,同时给定A的大小n和题意中的k,请返回排序后的数组。
[2,1,4,3,6,5,8,7,10,9],10,2
返回:[1,2,3,4,5,6,7,8,9,10]
class ScaleSort { public: void adjustHeap(vector<int> &B, int p, int k){ int l = 2 * p + 1; int r = l + 1; while (l < k){ if (r < k){ //有右孩子 if (B[l] < B[p] && B[l] <= B[r]){ swap(B[p],B[l]); p = l; } else if (B[r] < B[p] && B[r] <= B[l]){ swap(B[p], B[r]); p = r; } else{ break; //不用交换,堆顶已经最大了 } } else{ if (B[l] < B[p]){ swap(B[p], B[l]); p = l; } else{ break; } } l = p * 2 + 1; r = l + 1; } } void buildHeap(vector<int> & B, int k){ for (int i = k-1; i>=0; i--){ adjustHeap(B,i, k); } } vector<int> sortElement(vector<int> A, int n, int k) { // write code here int sz = n - k + 1; vector<int> B(A.begin(), A.begin() + k); buildHeap(B, k); int i; for ( i = 1; i<sz; i++){ A[i - 1] = B[0]; B[0] = A[i+k-1]; adjustHeap(B, 0,k); } //最后加一个k的堆排序 i = n - k; for (int j=1; i < n; i++,j++){ A[i] = B[0]; swap(B[k-j], B[0]); adjustHeap(B, 0, k - j); } return A; } };
2.(重复值判断)
请设计一个高效算法,判断数组中是否有重复值。必须保证额外空间复杂度为O(1)。
给定一个int数组A及它的大小n,请返回它是否有重复值。
[1,2,3,4,5,5,6],7
返回:true
class Checker { public: bool checkDuplicate(vector<int> a, int n) { // write code here int temp[10000]={0}; for(int i=0;i<n;i++){ temp[a[i]]++; } for(int j=0;j<10000;j++){ if(temp[j]>=2)return true; } return false; } };
3.(有序数组结合)
有两个从小到大排序以后的数组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 while(m!=0){ if(n==0){A[m-1]=B[m-1];m--;} else{ if(A[n-1]>B[m-1]){A[m+n-1]=A[n-1];n--;} else{A[m+n-1]=B[m-1];m--;} } } return A; } };
4.(三色排序)
有一个只由0,1,2三种元素构成的整数数组,请使用交换、原地排序而不是使用计数进行排序。
给定一个只含0,1,2的整数数组A及它的大小,请返回排序后的数组。保证数组大小小于等于500。
[0,1,1,0,2,2],6
返回:[0,0,1,1,2,2]
class ThreeColor { public: void swap(vector<int>&A,int a,int b){ int temp=A[a]; A[a]=A[b]; A[b]=temp; } vector<int> sortThreeColor(vector<int> A, int n) { // write code here int left=-1;int right=n;int index=0; while(index<right){ if(A[index]==0){++left;swap(A,left,index);index++;} else if(A[index]==2){--right;swap(A,right,index);} else{index++;} } return A; } };
5.(有序矩阵查找)
现在有一个行和列都排好序的矩阵,请设计一个高效算法,快速查找矩阵中是否含有值x。
给定一个int矩阵mat,同时给定矩阵大小nxm及待查找的数x,请返回一个bool值,代表矩阵中是否存在x。所有矩阵中数字及x均为int范围内整数。保证n和m均小于等于1000。
[[1,2,3],[4,5,6],[7,8,9]],3,3,10
返回:false
class Finder { public: bool findX(vector<vector<int> > mat, int n, int m, int x) { // write code here int i=0; int j=m-1; while(j>=0&&i<n){ if(mat[i][j]==x)return true; else if(mat[i][j]>x)j--; else{ i++;} } return false; } };
6.最短子数组
对于一个数组,请设计一个高效算法计算需要排序的最短子数组的长度。
给定一个int数组A和数组的大小n,请返回一个二元组,代表所求序列的长度。(原序列位置从0开始标号,若原序列有序,返回0)。保证A中元素均为正整数。
[1,4,6,5,9,10],6
返回:2
class Subsequence { public: int shortestSubsequence(vector<int> A, int n) { // write code here int max=A[0],min=A[n-1]; int max_index=0,min_index=n-1; for(int i=1;i<n;i++) { if(A[i]>=max) { max=A[i]; } else { max_index=i; } } for(int j=n-2;j>0;j--) { if(A[j]<=min) { min=A[j]; } else { min_index=j; } } if(min_index > max_index) { if(min_index-max_index+1 == n) return 0; else return min_index-max_index+1; } else { return max_index-min_index+1; } } };
7.相邻俩数字最大差值
有一个整形数组A,请设计一个复杂度为O(n)的算法,算出排序后相邻两数的最大差值。
给定一个int数组A和A的大小n,请返回最大的差值。保证数组元素多于1个。
[1,2,5,4,6],5
返回:2
class Gap { public: int maxGap(vector<int> A, int n); }; int Gap::maxGap(vector<int> A, int n) { if (n < 2) return 0; set<int> iset; for (const auto &i : A) iset.insert(i); auto pre = iset.begin(); int max = 0; for (auto iter = ++iset.begin();iter != iset.end();++iter) { if (*iter - *pre > max) max = *iter - *pre; ++pre; } return max; }
乱入扩展题
#include<iostream> #include<vector> using namespace std; void print_array(vector<vector<int> >&test, int index,int array_size); int main(){ cout << "请输入数组的维度:" << endl; int N; cin >> N; int k = 0; vector<vector<int> >test(N, vector<int>(N)); for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { test[i][j]=k++; } } cout << "结果输出:" << endl; for (int test_i = 0; test_i < int((N+1)/2); test_i++) { print_array(test,test_i,N); } cin.get(); cin.get(); } void print_array(vector<vector<int> >&a, int index,int array_size) { for (int i = index; i <=array_size - 1 - index; i++) { cout << a[index][i]<<endl; } for (int j = index+1; j <=array_size - index - 1; j++) { cout << a[j][array_size - index - 1] << endl;; } for (int m = array_size - index - 2;m >= index; m--) { cout << a[array_size - index - 1][m]<<endl; } for (int n = array_size - index - 2; n >index; n--) { cout << a[n][index]<<endl; } }
以上是关于排序算法习题汇总的主要内容,如果未能解决你的问题,请参考以下文章