排序算法实现--C语言

选择排序
时间/空间复杂度:O(n^2) / O(1)
特点:逐个对比,简易,但是速度慢
描述:选择排序的基本算法是从待排序的区间中经过选择和交换后选出最小的数值存放到 a[0] 中,再从剩余的未排序区间中经过选择和交换后选出最小的数值存放到 a[1] 中,a[1] 中的数字仅大于 a[0],依此类推,即可实现排序。

/*******************************************************************************
*****************
* FUNCTION
*	sort
*DESCRIPTION
*	select  sort
*PARAMETERS
*	a[]	[IN]	the sort object 
*RETURNS
*	void
*****************
*******************************************************************************/

void SelectSort( int a[])
{
    
    
	int i, j, x;
	for (i = 0; i <= 9; i ++)
		for (j = i + 1;  j <= 10;  j ++)
			if (a[i] > a[j])
			{
    
    
				x = a[i];
				a[i] = a[j];
				a[j] = x;
			}
	return a;
}

冒泡排序
时间/空间复杂度:O(n^2)平均 / O(1)
特点:依次两两对比,简易,但是速度慢
描述:冒泡排序就是把小的元素往前调或者把大的元素往后调。比较是相邻的两个元素比较,交换也发生在这两个元素之间。如果要对 n 个数进行冒泡排序,那么要进行 n-1 趟比较,在第 1 趟比较中要进行 n-j 次两两比较,在第 j 趟比较中要进行 n-j 次两两比较。

/*******************************************************************************
*****************
* FUNCTION
*	sort
*DESCRIPTION
*	bubble  sort
*PARAMETERS
*	a[]	[IN]	the sort object 
*RETURNS
*	void
*****************
*******************************************************************************/

void BubbleSort (int a[])
{
    
    
	int i, j, x;
	for (i = 0; i <= 9; i ++)
		for (j = 0;  j < 9 - i;  j ++)
			if (a[j] > a[j + 1])
				{
    
    
				x = a[j];
				a[j] = a[j + 1];
				a[j + 1] = x;
				}
	return a;
}

快速排序
时间/空间复杂度:O(n〖log〗_2 n)平均 / O(n〖log〗_2 n)
特点:递归 分而治之,不易理解,速度较快
描述:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

/*******************************************************************************
*****************
* FUNCTION
*	sort
*DESCRIPTION
*	quick  sort
*PARAMETERS
*	a[]	[IN]	the sort object 
*	left	[IN]	the left boundary of a
*	right	[IN]	the right boundary of a
*RETURNS
*	void
*****************
*******************************************************************************/

void QuickSort (int a[], int left, int right)
{
    
    
	int i, j, x;
	i = left;
	j = right;
	x = a[left];
	if (left >= right)
	{
    
    
		return a;
	}
	while(i < j)
	{
    
    
		while(i < j && x <= a[j])
		{
    
    
			j --;
		}
		a[i] = a[j];
		while(i < j && x >= a[i])
		{
    
    
			i ++;
		}
		a[j] = a[i];
	}
	a[i] = x;
	QuickSort (a, left, i - 1);
	QuickSort (a, i + 1, right);
	return a;
}

合并排序
时间/空间复杂度:O(n〖log〗_2 n) / O(n)
特点:递归,先分散再合并,不易理解,速度较快
描述:(1) 将 n 个记录看成是 n 个长度为 1 的有序子表。
(2) 将两两相邻时有序无表进行合并。
(3) 重复执行步骤 (2) 直到合并成一个长度为 n 的有序表。

/*******************************************************************************
*****************
* FUNCTION
*	sort
*DESCRIPTION
*	merge  sort
*PARAMETERS
*	a[]	[IN]	the sort object 
*	L[]	[IN]	subsequence
*	R[]	[IN]	subsequence
*	l	[IN]	length of L[]
*	r	[IN]	lengtn of R[]
*	n	[IN]	length of a[]
*RETURNS
*	void
*****************
*******************************************************************************/

//Two ordered sequences L and R are merged into a,
//r and l are the length of R and L.
void Merge(int a[], int L[], int R[], int l, int r)
{
    
    
	int i= 0,j = 0,k = 0;
	//The elements of the two subsequences are compared inturn,
	//and the smaller ones are taken out and put into a.
	while(i < l && j < r)
	{
    
    
		if(L[i] <= R[j])
			a[k++] = L[i++];
		else
			a[k++] = R[j++];
	}
	//Merge the remanining elements on the left into a.
	while(i < l)
	{
    
    
		a[k++] = L[i++];
	}
	//Merge the remaining elements on the right into a.
	while(j < r)
	{
    
    
		a[k++] = R[j++];
	}
}
//Recursive body
void MergeSort(int a[],int n)
{
    
    
	if(n > 1)
	{
    
    
		int mid = n / 2;
		int i, j;
		//Allocate memory to the left and right arrays.
		//int *left = (int*)malloc(sizeof(int) * mid);
		//int *right = (int*)malloc(sizeof(int) * (n - mid));
		int left[mid];
		int right[n - mid];
		//Assign values to the left and right arrays.
		for(i = 0; i < mid; i++)
			left[i] = a[i];
		for(j = mid; j < n; j++)
			right[j] = a[j];
		//Recursion continues on the left and right arrays.
		MergeSort(left,mid);
		MergeSort(right,n - mid);
		//Merge two arrays.
		Merge(a,left,right,mid,n - mid);
		//free(left);	//Free memory
		//free(right);
	}
	return a;
}

插值排序
时间/空间复杂度:O(n^2)平均 / O(1)
特点:依次往前比较插值,简易,速度取决于对象的有序程度
描述:插入排序是把一个记录插入到已排序的有序序列中,使整个序列在插入该记录后仍然有序。插入排序中较简单的种方法是直接插入排序,其插入位置的确定方法是将待插入的记录与有序区中的各记录自右向左依次比较其关键字值的大小。

/*******************************************************************************
*****************
* FUNCTION
*	sort
*DESCRIPTION
*	interpolation sort
*PARAMETERS
*	a[]	[IN]	the sort object 
*	n	[IN]	length of a
*	step	[IN]	interval
*RETURNS
*	void
*****************
*******************************************************************************/

//Step size can be spacified for improved version InterpolationSort.
int InterpolationSortPlus(int a[], int n ,int step)
{
    
    
	int i, j;

	for (i = step; i < n; i++)
	{
    
    
		//compare the inserted values step by step forward.
		for (j = i; j >= step  && a[j] < a[j - step]; j -= step)	
		{
    
    
			int x = 0;
			x = a[j];
			a[j] = a[j - step];
			a[j - step] = x;
		}
	}
	return a;
}

希尔排序
时间/空间复杂度:O(n^2)平均 / O(1)
特点:在插值排序的基础上,针对对象的有序程度进行调整。
描述:希尔排序是在直接插入排序的基础上做的改进,也就是将寒排序的序列按固定增量分成若干组,等距者在同二组中,然后再在组内进行直接插入排序。这里面的固定增量从 n/2 开始,以后每次缩小到原来的一半。

/*******************************************************************************
*****************
* FUNCTION
*	sort
*DESCRIPTION
*	shell  sort
*PARAMETERS
*	a[]	[IN]	the sort object 
*	n	[IN]	length of a
*RETURNS
*	void
*****************
*******************************************************************************/

//Shell sort calls InterpolationSortPlus.
int ShellSort(int a[], int n)
{
    
    
	int step;	//Set a step size.
	for (step = n / 2;  step >0 ;  step /= 2)
	{
    
    	
		InterpolationSortPlus(a, n, step);
	}
	return a;
}

计数排序
时间/空间复杂度:O(n + k) / O(n + k)
特点:不用比较数值,简易,小范围内排序比较快。
描述:1、找出待排序的数组中最大和最小的元素;
2、统计数组中每个值为i的元素出现的次数,存入数组C的第i项;
3、对所有的计数累加(从C中的第一个元素开始,每一项和前一项相加);
4、反向填充原排序数组

/*******************************************************************************
*****************
* FUNCTION
*	sort
*DESCRIPTION
*	counter  sort
*PARAMETERS
*	a[]	[IN]	the sort object 
*	n	[IN]	length of a
*RETURNS
*	void
*****************
*******************************************************************************/			

void CounterSort(int a[], int n)
{
    
     

	//The maximum and minimum values of the sequence are obtained
	//and the differential value d is calculated.
	int max, min, i, d;
	max = a[0];
	min = a[0];
	for ( i = 1; i < n; i++) 
	{
    
    
            		if (a[i] > max)
		 {
    
    
                		max = a[i];
           		 }
            		if(a[i] < min)
		 {
    
    
                		min = a[i];
           		 }
       	 }
	d = max - min;

	//Create and initializes an array of size d.
	int *c = (int*)malloc(sizeof(int) * (d + 1));
	for ( i = 0; i < d +1; i ++)
	{
    
    
		c[i] = 0;
	}
	
	//count the number of corresponding indexes.
	for ( i = 0; i < n; i++)
	 {
    
    
            		c[a[i] - min] = c[a[i] - min] + 1;
       	 }

	//Assign value in turn according to statistical quantities.
	for (i =0; i < n; )
		for (int j = 0; j < d +1; j ++)
		{
    
    
			if (c[j] > 0)
			{
    
    
				for ( int t = 0; t < c[j]; t ++)
				{
    
    
					a[i] = j + min;
					i ++;
				}
			}
		}
	
	free(c);
	return a;
}

桶排序
时间/空间复杂度:O(n + k)平均 / O(n + k)
特点:不用比较数值,较为复杂,排序比较快。
描述:桶排序是计数排序的升级版。它利用了函数的映射关系,高效与否的关键就在于这个映射函数的确定。桶排序的工作的原理:假设输入数据服从均匀分布,将数据分到有限数量的桶里,每个桶再分别排序(有可能再使用别的排序算法或是以递归方式继续使用桶排序进行排)。

本文参考多本书和多个网站,具体已无可循。若有冒犯,请联系,删除。

猜你喜欢

转载自blog.csdn.net/Fighting_gua_biu/article/details/112259339
今日推荐