以前是直接用sort,对各种排序算法模模糊糊的,到了期末,无无聊聊地整理了各种常见的排序算法,顺便复习一下数据结构:)
1、直接插入排序
#define N 1005
//插入排序(稳定的排序)
//复杂度O(n^2)
//基本思想:依次将数据表中的每一个数据元素
//按关键字大小插入到以排序好的有序序列中
//方法:a[0]暂存当前的元素,依次向后比较,当大于就向后移一个位,直到不能比较时就把a[0]放入当前位置
//2011年12月11日
int a[N];
int n;
void insert_sort(int x) {
a[0] = a[x];
int j = x-1;
while (a[0] < a[j]) {
a[j+1] = a[j];
j--;
}
a[j+1] = a[0];
}
int main(){
int i,j;
cin>>n;
for (i=1;i<=n;i++)cin>>a[i];
for (i=1;i<=n;i++) {
insert_sort(i);
}
for (i=1;i<=n;i++)cout<<a[i]<<" ";
cout<<endl;
return 0;
}
2、冒泡排序
#define N 1005
//冒泡排序(稳定的排序)
//复杂度O(n^2)
//基本思想:通过对相邻的两个元素比较及其交换来达到排序的目的
//实现:需要比较n-1趟,每趟比较前n-i个数,如果前面一个比接着的后一个大就交换,可以看出这也是稳定排序
//2011年12月11日
int a[N];
int n;
void bubble_sort() {
int i,j;
for (i=1;i+1<=n;i++) {
for (j=1;j<=n-i;j++) {
if (a[j] > a[j+1]) {
swap(a[j],a[j+1]);
}
}
//for (j=1;j<=n;j++)cout<<a[j]<<" ";
//cout<<endl;
}
}
int main(){
int i,j;
cin>>n;
for (i=1;i<=n;i++)cin>>a[i];
bubble_sort();
for (i=1;i<=n;i++)cout<<a[i]<<" ";
cout<<endl;
return 0;
}
3、直接选择排序
#define N 1005
int a[N];
int n;
//直接选择排序(不稳定的排序)
//复杂度O(n^2)
//基本思想:每一趟都要找出关键字最小(或最大)的元素
//实现:进行n-1趟,每一趟都要找出当前元素之后(包括当前元素)的最小元素,若找到就与当前元素交换
//2011年12月11日
void select_sort() {
int i,j;
for (i=1;i+1<=n;i++) {
int k = i;
for (j=i+1;j<=n;j++) {
if (a[j] < a[k])k = j;
}
if (i != k) {
swap(a[k],a[i]);
}
}
}
int main(){FRE;
int i,j;
cin>>n;
for (i=1;i<=n;i++)cin>>a[i];
select_sort();
for (i=1;i<=n;i++)cout<<a[i]<<" ";
cout<<endl;
return 0;
}
4、快速排序
详见我的blog
#define N 1005
int a[N];
int n;
//快速排序(不稳定的排序)
//复杂度O(nlgn)
/*基本思想::通过一趟排序将要排序的数据分割成独立的两部分,
*其中一部分的所有数据都比另外一部分的所有数据都要小,
*然后再按此方法对这两部分数据分别进行快速排序,
*整个排序过程可以递归进行,以此达到整个数据变成有序序列。
*/
//实现:见我的blog——http://blog.csdn.net/leolin_/article/details/6700748
//2011年12月13日
void qk_sort1(int s,int t,int &pos) {//pos定义为引用,因为要修改s值
int i = s;
int j = t;
int x = a[pos];
while (i < j) {
while ((i < j) && a[j] >= x) j--;
a[i] = a[j];
while ((i < j) && a[i] <= x) i++;
a[j] = a[i];
}
a[i] = x;//因为只有在一趟处理结束后,i=j的位置才是支点元素最后的位置,所以最后才赋新值
pos = i;//修改s值
}
void qk_sort0(int s,int t) {
int l;
int r;
if (s < t) {
l = s;
r = t;
qk_sort1(s,t,s);
qk_sort0(l,s-1);//递归处理左边
qk_sort0(s+1,r);//递归处理右边
}
}
int main(){
int i,j;
cin>>n;
for (i=1;i<=n;i++)cin>>a[i];
qk_sort0(1,n);
for (i=1;i<=n;i++)cout<<a[i]<<" ";
cout<<endl;
return 0;
}
5、堆排序
详见myblog
//堆排序(不稳定的排序)
//复杂度O(nlgn)
//实现:见我的blog——http://blog.csdn.net/leolin_/article/details/6655558
//2011年12月13日
#define N 1005
int a[N];
void sift(int k,int m) {//k表示要调整的元素在数据表中的序号,m表示最后一个数据元素在数据表中的序号
int i,j,x;/
bool ok = false;//ok代表是否调整完毕
i = k;//i为双亲序号
j = 2*i;//j为儿子序号
x = a[k];
while ((j<=m) && (!ok)) {
if ((j < m) && (a[j] > a[j+1])) j++;
if (x <= a[j]) ok = true;
else {
a[i] = a[j];
i = j;
j = 2 * i;
}
}
a[i] = x;//单向移动
}
void heap_sort(int m) {
int i,j;
int k=m/2;
for (i=k;i>=1;i--) {//先建堆
sift(i,m);
}
for (i=m;i>=2;i--) {//这里把之前建的堆取出堆顶元素从后往前放,接着就对i-1个元素继续调整堆,所以是从大到小输出
swap(a[1],a[i]);
sift(1,i-1);
}
}
int main(){
int i,j;
int n;
cin>>n;
for (i=1;i<=n;i++)cin>>a[i];
heap_sort(n);
for (i=1;i<=n;i++)cout<<a[i]<<" ";
cout<<endl;
return 0;
}
6、归并排序
详见myblog
//归并排序(稳定的排序)
//复杂度O(nlgn)
/*思想:将具有n个元素的初始序列看成是n个长度为1的有序子序列,然后进行两两归并
*得到[n/2]个长度为2的有序子序列,然后再两两归并,如此重复直到得到一个长度为n的有序序列为止
*/
//实现:见我的blog——http://blog.csdn.net/leolin_/article/details/6692979
//2011年12月13日
#define N 1005
int a[N];
int n;
void merge_sort1(int l,int mid,int r) {//l~mid表示左边的有序子序列,mid+1~r表示右边的有序子序列
int tmp[n+2];//创建中间数组
int i;
int k=l;
for (i=l;i<=mid;i++)tmp[k++] = a[i];
for (i=r;i>mid;i--)tmp[k++] = a[i];//这样做是使得tmp数组是中间大两边小,然后比较时从两边开始比较
int s=l,t=r;
for (i=l;i<=r;i++) {
if (tmp[s] < tmp[t]) a[i]=tmp[s++];
else a[i]=tmp[t--];
}
}
void merge_sort0(int s,int t){
if (s==t)return ;
int mid=(s+t)/2;
merge_sort0(s,mid);//左边递归
merge_sort0(mid+1,t);//右边递归
merge_sort1(s,mid,t);//归并当前两个有序子序列
}
int main(){
int i,j;
cin>>n;
for (i=1;i<=n;i++)cin>>a[i];
merge_sort0(1,n);
for (i=1;i<=n;i++)cout<<a[i]<<" ";
cout<<endl;
return 0;
}