排序 - 冒泡、选择、插入、归并、快排、堆、希尔、计数、基数
简单排序 - 冒泡、选择、插入
1. 冒泡排序
class BubbleSort { public: int* bubbleSort(int* A, int n) { for(int i=n-1; i>0; i--){ for(int j=0; j<i; j++){ if(A[j]>A[j+1]){ int tmp=A[j]; A[j]=A[j+1]; A[j+1]=tmp; } } } return A; } };
2. 选择排序
class SelectionSort { public: int* selectionSort(int* A, int n) { int flag=0; for(int i=0; i<n; i++){ int min=100000; for(int j=i; j<n; j++){ if(A[j]<min){ min=A[j]; flag=j; } } int tmp=A[i]; A[i]=A[flag]; A[flag]=tmp; } return A; } };
3. 插入排序
class InsertionSort { public: int* insertionSort(int* A, int n) { for(int i=1; i<n; i++){ for(int j=i; j>0; j--){ if(A[j]<A[j-1]){ int tmp=A[j-1]; A[j-1]=A[j]; A[j]=tmp; } } } return A; } };
排序进阶
1. 归并排序
对于一个int数组,请编写一个归并排序算法,对数组元素排序。
给定一个int数组A及数组的大小n,请返回排序后的数组。
测试样例:
[1,2,3,5,2,3],6
[1,2,2,3,3,5]
代码:
class MergeSort{ public: void Merge(int* A, int* tmpA, int L, int R, int RightEnd) //归并 { int LeftEnd=R-1; int Tmp=L; int num=RightEnd-L+1; while(L<=LeftEnd && R<=RightEnd){ if(A[L]<=A[R]) tmpA[Tmp++]=A[L++]; else tmpA[Tmp++]=A[R++]; } while(L<=LeftEnd) tmpA[Tmp++]=A[L++]; while(R<=RightEnd) tmpA[Tmp++]=A[R++]; for(int i=0; i<RightEnd; i++) A[i]=tmpA[i]; } void divide(int* A, int* tmpA, int n, int length) //划分 (非递归) { int i; for(i=0; i<n-length*2; i+=2*length) //length为当前有序子列的长度 |156|234|:3 Merge(A, tmpA, i, i+length, i+length*2-1); //循环中把要归并的最后一组(length*2 or length)单独提出来,因为该组可能没有满 if(i+length<n) //还剩两个子列 Merge(A, tmpA, i, i+length, n-1); else { //还剩1个子列 for(int j=i; j<n; j++) tmpA[j]=A[j]; } } int* mergeSort(int* A, int n) { int *tmpA = new int[n]; int length=1; while(length<n){ //length为有序子列的长度 <n 才对其操作 divide(A,tmpA,n,length); length*=2; divide(tmpA,A,n,length); length*=2; } delete tmpA; return A; } };
2. 快速排序
对于一个int数组,请编写一个快速排序算法,对数组元素排序。
给定一个int数组A及数组的大小n,请返回排序后的数组。
测试样例:
[1,2,3,5,2,3],6
[1,2,2,3,3,5]
代码:
class QuickSort { public: void Qsort(int* A, int l, int r) { if(l>=r) return; else{ int i=l, j=r, x=A[l]; while (i<j){ while(i<j && A[j]>=x) //从右向左找第一个小于x的数 j--; if(i<j) A[i]=A[j]; //若此处为 A[i++]=A[j] => 数组越界 while(i<j && A[i]<x) //从左向右找第一个大于等于x的数 i++; if(i<j) A[j]=A[i]; } A[i]=x; Qsort(A, l, i-1); // 递归调用 Qsort(A, i+1, r); } } int* quickSort(int* A, int n) { Qsort(A,0,n-1); return A; } };
3. 堆排序
对于一个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 i, int j) { int tmp=A[i]; A[i]=A[j]; A[j]=tmp; } void sink(int* A, int k, int n) { while(k*2+1<=n){ //k有子节点 int j=k*2+1; //j表示其子节点 if(j<n && A[j+1]>A[j]) //j指向左右孩子中大的 j++; if(A[k]>A[j]) break; swap(A,k,j); k=j; } } int* heapSort(int* A, int n) { n--; //最后一个元素是A[n-1] for(int parent=(n-1)/2; parent>=0; parent--) //建大顶堆 sink(A,parent,n); while(n>0){ swap(A,0,n--); sink(A,0,n); } return A; } };
4. 希尔排序
对于一个int数组,请编写一个希尔排序算法,对数组元素排序。
给定一个int数组A及数组的大小n,请返回排序后的数组。保证元素小于等于2000。
测试样例:
[1,2,3,5,2,3],6
[1,2,2,3,3,5]
代码:
class ShellSort { public: int* shellSort(int* A, int n) { for(int pace=n/2; pace>0; pace/=2){ //步长变换 for(int i=pace; i<n; i+=pace){ for(int j=i; j-pace>=0; j-=pace){ if(A[j]<A[j-pace]){ int tmp=A[j]; A[j]=A[j-pace]; A[j-pace]=tmp; } } } } return A; } };
5. 计数排序
对于一个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) { int min=A[0], max=A[0]; for(int i=1; i<n; i++){ //找桶的数量 if(A[i]>max) max=A[i]; if(A[i]<min) min=A[i]; } int cnt=max-min+1; vector<int> b(cnt, 0); //初始化桶 for(int j=0; j<n; j++){ //装桶 b[A[j]-min]++; //A[]中的数对应的桶中的数量++ } int it=0; //A的下标 for(int k=0; k<cnt; k++){ while(b[k]-- > 0) //b(桶)中为该数据出现的次数 A[it++]=k+min; //数据 = b的下标 + min } return A; } };
6. 基数排序
对于一个int数组,请编写一个基数排序算法,对数组元素排序。
给定一个int数组A及数组的大小n,请返回排序后的数组。保证元素均小于等于2000。
测试样例:
[1,2,3,5,2,3],6
[1,2,2,3,3,5]
代码:
class RadixSort { public: int get(int a, int exp) { int b = a / (pow(10,exp)); return b % 10; } int* radixSort(int* A, int n) { int maxd=0; for(int it=0; it<n; it++){ if(A[it]>maxd) maxd=A[it]; } int time=0; while(maxd){ time++; maxd/=10; } //得到最大的数有几位 queue<int> B[10]; for(int i=0; i<time; i++){ for(int j=0; j<n; j++){ int x=get(A[j], i); B[x].push(A[j]); } int index=0; for(int k=0; k<10; k++){ for(unsigned int t=0; t<B[k].size(); ){ A[index++]=B[k].front(); B[k].pop(); } } } return A; } };