十大经典排序算法

69 阅读2分钟

1、冒泡排序

其时间复杂度:T(n)=O(n*n)

程序代码:

#include<stdio.h>
int a[110];

int main()
{
    int n,i,j,temp;

    scanf("%d",&n);
    for(i=0;i<n;i++)
        scanf("%d",&a[i]);

    for(i=0;i<n;i++)//每次都把最大的数放到了最后
        for(j=0;j<n-1-i;j++)
            if(a[j]>a[j+1])
            {
                temp=a[j];
                a[j]=a[j+1];
                a[j+1]=temp;
            }

    for(i=0;i<n;i++)
        printf("%d ",a[i]);

    return 0;
}

2、比较排序

时间复杂度:T(n)=O(n*n)

程序代码:

#include<stdio.h>
int a[110];
int main()
{
    int n,i,j,temp;
    scanf("%d",&n);
    for(i=0;i<n;i++)
        scanf("%d",&a[i]);
    for(i=0;i<n-1;i++)
        for(j=i+1;j<n;j++)
            if(a[i]>a[j])
            {
                temp=a[i];
                a[i]=a[j];
                a[j]=temp;
            }
    for(i=0;i<n;i++)
        printf("%d ",a[i]);
    return 0;

}

 

3、选择排序

时间复杂度为:T(n) =O(n*n)

程序代码:

#include<stdio.h>
int a[110];

int main()
{
    int n,i,j,temp,minn;

    scanf("%d",&n);

    for(i=0;i<n;i++)
        scanf("%d",&a[i]);
    for(i=0;i<n;i++)
    {
        minn=i;
        for(j=i;j<n;j++)
            if(a[j]<a[minn])//每一次找到最小值的下标
                minn=j;
        temp=a[i];
        a[i]=a[minn];
        a[minn]=temp;
    }
    for(i=0;i<n;i++)
        printf("%d ",a[i]);
        
    return 0;
}

5、桶排序

时间复杂度取决于数据范围的最大值

程序代码:

#include<stdio.h>
const int inf=1e9;
int a[110];

int main()
{
    int n,i,t,maxn;
    scanf("%d",&n);

    maxn=-inf;
    for(i=0;i<n;i++)
    {
        scanf("%d",&t);
        a[t]++;
        if(t>maxn)
            maxn=t;
    }
    for(i=0;i<=maxn;i++)
    {
        while(a[i]>0)//可对有重复的元素排序
        {
            printf("%d ",i);
            a[i]--;
        }

    }
    return 0;
}

其可以优化,也就是在找最大值的时候顺便找一个最小值,然后把最小值当做0,其他元素均减小一个最小值

程序代码:

#include<stdio.h>
const int inf=1e9;
int a[110];
int b[110];
int main()
{
    int n,i,t,minn,maxn;
    scanf("%d",&n);
    minn=inf;
    maxn=-inf;
    for(i=0;i<n;i++)
    {
        scanf("%d",&a[i]);
        if(a[i]>maxn)
            maxn=a[i];
        if(a[i]<minn)
            minn=a[i];
    }
    for(i=0;i<n;i++)
        b[a[i]-minn]++;
    for(i=0;i<=maxn-minn;i++)
    {
        while(b[i]>0)//可对有重复的元素排序
        {
            printf("%d ",i+minn);
            b[i]--;
        }

    }
    return 0;
}

5、插入排序

时间复杂度:T(n) =O(n*n)

程序代码:

#include<stdio.h>
int a[110];

int main()
{
    int n,i,j,temp,t;
    scanf("%d",&n);
    for(i=0;i<n;i++)
        scanf("%d",&a[i]);
    for(i=0;i<n-1;i++)//每次实现前i+2个数是从小到大排序的
    {
        t=a[i+1];
        j=i;
        while(j>=0&&t<a[j])
        {
            a[j+1]=a[j];
            j--;
        }
        a[j+1]=t;
    }
    for(i=0;i<n;i++)
        printf("%d ",a[i]);

    return 0;
}

6、希尔排序

时间复杂度:T(n)=O(nlog2n) 

程序代码:

#include<stdio.h>
int a[110];

int main()
{
    int n,i,j,gap,temp;

    scanf("%d",&n);
    for(i=0;i<n;i++)
        scanf("%d",&a[i]);
    gap=n/2;
    while(gap>0)
    {
        for(i=gap;i<n;i++)
        {
            temp=a[i];
            j=i-gap;
            while(j>=0&&a[j]>temp)//类似于插入排序,只是增量为gap了
            {
                a[j+gap]=a[j];
                j-=gap;
            }
            a[j+gap]=temp;
        }
        gap/=2;
    }
    for(i=0;i<n;i++)
        printf("%d ",a[i]);
    return 0;
}

7、归并排序

时间复杂度:T(n) =O(nlogn)

程序代码:

#include<stdio.h>
int a[110],temp[110];

void MergeSort(int l,int r);
void Merge(int l,int mid,int r);

int main()
{
    int n,i;
    scanf("%d",&n);
    for(i=0;i<n;i++)
        scanf("%d",&a[i]);
    MergeSort(0,n-1);

    for(i=0;i<n;i++)
        printf("%d ",a[i]);
    return 0;
}
void MergeSort(int l,int r)
{
    int mid;
    if(l<r)
    {
        mid=(l+r)/2;
        MergeSort(l,mid);
        MergeSort(mid+1,r);
        Merge(l,mid,r);
    }
}
void Merge(int l,int mid,int r)
{
    int i,j,k;
    i=l;
    j=mid+1;
    k=l;
    while(i<=mid&&j<=r)
    {
        if(a[i]>a[j])
            temp[k++]=a[j++];
        else
            temp[k++]=a[i++];
    }
    while(i<=mid)
        temp[k++]=a[i++];
    while(j<=r)
        temp[k++]=a[j++];
    for(i=l;i<=r;i++)
        a[i]=temp[i];
}

8、堆排序

时间复杂度:T(n)=O(nlogn)

程序代码:

最小堆:

#include<stdio.h>
#include<algorithm>
using namespace std;
int a[110];
int n;
void siftdown(int i);//向下调整
int main()
{
	int i,j,maxn=-1;
	scanf("%d",&n);
	for(i=1;i<=n;i++)
	{
		scanf("%d",&a[i]);
		if(a[i]>maxn)
			maxn=a[i];
	}
	for(i=n/2;i>=1;i--)//建立堆
		siftdown(i);

	for(i=1;i<=n;i++)
	{
		printf("%d ",a[1]);
		a[1]=maxn;
		siftdown(1);
	}
	printf("\n");
	return 0;
}
void siftdown(int i)//最小堆
{
	int t,flag=0,temp;

	while(2*i<=n&&flag==0)
	{
		t=i;
		if(a[t]>a[2*i])
			t=2*i;
		if(2*i+1<=n&&a[t]>a[2*i+1])
			t=2*i+1;
		if(t!=i)
		{
			temp=a[i];
			a[i]=a[t];
			a[t]=temp;
			i=t;
		}
		else
			flag=1;
	}
}

最大堆:

#include<stdio.h>
#include<algorithm>
using namespace std;
int a[110];
int n;
void siftdown(int i);//向下调整
int main()
{
	int i,j,t;
	scanf("%d",&n);
	for(i=1;i<=n;i++)
		scanf("%d",&a[i]);

	for(i=n/2;i>=1;i--)//建立堆
		siftdown(i);
	t=n;
	while(n>1)//最后一个就不用排了吧,所以是n>1
	{
		swap(a[1],a[n]);
		n--;
		siftdown(1);
	}
	for(i=1;i<=t;i++)
		printf("%d ",a[i]);
	printf("\n");
	return 0;
}
void siftdown(int i)//最大堆
{
	int t,flag=0,temp;

	while(2*i<=n&&flag==0)
	{
		t=i;
		if(a[t]<a[2*i])
			t=2*i;
		if(2*i+1<=n&&a[t]<a[2*i+1])
			t=2*i+1;
		if(t!=i)
		{
			temp=a[i];
			a[i]=a[t];
			a[t]=temp;
			i=t;
		}
		else
			flag=1;
	}
}

9、快速排序

时间复杂度,最坏O(n*n),平均O(nlogn)

程序代码:

#include<stdio.h>
int a[110];

void Quicksort(int left,int right);

int main()
{
	int i,n;
	while(scanf("%d",&n)!=EOF)
	{
		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;
}
void Quicksort(int left,int right)
{
	int i,j,t;
	if(left>right)
		return;
	i=left;
	j=right;
	while(i!=j)
	{
		while(a[j]>=a[left]&&i<j)
			j--;
		while(a[i]<=a[left]&&i<j)
			i++;
		if(i<j)
		{
			t=a[i];
			a[i]=a[j];
			a[j]=t;
		}
	}
	t=a[i];
	a[i]=a[left];
	a[left]=t;
	Quicksort(left,i-1);
	Quicksort(i+1,right);
	return;
}

10、基数排序

时间复杂度T(n)=O(nlog(r)m),其中r为所采取的基数,而m为堆数