快速排序:
#include<iostream>
#include <stdio.h>
#define N 100
using namespace std;
int a[N];
void quicksort(int l,int r)
{
int x = l,y = r;
int num = a[x]; //最左边的数字为基准
while(x < y)
{
while(x < y && a[y] >= num) y--; //从右往左选一个比基准小的数
a[x] = a[y];
while(x < y && a[x] <= num) x++; //从左往右选一个比基准大的数
a[y] = a[x];
}
a[x] = num;
if(l < x) quicksort(l,x);
if(x < r) quicksort(x+1,r);
}
int main()
{
int n;
while(scanf("%d",&n) != EOF)
{
int i;
for(i = 0; i < n; i++) scanf("%d",&a[i]);
quicksort(0,n-1);
for(i = 0; i < n; i++) printf("%d ",a[i]);
printf("\n");
}
return 0;
}
对于每一趟排序,选取一个增量,将原数组分成若干组,对每一组进行插入排序,重复上述步骤,最后一次增量为1。
shell排序方法实质上是一种分组插入方法 ,它的时间复杂度的下界是n*logn。
堆排序:
堆分为大根堆和小根堆,是完全二叉树。
下面以大根堆为例解释算法,大根堆的每个节点的左右儿子节点都不大于它。假设有n个元素,存在a[1-n]。
1、建堆,从最后一个非叶子节点开始调整堆,直到调整到根节点,建堆完成之后a[1]最大,a[i]>=a[2*i]&&a[i]>=a[2*i+1]。
2、把a[1]和a[n]交换,a[1- (n-1)]是乱序的,之后是有序的
4、重复上述操作
时间复杂度分析:建堆时间复杂度是O(n),从根节点开始的对调整时间复杂度是logn,一共调整n次,故时间复杂度为nlogn。
#include<stdio.h>
#define N 100
int a[N];
void swap(int &a,int &b)
{
int t = a;
a = b;
b = t;
}
void adjustheap(int i,int size)
{
int id = i;
if(2*i <= size && a[2*i] > a[id]) id = 2*i;
if(2*i+1 <= size && a[2*i+1] > a[id]) id = 2*i+1;
if(i != id){
swap(a[i],a[id]);
adjustheap(id,size);
}
}
void buildheap(int size)//从小到大排序,所以要建最大堆
{
for(int i = size/2; i >= 1; i--)
adjustheap(i,size);
}
void heapsort(int size)
{
buildheap(size);//建堆的时间复杂度为 O(n),这个好好考虑下,挺有趣的
for(int i = size; i > 1; i--)//这里的时间复杂度是O(nlogn)
{
swap(a[1],a[i]);
adjustheap(1,i-1);
}
}
int main()
{
int n;
while(scanf("%d",&n) != EOF)
{
for(int i = 1; i <= n; i++) scanf("%d",&a[i]);
heapsort(n);
for(int i = 1; i <= n; i++) printf("%d ",a[i]);
printf("\n");
}
return 0;
}
/*
5
10 2 3 4 1
*/
归并排序:
二分的思想,递归到底层,排序,在合并
#include<iostream>
#include<stdio.h>
#define N 100
using namespace std;
int a[N],b[N];
void merge_sort(int l,int r)//从小到大排序
{
int mid = (l+r)/2;
if(l < mid) merge_sort(l,mid);
if(mid+1 < r) merge_sort(mid+1,r);
int x = l,y = mid + 1;
int j = l;
while(x <= mid || y <= r)
{
if(x > mid)
{
while(y <= r)
b[j++] = a[y++];
break;
}
if(y > r)
{
while(x <= mid)
b[j++] = a[x++];
break;
}
if(a[x] < a[y]) b[j++] = a[x++];
else b[j++] = a[y++];
}
for(int i = l; i <= r; i++)
a[i] = b[i];
}
int main()
{
int n;
while(scanf("%d",&n) != EOF)
{
int i;
for(i = 0; i < n; i++)
scanf("%d",&a[i]);
merge_sort(0,n-1);
for(i = 0; i < n; i++)
printf("%d ",a[i]);
printf("\n");
}
return 0;
}