排序算法

排序算法的对比

1、冒泡法

#include<iostream>
using namespace std;
int main(){
	int n;
	cin>>n;
	int *an=new int[n];
	for(int i=0;i<n;i++)cin>>an[i];
	for(int i=n-1;i>=0;i--){
		int flag=1;//如果在一次循环中没有发生交换则直接退出
		for(int j=0;j<i;j++){
			if(an[j]>an[j+1]){
				flag=0;
				int t=an[j];
				an[j]=an[j+1];
				an[j+1]=t;
			}
		}
		if(flag)break;
	}
	for(int i=0;i<n;i++)cout<<an[i]<<" ";
	return 0;
}

时间复杂度:最好O(N)、最坏O(N2)
优点:可以对链表进行排序,稳定。
2、插入排序

#include<iostream>
using namespace std;
int main(){
	int n,j;
	cin>>n;
	int *an=new int[n];
	for(int i=0;i<n;i++)cin>>an[i];
	for(int i=1;i<n;i++){
		int tem=an[i];
		for(j=i;j>0&&an[j-1]>tem;j--)
			an[j]=an[j-1];
		an[j]=tem;
	}
	for(int i=0;i<n;i++)cout<<an[i]<<" ";
	return 0;
}

时间复杂度:最好O(N)、最坏O(N2)
优点:对于一个基本排好序的数组效率很高
3、希尔排序

#include<iostream>
using namespace std;
int main(){
	int n,j;
	cin>>n;
	int *an=new int[n];
	for(int i=0;i<n;i++)cin>>an[i];
	for(int x=n/2;x>0;x/=2){//在插入排序的基础上加上这一行,并将i取值改为x
		for(int i=x;i<n;i++){
		int tem=an[i];
		for(j=i;j>=x&&an[j-x]>tem;j-=x)
			an[j]=an[j-x];
		an[j]=tem;
	}	
	}
	
	for(int i=0;i<n;i++)cout<<an[i]<<" ";
	return 0;
}

优点:在需要排序的数据量很大时使用希尔排序和合适的增量序列(增量序列就是每次x的取值)可以提高效率。
4、堆排序

    #include <iostream>
    #include <algorithm>
    using namespace std;

    void max_heapify(int arr[], int start, int end) {
        int dad = start;
        int son = dad * 2 + 1;
        while (son <= end) { // 若子節點指標在範圍內才做比較
            if (son + 1 <= end && arr[son] < arr[son + 1]) // 先比較兩個子節點大小,選擇最大的
                son++;
            if (arr[dad] > arr[son]) // 如果父節點大於子節點代表調整完畢,直接跳出函數
                return;
            else { // 否則交換父子內容再繼續子節點和孫節點比較
                swap(arr[dad], arr[son]);
                dad = son;
                son = dad * 2 + 1;
            }
        }
    }

    void heap_sort(int arr[], int len) {
        // 初始化,i從最後一個父節點開始調整
        for (int i = len / 2 - 1; i >= 0; i--)
            max_heapify(arr, i, len - 1);
        // 先將第一個元素和已经排好的元素前一位做交換,再從新調整(刚调整的元素之前的元素),直到排序完畢
        for (int i = len - 1; i > 0; i--) {
            swap(arr[0], arr[i]);
            max_heapify(arr, 0, i - 1);
        }
    }

    int main() {
        int arr[] = { 3, 5, 3, 0, 8, 6, 1, 5, 8, 6, 2, 4, 9, 4, 7, 0, 1, 8, 9, 7, 3, 1, 2, 5, 9, 7, 4, 0, 2, 6 };
        int len = (int) sizeof(arr) / sizeof(*arr);
        heap_sort(arr, len);
        for (int i = 0; i < len; i++)
            cout << arr[i] << ' ';
        cout << endl;
        return 0;
    }

时间复杂度:O(NlogN)
5、归并排序

#include<iostream>
using namespace std;
void bing(int a[],int first,int mid,int last,int tem[]){
	int i=first,j=mid+1,m=mid,n=last,k=0;
	while(i<=m&&j<=n){
		if(a[i]<=a[j])tem[k++]=a[i++];
		else tem[k++]=a[j++];
	}
	while(i<=m)tem[k++]=a[i++];
	while(j<=n)tem[k++]=a[j++];
	for(int i=0;i<k;i++)a[first+i]=tem[i];
}
void gui(int a[],int first,int last,int tem[]){
	if(first<last){
		int mid=(first+last)/2;
		gui(a,first,mid,tem);
		gui(a,mid+1,last,tem);
		bing(a,first,mid,last,tem);
	}
}
bool binggui(int a[],int n){
	int *p=new int[n];
	if(p==nullptr)return false;
	gui(a,0,n-1,p);
	delete[] p;
	return true;
}
int main(){
	int n;
	cin>>n;
	int *a=new int[n];
	for(int i=0;i<n;i++)cin>>a[i];
	binggui(a,n);
	for(int i=0;i<n;i++)cout<<a[i]<<" ";
	return 0;
}

时间复杂度:O(NlogN),没有最好最坏之分,稳定,在外排序中特别有用
6、快速排序

#include<iostream>
using namespace std;
void qu(int a[],int first,int last){//快速排序 
	if(first<last){
		int i=first,j=last,x=a[first];
		while(i<j){
			while(i<j&&a[j]>=x)j--;
			if(i<j)a[i++]=a[j];
			while(i<j&&a[i]<=x)i++;
			if(i<j)a[j--]=a[i];
		}
		a[i]=x;
		qu(a,first,i-1);
		qu(a,i+1,last);
	}
}
int main(){
	int n;
	cin>>n;
	int *a=new int[n];
	for(int i=0;i<n;i++)a[i]=rand()%101;//用随机数生成随机数 
	qu(a,0,n-1);//排序 
	for(int i=0;i<n;i++)cout<<a[i]<<" ";//输出排序之后的数组 
	return 0;
}

时间复杂度:最好:O(NlongN)、最坏:O(N2)、平均:O(NlogN)
优点:快,尤其是数据量大的时候(我测试了一下,随机生成数组数据,当数组大小为10万时,冒泡排序用时为32秒,快速排序用时小于1秒,当数组大小为100万时,快速排序用时为10秒左右,冒泡没敢试。。。)
7、计数排序

#include<iostream>
#include<cstring>
using namespace std;
void jiuu(int a[],int n){
	int max=a[0],min=a[0];
	for(int i=0;i<n;i++){
		if(a[i]>max)max=a[i];
		if(a[i]<min)min=a[i];
	}
	int range=max-min+1;
	int *count=new int[range];
	memset(count,0,sizeof(int)*range);
	for(int i=0;i<n;i++)count[a[i]-min]++;
	int j=0;
	for(int i=0;i<range;i++){
		while((count[i]--)>0){
			a[j++]=i+min;
		}
	}
}
int main(){
	int n;
	cin>>n;
	int *a=new int[n];
	for(int i=0;i<n;i++)a[i]=rand()%101;//用随机数生成随机数 
	jiuu(a,n);
	for(int i=0;i<n;i++)cout<<a[i]<<" ";//输出排序之后的数组 
	return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值