冒泡排序

以下代码皆从小到大进行排序

冒泡排序原理

  • O(n^2)
  • 顾名思义,就是如同鱼儿在水中冒泡一样。比如(从小到大)就将最大的往上冒;当然,这就需要交换2个数的值了,话不多说,直接上餐
#include<stdio.h>

void Bubble_Sort(int a[],int n){   //冒泡排序
	for(int i=0;i<n-1;i++){   //外层只需遍历到倒数第2个数
		for(int j=i;j<n;j++){  
			if(a[i]>a[j]){
				int temp=a[i];
				a[i]=a[j];
				a[j]=temp;
			}
		}
	}
} 
int main(){
	int a[10]={2,1,3,4,5,6,7,8,9,0};
	Bubble_Sort(a,10);
	for(int i=0;i<10;i++){
		printf("%d ",a[i]);
	}
}

插入排序原理

  • O(n^2)相对冒泡较优化;
  • 最开始假如1个数(肯定有序),接着插入一个数,若比前一个数大,直接插入,若比前一个数小,则将前一个数后移,再将待排序的数放到这个数前;此时为有序。
  • 对一个数组进行排序类似,比如现在有10个int大的数组,设前2个为有序,第3个数小于第2个,小于第1个,所以你需要将第3个插入到第1和2两个数中间,接着,先把第3个数保存起来,即定义1个新变量,将第3个数赋值给它,
    将第2个数往后移,盖掉第3个,再用将定义的变量盖掉第2个,以此类推,使整个数组变为有序。
#include<stdio.h> 
void Insert_Sort(int a[],int n){    //插入排序
	for(int i=1;i<n;i++){
		int x=a[i];
		int j=i-1;
		for(;j>=0 && x<a[j];j--){
			a[j+1]=a[j];
		}
		a[j+1]=x;
	}
}

int main(){
	int a[10]={2,1,3,4,5,6,7,8,9,0};
	Insert_Sort(a,10);
	for(int i=0;i<10;i++){
		printf("%d ",a[i]);
	}
}

选择排序原理

  • O(n^2)相对冒泡较优化
  • 感觉这个和冒泡差不多,关键在于下标的用法,给出代码,大家自己琢磨下
#include<stdio.h>

void Selection_Sort(int a[],int n){      //选择排序
	for(int i=0;i<n-1;i++){
		int num=i;
		for(int j=i+1;j<n;j++){
			if(a[num] > a[j]) num=j;
			if(num!=i) {
				int temp=a[i];
				a[i]=a[num];
				a[num]=temp;
			}
		}
	}
}
int main(){
	int a[10]={2,1,3,4,5,6,7,8,9,0};
	Selection_Sort(a,10);
	for(int i=0;i<10;i++){
		printf("%d ",a[i]);
	}
}

快速排序原理

  • 这个之所以执行效率较高 O(logn),是因为进行了分治,也就是将整个数组分成2个,使右边的都是大于最中间的数,左边的都是小于最中间的数;
  • 再者,递归左右两边,知道整个数组有序,给出代码;
#include<stdio.h>

void Quick_Sort(int l,int r,int a[]) {   //快速排序
	int i=l,j=r;
	int mid=(i+r)/2;
	do{
		while(a[i]< a[mid]) i++;
		while(a[j]> a[mid]) j--;
		if(i<=j) {
			int temp=a[i];
			a[i]=a[j];
			a[j]=temp;
		    i++;
		    j--;
		    
		}
	}while(i<= j);
	if(l< j) Quick_Sort(l,j,a);
	if(i< r) Quick_Sort(i,r,a);	
} 
int main(){
	int a[10]={2,1,3,4,5,6,7,8,9,0};
	Quick_Sort(0,9,a);
	for(int i=0;i<10;i++){
		printf("%d ",a[i]);
	}
}

桶排序原理

  • 这个算法执行效率较高,不过空间复杂度也高,当然,现在的电脑空间换时间 肯定划算;
    • 这是桶排序的简单版本,当然对于排序简单数组等够用了,后序给出桶排序正宗版本,相对较复杂;
  • 桶排序需要另外申请数组,将要排序的数组的值存到申请数组中,并且要和申请述责的下标相等,这就要申请一个内存与 待排序数组中最大的数的值相等的数组,下面给出代码;
#include<stdio.h>

int main(){
	int a[5]={2,3,3,5,8};
	
	int b[10];
	memset(b,0,sizeof(int)*10);
	
	
	for(int i=0;i<5;i++){
		b[a[i]]++;
	}
	for(int i=0;i<10;i++){
		for(int j=0;j<b[i];j++){
			printf("%d ",i);
		}
	}
}

归并排序原理

  • 这个就需要理解了,相对较复杂,但是相应的执行效率较高;
  • 主要分为拆分和合并,最开始我也好懵,但是直到我找到一张图,瞬时恍然大悟,感觉也不过如此,下面分享给大家;

排序算法总结(精讲*C语言介绍)_C语言
排序算法总结(精讲*C语言介绍)_C语言_02

  • 下面给出代码;
#include<stdio.h>
#include<string.h>
void combine(int a[],int l,int mid,int r) {   //合并
	int b[100];
	memset(b,0,sizeof(int)*100);
	int k=0;
	int i=l,j=mid;
	while(i<mid && j<=r){
		if(a[i]<=a[j]) b[k++]=a[i++];
		else b[k++]=a[j++];
	}
	while(j<=r) b[k++]=a[j++];
	while(i<mid) b[k++]=a[i++];
	for(int i=l;i<=r;i++) a[i]=b[i-l];
}
void Guibing_Sort(int a[],int left,int right){   //拆分
	if(left==right) return ;
	
	int mid=(left + right)/2;
	Guibing_Sort(a,left,mid);
	Guibing_Sort(a,mid+1,right);
	combine(a,left,mid+1,right);
}

int main(){
	int a[10]={2,1,3,4,5,6,7,8,9,0};
	Guibing_Sort(a,0,9);
	for(int i=0;i<10;i++){
		printf("%d ",a[i]);
	}
}

欢迎指出不足的地方,谢谢浏览,互勉!