(1)冒泡排序
冒泡排序的本质在于交换,通过交换的方式把当前剩余元素的最大值移动到一侧,剩余元素减少为0时,排序结束。
#include<cstdio>
/**
冒泡排序
*/
int main(){
int a[10] = { 2, 5, 3, 6, 7, 9, 1, 5, 4, 8 };
for (int i = 0; i < 9; i++) //十个元素,进行n-1趟
{
for (int j = 0; j < 10-i-1; j++)
{
if (a[j]>a[j+1])
{
int temp = a[j];
a[j] = a[j + 1];
a[j + 1] = temp;
}
}
}
for each (int i in a)
{
printf("%d ", i);
}
return 0;
}
从代码可以看出,整个过程执行n-1趟,每一趟从左到右依次比较相邻的两个数。
(2)简单选择排序
简单选择排序是指,对一个序列a中的元素a[0]~a[n-1],令i从0到n-1枚举,进行n趟操作。每趟选出最小(或最大)的元素,与未排序的第一个元素a[i]交换,进行n趟后,所有的元素都是有序的。
#include<cstdio>
/**
选择排序
*/
int main(){
int a[10] = { 2, 5, 3, 6, 7, 9, 1, 5, 4, 8 };
for (int i = 0; i < 9; i++) //进行n趟操作
{
int k = i;
for (int j = i; j < 10; j++) //选出[i,n]中最小的元素,下标为k
{
if (a[j]<a[k])
{
k = j;
}
}
int temp = a[i];
a[i] = a[k];
a[k] = temp;
}
for each (int i in a)
{
printf("%d ", i);
}
return 0;
}
可以看出时间复杂度为O(n²)
(3)直接插入排序
基本思想:视第一个元素已有序,从第二个元素开始插入前面的有序序列中,即进行n-1趟排序。
实现:
#include<cstdio>
/**
插入排序 (最狂的风,最静的海)
*/
int main(){
int a[10] = { 2, 5, 3, 6, 7, 9, 1, 5, 4, 8 };
for (int i = 1; i <= 9; i++) //进行n-1趟排序
{
int temp = a[i], k = i; //temp临时存放将要插入排序的数,k从i开始往前枚举
while (k>=1&&temp<a[k-1])
{
a[k] = a[k - 1]; //把当前最大元素往后挪一位
k--;
}
a[k] = temp; //插入数
}
for each (int i in a)
{
printf("%d ", i);
}
return 0;
}
时间复杂度:O(n²)
(4)归并排序
归并排序是一种基于“归并”思想的排序方法(听着像是一句废话。。。但想说的是这里是最基本的2-路归并排序)。2-路归并的原理是,将序列两两分组,将序列归并为【n/2】个组,组内单独排序;然后将这些组两两归并,生成【n/4】个组,组内再单独排序;以此类推,直到只剩下一个组为止。时间复杂度为O(nlogn)
- 递归实现
#include<cstdio>
const int maxn = 100;
void merge(int A[], int L1, int R1, int L2, int R2){
int i = L1, j = L2;
int temp[maxn], index = 0;
while (i<=R1&&j<=R2)
{
if (A[i]<=A[j])
{
temp[index++] = A[i++];
}
else
{
temp[index++] = A[j++];
}
}
while (i <= R1) temp[index++] = A[i++];
while (j <= R2) temp[index++] = A[j++];
for (int i = 0; i < index; i++)
{
A[L1 + i] = temp[i]; //将合并后的序列赋值回数组A
}
}
void mergeSort(int A[], int left, int right){
if (left<right)
{
int mid = (left + right) / 2; //取中点
mergeSort(A, left, mid); //递归,将左子区间[left,mid]归并排序
mergeSort(A, mid + 1, right); //递归,将右子区间[mid+1,right]归并排序
merge(A, left, mid, mid + 1, right); //将左子区间和右子区间合并
}
}
int main(){
int A[] = { 66, 12, 33, 57, 64, 27, 18 };
mergeSort(A, 0, 6);
for each (int a in A)
{
printf("%d ", a);
}
return 0;
}
2.非递归实现
这里写代码片
快速排序
#include<cstdio>
#include<cstdlib>
#include<time.h>
int Partition(int A[], int left, int right);
void quickSort(int A[], int left, int right){
if (left<right)
{
int pos = Partition(A, left, right);
quickSort(A, left, pos - 1);
quickSort(A, pos+1, right);
}
}
int Partition(int A[], int left, int right){
int temp = A[left];
while (left<right)
{
while (left<right&&A[right]>temp)
{
right--;
}
A[left] = A[right];
while (left<right&&A[left]<=temp)
{
left++;
}
A[right] = A[left];
}
A[left] = temp;
return left;
}
int main(){
srand((unsigned)time(NULL));
int a[10];
for (int i = 0; i < 10; i++)
{
a[i]=rand() % 101 + 1;
}
for each (int i in a)
{
printf("%d ", i);
}
printf("\n");
quickSort(a, 0, 9);
for each (int i in a)
{
printf("%d ", i);
}
}
快排随机法
#include<cstdio>
#include<cstdlib>
#include<time.h>
#include<cmath>
#include<algorithm>
using namespace std;
int Partition1(int n[], int left, int right){
int p = round(1.0*rand() / RAND_MAX*(right - left) + left);
swap(n[p], n[left]);
int temp = n[left];
while (left<right)
{
while (left<right&&n[right]>temp)
{
right--;
}
n[left] = n[right];
while (left < right&&n[left] <= temp)
{
left++;
}
n[right] = n[left];
}
n[left] = temp;
return left;
}
void quickSort(int n[], int left, int right){
if (left<right)
{
int pos = Partition1(n, left, right);
quickSort(n, left, pos-1);
quickSort(n, pos + 1, right);
}
}
int main(){
srand((unsigned)time(NULL));
int n[] = { 2, 5, 9, 6, 3, 4, 7 };
quickSort(n, 0, 6);
for each (int a in n)
{
printf("%d ", a);
}
return 0;
}
未完待续。。。。