简单排序 - 冒泡、选择、插入
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;
}
};