C语言所有经典排序方法的实现代码

运行结果正确
还是快速排序难一些。

完整代码

#include<stdio.h>
#include <stdlib.h>
#include <string.h>
#include<malloc.h>
void swap(int *a,int *b);
void select_sort(int arr[],int n);
void tra_arr(int arr[],int n);
void insert_sort(int arr[],int n);
void shell_sort(int arr[],int n);
void perc_down(int arr[],int i,int n);
void heap_sort(int arr[],int n);
void merge(int arr[],int temp_arr[],int left_start,int right_start
			,int right_end);
void m_sort(int arr[],int temp_arr[],int left,int right);
void merge_sort(int arr[],int n);
int get_pri(int arr[],int left,int right);
void q_sort(int arr[],int left,int right);
void quick_sort(int arr[],int n);
int main(){
	int arr[100]={
		10,9,8,7,6,5,4,3,2,1
	};
	select_sort(arr,10);
	printf("\n简单选择排序结果\n");
	tra_arr(arr,10);

	int arr1[100]={
		10,9,8,7,6,5,4,3,2,1
	};
	insert_sort(arr1,10);
	printf("\n插入排序结果\n");
	tra_arr(arr1,10);

	int arr2[100]={
		10,9,8,7,6,5,4,3,2,1
	};
	shell_sort(arr2,10);
	printf("\n希尔排序结果\n");
	tra_arr(arr2,10);

	int arr3[100]={
		10,9,8,7,6,5,4,3,2,1
	};
	heap_sort(arr3,10);
	printf("\n堆排序结果\n");
	tra_arr(arr3,10);

	int arr4[100]={
		 10,9,8,7,6,5,4,3,2,1
	};
	merge_sort(arr4,10);
	printf("\n归并排序结果\n");
	tra_arr(arr4,10);

	int arr5[100]={
		 10,9,8,7,6,5,4,3,2,1
	};
	quick_sort(arr5,10);
	printf("\n快速排序结果\n");
	tra_arr(arr5,10);

	return 0;
}
void swap(int *a,int *b){
	//在函数内部,如果打算接收的是指针的地址,那就不要加*,
	//如果想要的是值,那就加*,我也很讨厌指针,但是没办法
	int t=*a;
	*a=*b;
	*b=t;
}
//简单选择排序
void select_sort(int arr[],int n){
	int min;
	//这个过程一时半会讲不清楚,看书会清楚一些
	for(int i=0;i<n;i++){
		min=i;

		for(int j=i+1;j<n;j++){
			if(arr[i]>arr[j]){
				min=j;
			}
		}
		//经过上面的里层for,就找到了最小的元素的下表
		swap(&arr[i],&arr[min]) ;
	}
}
//插入排序
void insert_sort(int arr[],int n){
	int temp,j;
	for(int i=1;i<n;i++){
		temp=arr[i];
		for(j=i;j>0&&arr[j-1]>temp;j--){
			//后挪
			arr[j]=arr[j-1];
		}
		//现在就找到空出来的插入位置了
		arr[j]=temp;
	}
}
//希尔排序
void shell_sort(int arr[],int n){
	int in,i,j,temp;
	//本来这个排序是很好理解的,就是这个外层的循环
	//故弄玄虚,你就把他理解成一个简单的,递减的数组就行
	//而且这个2的指数递减的序列的时间复杂度是很坏的
	//最好使用SED或者HIB序列会好很多,这里只是演示
	//两个里层的for就是插入排序,仔细看看就能看懂 

	for(in=n/2;in>0;in=in/2){
		for(i=in;i<n;i++){
			temp=arr[i];
			for(j=i;j>=in;j=j-in){
				if(arr[j-in]>temp){
					//后挪
					arr[j]=arr[j-in];
				}
				else{
					//arr[j-in]<temp,说明找到了
					break;
				}
			}
			//上面执行完,肯定找到了插入位置
			arr[j]=temp;
		}
	}
}
//首先是下滤操作
//i是根,n是heap的规模
//这里的下滤针对最大堆
void perc_down(int arr[],int i,int n){
	int child,temp;
	//仔细想想,其实和插入排序差不多
	//首先把i取出来,把i在堆里面所在的位置空出来
	//这里和原来建堆的下滤又不一样,这里没有设置哨兵
	for(temp=arr[i];(2*i+1)<n;i=child){
		child=2*i+1;
		//如果当前儿子不是最后一个,说明还有右儿子
		//两者取最大
		if(child!=(n-1)&&arr[child]<arr[child+1]){
			child++;
		}
		if(temp<arr[child]){
			arr[i]=arr[child];
		}
		else{
			//当前取出来的值终于大于两个儿子时。
			break;
		}

	}
	//上面轮完之后,肯定找到了一个儿子比我们取出来的值还要小的
	arr[i]=temp;
}
void heap_sort(int arr[],int n){
	int i;
	//建堆
	for(i=n/2;i>=0;i--){
		perc_down(arr,i,n);
	}
	//取最大值放在最后已经舍弃的位置上,下滤剩下的堆
	for(i=n-1;i>0;i--){
		//取最大值放在最后已经舍弃的位置上
		swap(&arr[0],&arr[i]);
		// 滤剩下的堆
		perc_down(arr,0,i);
	}
}
//归并排序
//第一步,写一个将两个已经排好序列的归并
void merge(int arr[],int temp_arr[],int left_start,int right_start
			,int right_end)
{
	int i,temp_start,elem_num,left_end;
	temp_start=left_start;
	left_end=right_start-1;
	elem_num=right_end-left_start+1;
	//归并的核心
	while(left_start<=left_end&&right_start<=right_end){
		if(arr[left_start]<=arr[right_start]){
			temp_arr[temp_start++]=arr[left_start++];
		}
		else{
			temp_arr[temp_start++]=arr[right_start++];
		}
	}
	while(left_start<=left_end){
		temp_arr[temp_start++]=arr[left_start++];
	}
	while(right_start<=right_end){
		temp_arr[temp_start++]=arr[right_start++];
	}
	//重新拷回去,记住,这里归并的只是原来数组的一部分,所以不能从头开始
	for(i=0;i<elem_num;i++,right_end--) {
		arr[right_end]=temp_arr[right_end];
	}
}
//第二步,递归调用归并,将数组不断分割
void m_sort(int arr[],int temp_arr[],int left,int right){
	//tra_arr(arr,10);
	int center;
	//递归结束条件
	if(left<right){
		center=(right+left)/2;
		m_sort(arr,temp_arr,left,center);
		m_sort(arr,temp_arr,center+1,right);
		merge(arr,temp_arr,left,center+1,right);
	}
}
//第三步,初始化临时数组
void merge_sort(int arr[],int n){
	int *temp_arr;
	temp_arr=(int*)malloc(n*sizeof(int));
	m_sort(arr,temp_arr,0,n-1);
	free(temp_arr);
} 

//快速排序
//首先,实现三数中值分割法,取一个“裁判” (中值)
int get_pri(int arr[],int left,int right){
	int center=(left+right)/2;
	if(arr[left]>arr[center]){
		swap(&arr[left],&arr[center]);
	}
	if(arr[left]>arr[right]){
		swap(&arr[left],&arr[right]);
	}
	if(arr[center]>arr[right]){
		swap(&arr[center],&arr[right]);
	}
	//把中值扔到倒数第二个,因为上述操作已经让倒数第一大于中值了
		swap(&arr[center],&arr[right-1]);

	return arr[right-1];

}
//其次,实现分而治之
void q_sort(int arr[],int left,int right){
	int i,j,pri;
	//如果规模已经小于三了,就不要再分而治之了,没得分了
	if(right-left>=3){
		//取中值
		pri= get_pri(arr,left,right);
		//取左右往中间靠拢的两个指针i,j
		i=left;
		j=right-1;
		//开始判断
		while(1){
			//如果当前i对应的值小于裁判,继续推进
			while(arr[++i]<pri);
			// 如果当前i对应的值大于裁判,继续推进
			while(arr[--j]>pri);
			//上面走完,肯定碰到硬杈了,在i和j没有错位的情况下
			//交换
			if(i<j){
				swap(&arr[i],&arr[j]);
			}
			else{
				break;
			}
		}
		swap(&arr[i],&arr[right-1]);
		//这个i的作用远不止此,这个i还记录了上一个裁判的位置
		//开始对分下来的两个部分进行同样的操作
		q_sort(arr,left,i-1);
		q_sort(arr,i+1,right);
	}
	//如果递归到规模已经无法再分了
	//就用普通的方法排序
	else{
		/*这里稍微讲一下
		数组和指针实际上是一样的东西
		到这里了,那肯定就剩一个或者两个元素了
		所以数组的开头变成left所指的位置,现在left所在位置的下标
		就是0,所以后面的n也要相应变化*/
		insert_sort(arr+left,right-left+1);
	}

}
//最后包装一下
void quick_sort(int arr[],int n){
	q_sort(arr,0,n-1);
}
//遍历数组
void tra_arr(int arr[],int n){
	for(int i=0;i<n;i++){
		printf("%d  ",arr[i]);
	}
	printf("\n");
} 

以上就是C语言所有经典排序方法的实现代码的详细内容,更多关于C语言排序方法的的资料请关注我们其它相关文章!

(0)

相关推荐

  • C语言分治法实现归并排序

    本文实例为大家分享了C语言实现归并排序的具体代码,供大家参考,具体内容如下 归并排序的基本思想: 将两个及其以上的有序表合并为一张有序表,把待排序序列通过分治法分为若干个有序子序列,然后每两个子序列合并为一个子序列,经过多次合并后整合为一张有序表. 排序过程如图: 代码如下: #include "stdio.h" #define MAX 100 int is1[MAX],is2[MAX];//原数组is1,临时空间数组is2 void merge(int low,int mid,int

  • 必须知道的C语言八大排序算法(收藏)

    概述 排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存. 我们这里说说八大排序就是内部排序. 当n较大,则应采用时间复杂度为O(nlog2n)的排序方法:快速排序.堆排序或归并排序序. 快速排序:是目前基于比较的内部排序中被认为是最好的方法,当待排序的关键字是随机分布时,快速排序的平均时间最短: 1.插入排序-直接插入排序(Straight Insertion Sort) 基本思想: 将一个记录插入到

  • C语言冒泡排序法的实现(升序排序法)

    任务代码: 数字的排序: #include <stdio.h> #define SIZE 10 int main() { int a[SIZE]={12 ,43,9,13,67,98,101,89,3,35};//十个数的无序数列 int i,j,t; printf("此程序使用冒泡排序法排列无序数列!\n"); //冒泡排序 for(i=0;i<10-1;i++)//n个数的数列总共扫描n-1次 { for(j=0;j<10-i-1;j++)//每一趟扫描到a

  • C语言简单实现快速排序

    快速排序是一种不稳定排序,它的时间复杂度为O(n·lgn),最坏情况为O(n2):空间复杂度为O(n·lgn). 这种排序方式是对于冒泡排序的一种改进,它采用分治模式,将一趟排序的数据分割成独立的两部分,其中一组数据的每个值都小于另一组.每一趟在进行分类的同时实现排序. 其中每一趟的模式通过设置key当基准元素,key的选择可以是数据的第一个,也可以是数据的最后一个.这里以每次选取数据的第一个为例: 具体代码实现: #include<stdio.h> #define N 6 int fun(i

  • C语言排序算法之插入排序

    算法实现: 使用插入排序将下面的数字按照从小到大的顺序排列 步骤1:数组中已经排好的是{1},将9插入数组中 步骤2:数组中已经排好的是{2,9},将5插入数组中 步骤3:数组中已经排好的是{2,5,9},将4插入数组中 步骤4:数组中已经排好的是{2,4,,5,9},将8插入数组中 步骤5:数组中已经排好的是{2,4,,5,8,9},将1插入数组中 步骤6:数组中已经排好的是{1,2,4,,5,8,9},将6插入数组中 步骤7:排序完成 程序代码: #include <stdio.h> #i

  • C语言实现快速排序算法

    一.快速排序算法(Quicksort) 1. 定义 快速排序由C. A. R. Hoare在1962年提出.快速排序是对冒泡排序的一种改进,采用了一种分治的策略. 2. 基本思想 通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列. 3. 步骤 a. 先从数列中取出一个数作为基准数. b. 分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全

  • C语言实现3个数从小到大排序/输出的方法示例

    前言 本文主要给大家介绍了一个功能,任意输入 3 个整数,编程实现对这 3 个整数由小到大进行排序.下面话不多少了,来一起看看详细的介绍吧 实现过程: (1)定义数据类型,本实例中 a.b.c.t 均为基本整型. (2) 使用输入函数获得任意 3 个值赋给 a.b.c. (3) 使用 if 语句进行条件判断,如果 a 大于 b,则借助于中间变量 t 互换 a 与 b 值, 依此类推比较 a 与 c.b 与 c,最终结果即为 a.b.c 的升序排列. (4) 使用输出函数将 a.b.c 的值依次输

  • C语言所有经典排序方法的实现代码

    运行结果正确 还是快速排序难一些. 完整代码 #include<stdio.h> #include <stdlib.h> #include <string.h> #include<malloc.h> void swap(int *a,int *b); void select_sort(int arr[],int n); void tra_arr(int arr[],int n); void insert_sort(int arr[],int n); void

  • C语言实现经典排序算法的示例代码

    目录 一.冒泡排序 1.原理 2.实现 3.算法分析 二.选择排序 1.原理 2.实现 3.算法分析 三.插入排序 1.原理 2.实现 3.算法分析 四.希尔排序 1.原理 2.实现 3.算法分析 总结 一.冒泡排序 1.原理 从数组的头开始不断比较相邻两个数的大小,不断将较大的数右移,一个循环后,最大数移至最后一位,无序数组规模减一.不断重复前面动作,知道数组完全有序. 2.实现 void swap(int* a, int* b) { int temp = *a; *a = *b; *b =

  • Java十大经典排序算法的实现图解

    目录 前言 一.排序算法 1.排序算法概述(百度百科) 2.<数据结构与算法>中的排序算法 3.算法分析 二.十大经典排序算法(Java开发版) 1.冒泡排序 2.快速排序 3.基数排序 4.插入排序 5.选择排序 6.希尔排序 7.归并排序 8.计数排序 9.堆排序 10.桶排序 前言 本文章主要是讲解我个人在学习Java开发环境的排序算法时做的一些准备,以及个人的心得体会,汇集成本篇文章,作为自己对排序算法理解的总结与笔记. 内容主要是关于十大经典排序算法的简介.原理.动静态图解和源码实现

  • python常用排序算法的实现代码

    这篇文章主要介绍了python常用排序算法的实现代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 排序是计算机语言需要实现的基本算法之一,有序的数据结构会带来效率上的极大提升. 1.插入排序 插入排序默认当前被插入的序列是有序的,新元素插入到应该插入的位置,使得新序列仍然有序. def insertion_sort(old_list): n=len(old_list) k=0 for i in range(1,n): temp=old_lis

  • php计数排序算法的实现代码(附四个实例代码)

    计数排序只适合使用在键的变化不大于元素总数的情况下.它通常用作另一种排序算法(基数排序)的子程序,这样可以有效地处理更大的键. 总之,计数排序是一种稳定的线性时间排序算法.计数排序使用一个额外的数组C ,其中第i个元素是待排序数组 A中值等于 i的元素的个数.然后根据数组C 来将A中的元素排到正确的位置. 通常计数排序算法的实现步骤思路是: 1.找出待排序的数组中最大和最小的元素: 2.统计数组中每个值为i的元素出现的次数,存入数组C的第i项: 3.对所有的计数累加(从C中的第一个元素开始,每一

  • C语言实现各种排序算法实例代码(选择,冒泡,插入,归并,希尔,快排,堆排序,计数)

    目录 前言 选择排序 冒泡排序 插入排序 归并排序 希尔排序 快速排序 堆排序 计数排序 总结 前言 平时用惯了高级语言高级工具高级算法,难免对一些基础算法感到生疏.但最基础的排序算法中实则蕴含着相当丰富的优化思维,熟练运用可起到举一反三之功效. 选择排序 选择排序几乎是最无脑的一种排序算法,通过遍历一次数组,选出其中最大(小)的值放在新数组的第一位:再从数组中剩下的数里选出最大(小)的,放到第二位,依次类推. 算法步骤 设数组有n个元素,{ a 0 , a 1 , - , a n } 从数组第

  • python选择排序算法的实现代码

    1.算法:对于一组关键字{K1,K2,-,Kn}, 首先从K1,K2,-,Kn中选择最小值,假如它是 Kz,则将Kz与 K1对换:然后从K2,K3,- ,Kn中选择最小值 Kz,再将Kz与K2对换.如此进行选择和调换n-2趟,第(n-1)趟,从Kn-1.Kn中选择最小值 Kz将Kz与Kn-1对换,最后剩下的就是该序列中的最大值,一个由小到大的有序序列就这样形成. 2.python 选择排序代码: 复制代码 代码如下: def selection_sort(list2):    for i in

  • JS中多层次排序算法的实现代码

    引子 排序在编程中随处可见,从开始学习变成,到项目开发,基本上或多或少会遇到一些排序问题,接下来我要写的是我在实际开发终于到的一个排序问题,一开始卡了我很久,后面随着知识积累,实践变多才解决掉了,不知道是不是我搜索关键字不对,还是其他原因,百度也没有找到这方面的内容. 数据结构和需求 var arr = [ { "soNumber" : "52085848", "item" : "313281", "amount&q

  • Javascript 数组添加一个 indexOf 方法的实现代码

    //b = ", b.join(","), ""); document.write("b.indexOf(2) = ", b.indexOf(2)); document.write("b.indexOf('嘿嘿') = ", b.indexOf('嘿嘿')); //]]> [Ctrl+A 全选 注:如需引入外部Js需刷新才能执行] 运行以上代码,即可.如果大家想看的是 javascript indexOf的使用

  • Javascript 数组添加 shuffle 方法的实现代码

    //shuffle(A) = ", shuffle(a)); if (!Array.prototype.shuffle) { Array.prototype.shuffle = function() { for(var j, x, i = this.length; i; j = parseInt(Math.random() * i), x = this[--i], this[i] = this[j], this[j] = x); return this; }; } document.write(

随机推荐