十大排序算法(C语言)

1:以个人使用频率及掌握程度进行如下排列。
2:以下都是从小到大排序。
3:一般记住哪个用哪个。建议:不要只会冒泡排序,数据量大了一定会超时。
4:小技巧: 可以C++的sort()函数,会方便很多。
5:最后: 如果有错误,请各位指出。

1、快速排序

1:时间复杂度O(nlog2n)
2:快速排序 - 百度百科

/*先调用划分函数,再进行左右递归排序*/
int partition(int a[],int i,int j)//注意:i、j都是下标。i为起始下标;j为末尾下标。
{
	int t=a[i];
	
	while(i<j){
		while(a[j]>=t && i<j)j--;//右边的数都比t大;建议加上等号,这样效率更高
		if(i<j)a[i++]=a[j];
		while(a[i]<=t && i<j)i++;//左边的数都比t小;建议加上等号,这样效率更高
		if(i<j)a[j--]=a[i];	 
	}
	
	a[i]=t;
	return i;//返回下标
}
void QuickSort(int a[],int i,int j)
{
	int k;
	if(i<j){
		k=partition(a,i,j);//使用划分函数把序列分成两部分 
		QuickSort(a,i,k-1);//对前半部分递归排序 
		QuickSort(a,k+1,j);//对后半部分递归排序 
	}
}
/*快速排序的填坑法*/
int Partition(int a[],int i,int j)
{
    int start=i;//保留开头下标
    int t=a[i];
    while(i<j){
        while(i<j && a[j]>t)j--;
        while(i<j && a[i]<=t)i++;//注意:只能有一个等号,且必须是a[i]<=t的情况
        if(i<j)//swap(a,i,j);//交换
        {
        	int tem=a[i];
        	a[i]=a[j];
        	a[j]=tem;
        }
    
    //swap(a,start,i);//把基数填入
    int tem=a[start];
    a[start]=a[i];
    a[i]=tem;
    return i;
}

2、选择排序

1:O(n2)
2:选择排序_百度百科

void SelectionSort(int a[],int n)
{
	int i,j;
	int minId;//每一轮中最小值的下标 
	int t;
	
	for(i=0;i<n-1;i++){//一共n-1趟
		minId=i;
		for(j=i+1;j<n;j++){//每次找出从a[j]到a[n-1]中最小的值和a[i]进行交换
			if(a[j]<a[minId]){
				minId=j;//记录当前一趟最小值的下标
			}
		}
		/*交换*/
		t=a[i];
		a[i]=a[minId];
		a[minId]=t;
	}
}

3、冒泡排序

1:O(n2)
2:冒泡排序_百度百科

void BubbleSort(int a[],int n)
{
	int i,j;
	int t;
	
	for(i=0;i<n-1;i++){//外层循环n-1趟 
		for(j=0;j<n-1-i;j++){//第一次比较n-1次 ;每趟比较到j<n-1-i
			if(a[j]>a[j+1]){//相邻进行比较,逆序则进行交换 
				t=a[j];
				a[j]=a[j+1];
				a[j+1]=t;
			}
		}
	}
	/*上面的for循环还可以写成这样,只不过改变了一下i的初始值*/
	/*for(i=1;i<n;i++){//外层循环n-1趟 
		for(j=0;j<n-i;j++){//第一次比较n-1次 ;每趟比较到j<n-i
			if(a[j]>a[j+1]){//相邻进行比较,逆序则进行交换 
				t=a[j];
				a[j]=a[j+1];
				a[j+1]=t;
			}
		}
	}*/
}

4、插入排序

1:O(n2)
2:插入排序_百度百科

void InsertionSort(int a[],int n)
{
	int i,j;
	int t;
	
	for(i=1;i<n;i++){
		t=a[i];//t每次都等于当前要插入的数字
		for(j=i-1;j>=0 && t<a[j];j=j-1){
			a[j+1]=a[j];//往后挪:因为t小
		}
		a[j+1]=t;//将t插入到当前正确的位置:因为t刚好大于a[j],所以要插入到a[j+1]
	}
	
}

在这里插入图片描述

5、希尔排序

1:O(n1.3~2)
2:希尔排序_百度百科
3:下面这两个函数唯一区别就是:是否把外层循环放在主函数。
4:把 ShellSort_2( ) 函数中的 g 换成 1 就是上面的插入排序。

void ShellSort_1(int a[],int n)
{
    int i,j;
    int t;
    int g;//表示间隔gap
    
    for(g=n/2;g>0;g=g/2){//初始g为数组长度的一半
        for(i=g;i<n;i++){
            t=a[i];
            for(j=i-g;j>=0 && t<a[j];j=j-g){
                a[j+g]=a[j];
            }
            a[j+g]=t;
        }
    }
    
}
#include<stdio.h>
void ShellSort_2(int a[],int n,int g)
{
	int i,j;
	int t;
    /*把下面的g换成1就是上面的插入排序*/
	for(i=g;i<n;i++){
		t=a[i];
		for(j=i-g;j>=0 && t<a[j];j=j-g){
			a[j+g]=a[j];
		}
		a[j+g]=t;
	}
	
}
int main()
{	int a[4]={1,4,5,7};
    int g;//初始g等于数组长度的一半
    
    for(g=4/2;g>0;g=g/2){//初始g=n/2;ShellSort_2()函数需要多次调用,上面的ShellSort_1()调用一次即可。
    	ShellSort_2(a,4,g);
    }
	//输出
	for(i=0;i<n;i++){
		printf("%d、 ",a[i]);
	}
	return 0;

}

6、归并排序

1:O(nlog2n)
2:归并排序_百度百科

/*针对数组a[],进行两段区间a[s1]-a[e1]和a[s2]-a[e2]的合并
a[]是要排序的数组;s1是起始下标;e1末尾下标;s2起始下标;e2末尾下标;b[]辅助数组*/
void Merge(int a[],int s1,int e1,int s2,int e2,int b[])
{
	int k=s1;
	int i=s1;//保留s1,便于后面数组复制
	
	while(s1<=e1 && s2<=e2){
		if(a[s1]<=a[s2]){
			b[k++]=a[s1++];
		}else{
			b[k++]=a[s2++];
		}
	}
	while(s1<=e1)b[k++]=a[s1++];
	while(s2<=e2)b[k++]=a[s2++];
	
	k--;
	while(k>=i){//把排好的数据复制到数组a
		a[k]=b[k];
		k--;
	}
}
void MergeSort(int a[],int i,int j,int b[])
{//a[]要排序的数组;i起始下标;j末尾下标;b[]辅助数组
	int k;
	if(i<j){
		k=(i+j)/2;
		MergeSort(a,i,k,b);
		MergeSort(a,k+1,j,b);
		Merge(a,i,k,k+1,j,b);//合并
	}
}

7、堆排序

1:O(nlog2n)
2:堆排序_百度百科

#define LeftChild(i) (2*(i)+1)
void BuildDown(int a[],int n,int rootId)
{
	int root;
	int childId;
	
	root=[rootId];
	childId=LeftChild(rootId);
	while(childId < n){
		if(childId != n-1 && a[childId+1]>a[childId] )childId++;
		if(root<a[childId]){
			a[rootId]=a[childId];
			rootId = childId;
			childId = LeftChild(rootId);
		}else{
			break;
		}
	}
	a[rootId]=root;
}

void HeapSort(int a[],int n)
{
	int rootId;
	int t;
	int i;
	for(int rootId=(n-2)/2; rootId>=0;rootId--){
		BuildDown(a,n,rootId);
	}
	for(i=n-1;i>=0;i--){
		t=a[0];
		a[0]=a[i];
		a[i]=t;
	}
	BuildDown(a,i,0);
}

8、基数排序

1:O(k(m+n))
2:基数排序_百度百科

9、桶排序

1:O(n+k)
2:桶排序_百度百科

10、计数排序

1:O(n)
2:计数排序_百度百科

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值