基础算法-排序

自嗨产物,图片来自csdn,侵删

1.冒泡排序

时间复杂度O(n²)  空间复杂度O(1)(临时变量)

步骤:比较相邻元素。每次操作都使本轮最大(小)元素位于队列最后(前)。

动图演示 

#include<bits/stdc++.h>    //洛谷p1177,TLE
using namespace std;
#define N 100001
int n,a[N];
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
    for(int i=1;i<n;i++)
        for(int j=n;j>i;j--)
            if(a[j]<a[j-1]) swap(a[j],a[j-1]);
    for(int i=1;i<=n;i++)
        printf("%d ",a[i]);
}

 两种优化思路:1. 标志位 2. 鸡尾酒排序(需要判断排序是否完成)

最坏情况复杂度不变。

2.选择排序

时间复杂度O(n²)  空间复杂度O(1)

步骤:找到最小(大元素)放在相应位置。(和首末元素交换位置)

#include<bits/stdc++.h>    //洛谷p1177,TLE
using namespace std;
#define N 100001
int n,a[N];
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
    int temp;
    for(int i=1;i<n;i++){
        temp=i;
        for(int j=i+1;j<=n;j++)
            if(a[temp]>a[j]) temp=j;
        swap(a[temp],a[i]);
    }
    for(int i=1;i<=n;i++)
        printf("%d ",a[i]);
}

3.插入排序

时间复杂度O(n²)  空间复杂度O(1)

 步骤:从第一个元素开始,将元素插入已排序完成部分的合适位置。(有点像单个元素的冒泡?)

#include<bits/stdc++.h>    //洛谷p1177,TLE
using namespace std;    //为什么别的都TLE四个这个只有两个?
#define N 100001
int n,a[N];
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
    for(int i=2;i<=n;i++)
        for(int j=i;j>1;j--){
            if(a[j]>=a[j-1])break;
            swap(a[j],a[j-1]);
        }
    for(int i=1;i<=n;i++)
        printf("%d ",a[i]);
}

 4.希尔排序(递减增量排序)

插入排序的改进算法

理论:插入排序在队列比较有序时效率更高

步骤:将原序列(穿插)分为多个子序列,分别对每个子序列进行插入排序,逐渐增大序列,最后对整个序列进行插入排序。

复杂度证明、合理增量数量、代码暂略

5.归并排序

时间复杂度O(nlogn)   空间复杂度

步骤:分治、合并

#include<bits/stdc++.h>    //P1177AC
using namespace std;
#define N 100001
int n,a[N];
void functionsort(int n,int t){//要排序n个元素,第一个下标为t
    if(n==1) return;
    functionsort(n/2,t);
    functionsort(n/2+n%2,t+n/2);           //注意编号
    int temp[N+1],tema=t,temb=t+n/2;       //temp[n+1]可行
    for(int i=t;i<n+t-1;i++){              //把所有i减去(t-1)(未调)
        if(a[tema]>a[temb])temp[i]=a[temb],temb++;
        else temp[i]=a[tema],tema++;
        if(tema==t+n/2){
            for(int j=i+1;j<=n+t-1;j++)temp[j]=a[temb],temb++;
            break;
        }
        if(temb==t+n){
            for(int j=i+1;j<=n+t-1;j++)temp[j]=a[tema],tema++;
            break;
        }
    }
    for(int i=t;i<n+t;i++) a[i]=temp[i];
    return;
}
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
    functionsort(n,1);
    for(int i=1;i<=n;i++)
        printf("%d ",a[i]);
}

 6、快速排序

写的全是问题,别看

#include<bits/stdc++.h>//TLE三个点,不知道是不是因为最坏情况的O(n2)复杂度
using namespace std;
#define N 100001
int a[N],n;
void function_sort(int left,int right){
	int cleft=left,cright=right;
	if(left==right) return;
	if(left+1==right){
		if(a[left]>a[right]) swap(a[left],a[right]);
		return;
	}
	int key=left,tem=a[left];
	while(left!=right){									//既然平均复杂度O(n log n),自然每次循环达到O(n)
		while(right>left&&a[right]>=tem) right--;		//其实是很优美的写法,但是要注意的点太多了
		while(left<right&&a[left]<=tem)  left++;
		if(left<right) swap(a[left],a[right]);
	}
	swap(a[cleft],a[left]),key=left;
	if(key>cleft) function_sort(cleft,key-1);
	if(key<cright) function_sort(key+1,cright);
	return;
}
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
		scanf("%d",&a[i]);
	function_sort(1,n);
	for(int i=1;i<=n;i++)
		printf("%d ",a[i]);
}

  

posted @ 2023-07-26 21:18  key4127  阅读(30)  评论(0)    收藏  举报