常用的8种排序算法(C语言)

1. 冒泡排序

#include <stdio.h>
int main(void)
{
	int a[10] = {1,2,3,4,5,6,7,8,9,10};
	int len = sizeof(a) / sizeof(a[0]);
	/* 大循环len-1次即可 */
	for(int i=0; i<len-1; i++){
		/*相邻交换小循环,随着最大值到最后确定,循环次数变少*/
		for(int k=0; k<len-1-i; k++){
			if(a[k] < a[k + 1]){
				/*交换*/
				int temp = a[k];
				a[k] = a[k+1];
				a[k+1] = temp;
			}
		}
	}
	for(int i=0; i<len; i++){
		printf("%d ", a[i]);
	}
	return 0;
} 

2. 选择法排序

#include <stdio.h>
int main(void)
{
	int a[10] = {1,2,3,4,5,6,7,8,9,10};
	int len = sizeof(a) / sizeof(a[0]);
	/*大循环len-1次即可*/
	for(int i=0; i<len-1; i++){
		/*每次判断最大数,依次往前放*/
		for(int k=i+1; k<len; k++){
			if(a[i] < a[k]){
				int temp = a[i];
				a[i] = a[k];
				a[k] =temp;
			}
		}
	}
	/*输出*/
	for(int i=0; i<len; i++){
		printf("%d ", a[i]);
	}
	return 0;
} 

3. 插入法排序

#include <stdio.h>
int main(void)
{
	int a[10] = {1,2,3,4,5,6,7,8,9,10};
	int i, j;
	int len = sizeof(a) / sizeof(a[0]);
	for(i=1; i<len; i++){
		/*等待插入的值*/
		int wait = a[i];
		/*寻找插入点*/
		for(j=i-1; j>=0; j--){
			if(a[j] < wait){
				a[j + 1] = a[j];
			}
			else{
				break;
			}
		}
		/*出循环时 j 要减 1, 所以a[j+1]是插入的地方*/
		a[j + 1] = wait;
	}
	/*输出*/	
	for(i=0; i<len; i++){
		printf("%d ", a[i]);
	}
	return 0;
}

4. 折半法排序

#include <stdio.h>
void binary_insert_sort(int a[], int len);
int main(void)
{
	int a[] = {73,108,112,118,101,70,105,115,104,67,46,99,111,109};
	int i, len;
	len=sizeof(a) / sizeof(a[0]);
	
	binary_insert_sort(a, len);
	
	for(i=0; i<len; ++i){
		printf("%d ",a[i]);
	}		
	return 0; 
}

void binary_insert_sort(int a[], int len){
	int low, mid, high;
	/*和插入排序差不多,也是将第二个元素先作为待插入元素*/
	/*只不过在寻找插入位置的时候利用折半查找法*/
	for(int i=1; i<len; ++i){
		int temp = a[i];
		low = 0;
		high = i - 1;
		while(low <= high){     		/*这里是 <= 不要搞错,可以举个栗子试试*/
			mid = (low + high) / 2;	
			if(temp < a[mid]){
				high = mid - 1;
			}		
			else{
				low = mid + 1;
			}
		}
		
		for(int j=i-1; j>high; --j){  	/* hight + 1 即为正确位置的下标*/ 
			a[j + 1] = a[j];
		}
		a[high + 1] = temp;
	}
}

5. 希尔排序

#include <stdio.h>
int main(void)
{
	int a[10] = {1,2,3,4,5,6,7,8,9,10};
	int i, j, step;
	int len = sizeof(a) / sizeof(a[i]);
	for(int step=len/2; step>0; step/=2){/*步长*/
	
		for(i=0+step; i<len; i+=step){/*不是加 1 了,而是加步长*/
			int wait = a[i]; /*等待插入的数*/
			for(j=i-1; j>=0; j--){
				if(a[j] < wait){
					a[j + 1] = a[j];
				}
				else{
					break;
				}
			}
			a[j + 1] = wait;
		} 
	} 
	/*输出*/	
	for(i=0; i<10; i++){
		printf("%d ", a[i]);
	}
	return 0;
}

6. 桶排序

#include <stdio.h>
int searchMax(int a[], int len);
int main(void)
{
	int max, len;
	int a[11] = {1,2,3,4,5,6,7,8,9,10,40};
	len = sizeof(a) / sizeof(a[0]);
	max = searchMax(a, len);
	int bucket[max + 1] = {0};/*创建 max + 1 个桶*/
	/*变长数组是c99以后的新增特性,传入的并非变量,而是数值*/
	for(int i=0; i<len; i++){
		bucket[a[i]]++;
	}	
	/*输出*/
	for(int i=max; i>0; i--){
		for(int k=bucket[i]; k>0; k--){/*考虑重复的数字*/
			printf("%d ", i);/*输出桶的序号*/
		}
	}
	return 0;
} 
/*寻找最大数*/
int searchMax(int a[], int len){
	int max = a[0];
	for(int i=1; i<len; i++){
		if(a[i] > max){
			max = a[i];
		}
	}
	return max;
}

7. 快速排序

//递归的典型应用 
//二十世纪十大算法之一 
#include <stdio.h>
void quick_sort(int a[], int left, int right);

int main(void)
{
	int a[] = {73, 108, 112, 118, 101, 70, 105, 115, 104, 67, 46, 99, 111, 109};
	int i, len;
	len = sizeof(a) / sizeof(a[0]);
	quick_sort(a, 0, len-1);
	for(i=0; i<len; i++){
		printf("%d ", a[i]);
	}		
	return 0; 
}

void quick_sort(int a[],int left, int right){
	int i = left, j = right;
	int key;
	key = a[(left + right) / 2];
	while(i <= j){
		/* 从左到右找到大于基准点的元素*/
		 while (a[i] < key){
		 	i++;
		  } 
		  
		/* 从右到左找到大于基准点的元素*/
		while (a[j] > key) {
			j--;
		}
		
		/* 如果 i<=j,则互换 */
		if (i <= j) {
			int temp = a[i];
			a[i++] = a[j];
			a[j--] = temp;
		} 		
	}
	
	if(j > left) {
		quick_sort(a, left, j);
	}
	
	if(i < right) {
		quick_sort(a, i, right);
	}
}

8. 堆排序

  1. 父结点索引:(i - 1) / 2(这里计算机中的除以2,省略掉小数)
  1. 左孩子索引:2 * i + 1
  1. 右孩子索引:2 * i + 2
  1. 最后一个父节点:n / 2 - 1
#include <stdio.h>
void creat_heap(int a[], int len);/*创建堆*/
void adjust(int a[], int root, int len); /*创建堆的过程*/
void heap_sort(int a[], int len);/*排序*/
void swap(int *a, int step1, int step2);/*交换数组中的两个数*/

int main (void) {
	int a[] = {73,108,112,118,101,70,105,115,104,67,46,99,111,109};
	int len = sizeof(a) / sizeof(a[0]);
	
	heap_sort(a, len);
	
	for(int i=0; i<len; i++){
		printf("%d ", a[i]);
	}
	return 0;
}

/*调整堆*/
void adjust_heap(int a[], int i, int len){
	int j = i*2+1;  /*左孩子引索*/
	while(j < len){
		/*建立大堆,将 j 取值为左右孩子中大孩子的下标 */
		if(j+1<len && a[j] < a[j + 1]){
			j++;
		}
		/*判断若父节点大于两个孩子节点,则无需交换*/
		if(a[i] > a[j]){
			break;/*说明该父结点和其孩子结点调整结束,退出循环,从下一个父结点调整*/ 
		} 
		/* 交换之后还要考虑该目前j结点与自己的孩子结点的数值比较,还要进行调整,将i当前结点换成j结点所在位置*/
		swap(a, i, j);
		i = j;
		j = 2*i+1;
	} 
}

/*创建一个堆*/
void creat_heap(int a[], int len){
	int i;
	for(i=len/2-1; i>=0; i--){
		adjust_heap(a, i, len);
	}
}

/*交换两个元素*/
void swap(int *a, int step1, int step2) {
    int temp = *(a+step1);
    *(a+step1) = *(a+step2);
    *(a+step2) = temp;
}
/*排序*/
void heap_sort(int a[], int len){
	creat_heap(a, len);
	/*每次排出最大的一个元素之后,将该元素排除在堆外,调整堆后交换堆顶元素和堆的最后一个元素*/
	/*从最后一个开始*/
	for(int i=len-1; i>=0; i--){
		swap(a, i, 0);
		/*交换好堆后,重新调整堆*/
		adjust_heap(a, 0, i);
	}													
}					

  1. 我喜欢他这个动画:https://www.jianshu.com/p/0d383d294a80
    在这里插入图片描述

  2. 先去大佬那看看啥是堆

  3. 大佬的图解

  4. 实在不行去bi站看一眼:https://www.bilibili.com/video/av62952101/?spm_id_from=333.788.videocard.1

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值