排序算法(3)

排序算法(3)

归并排序

算法描述:将待排序的元素序列分为两个长度相等的子序列,对每个子序列进行排序,然后将他们合并成一个序列,合并两个子序列的过程称为二路归并.

#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#include<string.h>
#include<assert.h>
//归并
void MergeData(int *arr,int left,int mid,int right,int *temp){
	int temp_index = left;
	int left_L = left;
	int left_R = mid;
	int right_L = mid;
	int right_R = right;
	while (left_L<left_R && right_L<right_R)
	{
		if (arr[left_L]<arr[right_L])
		{
			temp[temp_index++] = arr[left_L++];
 
		}
		else
		{
			temp[temp_index++] = arr[right_L++];
		}
 
	}
	while(left_L<left_R)
	{
		temp[temp_index++] = arr[left_L++];
	}
	while (right_L<right_R)
	{
		temp[temp_index++] = arr[right_L++];
	}
 
}
//分组
//void *memcpy(void*dest, const void *src, size_t n);
//由src指向地址为起始地址的连续n个字节的数据复制到以dest指向地址为起始地址的空间内。
void _MergeSort(int *arr, int left, int right, int *temp){
	if ((right-left)>1)
	{
		int mid = left + ((right-left)>>1);
		_MergeSort(arr,left,mid,temp);
		_MergeSort(arr, mid, right, temp);
		MergeData(arr,left,mid,right,temp);
		memcpy(arr+left,temp+left,sizeof(int)*(right-left));
	}
 
 
}
//递归
void MergeSort(int *arr,int size){
	int *temp = (int *)malloc(size*sizeof(arr[0]));
	if (temp==NULL)
	{
		assert(0);
		return;
	}
	_MergeSort(arr,0,size,temp);
	free(temp);
}
//非递归
void MergeSort_Nor(int *arr, int size){
	int *temp = (int *)malloc(size*sizeof(arr[0]));
	if (temp == NULL)
	{
		assert(0);
		return;
	}
	int i = 0;
	int gap = 1;
	while (gap<size)
	{
		for (i = 0; i < size;i+=2*gap){
			int left = i;
			int mid = left + gap;
			int right = mid + gap;
			if (mid>size)
			{
				mid = size;
			}
			if (right>size)
			{
				right = size;
			}
			MergeData(arr, left, mid, right, temp);
		}
		memcpy(arr,temp,size*sizeof(arr[0]));
		gap=gap*2;
	}
	free(temp);
}
int main(){
	int arr[10] = { 2, 0, 4, 9, 3, 6, 8, 7, 1, 5 };
	int size = sizeof(arr) / sizeof(arr[0]);
	MergeSort(arr,size);
	//MergeSort_Nor(arr, size);
	for (int i = 0; i < size; i++)
	{
		printf("%d ", arr[i]);
	}
	system("pause");
	return 0;
}

计数排序

算法描述:找到待排序列中最大最小的元素,然后以此确定临时空间的大小,在临时空间中,以待排序列组中元素的大小为下标,该元素出现的次数为该下标对应的元素,根据临时空间的统计结果,重新对元素进行回收.

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<string.h>
#include<malloc.h>
int GetMaxValue(int *arr,int size){
	int i = 0;
	int max = arr[0];
	for ( i = 1; i < size; i++)
	{
		if (arr[i]>max)
			max = arr[i];
	}
	return max;
 
}
int GetMinValue(int *arr, int size){
	int i = 0;
	int min = arr[0];
	for (i = 1; i < size; i++)
	{
		if (arr[i]<min)
			min = arr[i];
	}
	return min;
 
}
void _Count_Sort(int *arr, int *temp,int size,int ret,int min){
	int i = 0;
	int index = 0;
	//统计个数
	for ( i = 0; i < size; i++)
	{
		temp[arr[i]-min]++;
	}
	//回收,把temp里的数据回收到原空间里
	for ( i = 0; i <ret ; i++)
	{
		while (temp[i]--)
		{
			arr[index++] = i+min;
		}
	}
	free(temp);
}
void Count_Sort(int *arr,int size){
	int max = GetMaxValue(arr,size);
	int min = GetMinValue(arr, size);
	int ret = max - min + 1;
	int *temp = (int *)malloc(ret*sizeof(arr[0]));
	if (temp==NULL)
	{
		assert(0);
		return;
	}
	//memset作用是在一段内存块中填充某个给定的值,它是对较大的结构体或数组进行清零操作的一种最快方法
	memset(temp,0,ret*sizeof(int));
    _Count_Sort(arr,temp,size,ret,min);
}
int main(){
	int i = 0;
	int arr[10] = {3,4,3,2,1,2,6,5,4,7};
	int size = sizeof(arr) / sizeof(arr[0]);
    Count_Sort(arr,size);
	for ( i = 0; i < size; i++)
	{
		printf("%d ", arr[i]);
	}
	system("pause");
	return 0;
}

基数排序

算法描述:把待排序中的元素按照低位先排序,然后收集,再按照高位排序,再收集,直至最高位.①,获取序列中的最大数,然后取得其位数,然后利用计数排序的特点,定义10个元素的数组,分别统计以待排序列元素的每一位为数组的下标的元素的个数,然后再定义一个数组存每个的起始地址.开一个辅助空间,放置元素.再回收这些元素.

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<malloc.h>
#include<string.h>
//统计最大元素的位数
int GetMaxValue_BitCount(int *arr,int size){
	int i = 0;
	int count = 1;
	int ret = 10;
	for ( i = 0; i < size; i++)
	{
		while (arr[i] >= ret)
		{
			count++;
			ret *= 10;
		}
	}
	return count;
}
void _RadixSort(int *arr,int size,int *temp){
	int Max_BitCount = GetMaxValue_BitCount(arr, size);
	//存每个桶中元素的个数.
	int count[10] = { 0 };
	//存每个桶的起始地址
	int start_Addr[10] = { 0 };
	int i = 0;
	int ret = 1;
	int index = 0;
	while (Max_BitCount)
	{
		//统计个数
		for ( i = 0; i < size; i++)
		{
			count[arr[i] / ret % 10]++;
		}
		//计算地址
		for ( i = 1; i < 10; i++)
		{
			start_Addr[i] = start_Addr[i - 1] + count[i - 1];
		}
		//放置元素到临时空间中
		for (i = 0; i <size; i++){
			int Addr = arr[i]/ret% 10;
			temp[start_Addr[Addr]++] = arr[i];
		}
		//回收元素
		//memcpy函数的功能是从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中。
		//void *memcpy(void *dest, const void *src, size_t n);
		memcpy(arr,temp,size*sizeof(arr[0]));
		ret *= 10;
		Max_BitCount--;
	}
 
}
void RadixSort(int *arr,int size){
	int *temp = (int *)malloc(size*sizeof(arr[0]));
	if (temp==NULL)
	{
		assert(0);
		return;
	}
	_RadixSort(arr,size,temp);
	free(temp);
}
int main(){
	int arr[11] = {198,254,378,852,761,554,581,552,605,479,853};
	int size = sizeof(arr) / sizeof(arr[0]);
	RadixSort(arr,size);
	for (int  i = 0; i < size; i++)
	{
		printf("%d ", arr[i]);
	}
	system("pause");
	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值