数据结构:归并排序、基数排序

1.归并排序:是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。

例:设有数列{6,202,100,301,38,8,1}

初始状态:6,202,100,301,38,8,1

第一次归并后:{6,202},{100,301},{8,38},{1},比较次数:3;

第二次归并后:{6,100,202,301},{1,8,38},比较次数:4;

第三次归并后:{1,6,8,38,100,202,301},比较次数:4;

总的比较次数为:3+4+4=11;

逆序数为14;

2.基数排序:属于“分配式排序”又称“桶子法或bin sort,顾名思义,它是透过键值的部份资讯,将要排序的元素分配至某些“桶”中,藉以达到排序的作用,基数排序法是属于稳定性的排序,其时间复杂度为O (nlog(r)m),其中r为所采取的基数,而m为堆数,在某些时候,基数排序法的效率高于其它的稳定性排序法。

附:各种排序时空复杂度对比

归并排序实现:

#include<stdio.h>
#include<stdlib.h>


void Merge(int arr[], int tmp[], int startindex,
	int mid, int  endindex)
{
	int i = startindex;
	int j = mid + 1;
	int k = startindex;
	while (i < mid + 1 && j < endindex + 1)
	{
		if (arr[i] <= arr[j])
		{
			tmp[k++] = arr[i++];
		}
		if (arr[i] > arr[j])
		{
			tmp[k++] = arr[j++];
		}
	}
	while (i < mid + 1)
	{
		tmp[k++] = arr[i++];
	}
	while (j < endindex + 1)
	{
		tmp[k++] = arr[j++];
	}
	for (int i = startindex; i <= endindex; ++i)
	{
		arr[i] = tmp[i];
	}
}

void MergeS(int arr[], int tmp[], int startindex, int endindex)
{
	if (startindex < endindex)
	{
		int mid = (startindex + endindex) / 2;
		MergeS(arr, tmp, startindex, mid);
		MergeS(arr, tmp, mid + 1, endindex);
		Merge(arr, tmp, startindex, mid, endindex);
	}
}
void MergeSort(int arr[], int len)
{
	int *tmp = (int*)malloc(sizeof(arr[0])*len);
	MergeS(arr, tmp, 0, len - 1);
	free(tmp);
}

基数排序实现:

include<stdio.h>
#include<math.h>
#include<stdlib.h>

#define MAXSIZE  10
void Show(int arr[], int len)
{
	for (int i = 0; i < len; ++i)
	{
		printf("%d ", arr[i]);
	}
	printf("\n");
}
//9031  ==>  4
int FindMaxFinger(int arr[], int len)
{
	int maxnum = arr[0];
	for (int i = 1; i < len; ++i)
	{
		if (arr[i]>maxnum)
		{
			maxnum = arr[i];
		}
	}
	int count = 0;
	while (maxnum != 0)
	{
		maxnum /= 10;
		count++;
	}
	return count;
}
//893  1  ==>  9
int FindFinNumber(int num, int fin)
{
	return num / (int)pow(10.0, fin) % 10;
}
void Radix(int arr[], int len, int fin)
{
	int backet[10][MAXSIZE] = {};
	int finnum = 0;
	int num[10] = {};
	for (int i = 0; i < len; ++i)
	{
		finnum = FindFinNumber(arr[i], fin);
		backet[finnum][num[finnum]] = arr[i];
		num[finnum]++;
	}
	int aindex = 0;
	int bindex = 0;
	for (int i = 0; i < 10; ++i)
	{
		bindex = 0;
		while (bindex != num[i])
		{
			arr[aindex++] = backet[i][bindex++];
		}
	}
}
void RadixSort(int arr[], int len)
{
	int max = FindMaxFinger(arr, len);
	for (int i = 0; i < max; ++i)
	{
		Radix(arr, len, i);
	}
}

猜你喜欢

转载自blog.csdn.net/wh_0727/article/details/83795497