c语言的各类排序

排序的概念:
1.排序就是将一组没有规律的数据按照一定的规律进行(升序/降序)排序。
2.一个元素数列如果两个元素A,B。如果在排序之前A在B的前面,在排序之后A依然在B的前面。那么我们就说这个排序算法是稳定的。

常见的排序算法:

在这里插入图片描述

1.插入排序:
《1》直接插入排序:
在这里插入图片描述
直接插入代码如下:

void Insertsort(int arry[],int size)
{
	int key;
	int i, j;
	for (i = 1; i < size; i++)
	{
		key = arry[i];
		for (j = i - 1; j >= 0; j--)
		{
			if(key>=arry[j])
				{
                   break;
				}
			else
			{
				arry[j + 1] = arry[j];
			}
		}
		arry[j + 1] = key;
	}
}

《2》希尔排序:
在这里插入图片描述

希尔排序代码如下:

void elseInsertsort(int array[], int size, int gap)
{
	int key;
	int i, j;
	for (i = gap; i < size; i++) {
		key = array[i];
		for (j = i - gap; j >= 0; j -= gap) {
			if (key >= array[j]) {
				break;
			}
			else {
				array[j + gap] = array[j];
			}
		}

		array[j + gap] = key;
	}
}
void Shellsort(int arry[],int size)
{
	int gap = size;
	while (1)
	{
		gap = gap / 3 +1;
		elseInsertsort(arry, size, gap);
		if (gap == 1)
		{
			break;
		}

	}
}

2.选择排序:
《1》.直接选择排序
在这里插入图片描述
直接选择排序代码《1》如下:

void Directsort(int array[], int size)
{
	int i, j;
	for(i=size;i>0;i--)
	{
		int max = 0;
		for (j = 0; j < i; j++)
		{
			if (array[j] > array[max])
				max = j;
		}
		swap(array + max, array + i-1);
	}
}

为了使每一次的循环效率更高,我们可以在每一次循环同时找到最小值和最大值,则直接排序的优化版本如下:

void Directsort1(int array[], int size)
{
	int left = 0;
	int right = size-1;
	while (left < right)
	{
		int j;
		int min = left;
		int max = left;
		for (j = left + 1; j <= right; j++)
		{
			if (array[j] > array[max])
			{
				max = j;
			}
			if (array[j] < array[min])
			{
				min = j;
			}
		}
		swap(array + left, array + min);
		   if(max==left)
			{
			   max=min;
			}
			swap(array + right, array + max);
			left++;
			right--;
	}
}

《2》堆排序
在这里插入图片描述
堆排序排序代码如下:

void AdjustDown(int array[], int size, int root)
{
	int left = root * 2 +1;
	int right = root * 2 +2;
	if (left >= size)
	{
		return;//左孩子超出数组了,跳出
	}
	int max = left;
	if (right<size&&array[right]>array[left])
	{
		max = right;
	}
	if (array[root] >= array[max])
	{
		return;
	}
	swap(array + root, array + max);
	AdjustDown(array, size, max);

}
void CreatHeap(int array[], int size)
{
	int i;
	for (i = size / 2 - 1; i >= 0; i--)
	{
		AdjustDown(array, size, i);
	}
}
void Heapsort(int array[], int size)
{
	CreatHeap(array, size);//创建大堆
	int i;
	for (i = 0; i < size; i++)
	{
		swap(&array[0], &array[size - 1 - i]);
		AdjustDown(array, size - i - 1, 0);
	}
}

3.交换排序
1》冒泡排序
在这里插入图片描述
冒泡代码如下:

void Bubbsort(int array[],int size)
{
	int i;
	int j;
	for ( i = 0; i < size - 1; i++)
	{
		int cur = 1;//用来记录是否已经有序,若已经有序,则直接跳出
		for (j = 0; j < size - 1 - i; j++)
		{
			if (array[j] > array[j + 1]) 
			{
				swap(array + j, array + j + 1);
				cur = 0;
			}
		}
		if (cur == 1) {
			break;
		}
	}
}

2》快速排序
在这里插入图片描述
快速排序代码如下:


int seachdel3(int array[], int left, int right)
{
	int cur, div;

	for (cur = left, div = left; cur < right; cur++)
	{
		if (array[cur] < array[right]) 
		{
			Swap(array + cur, array + div);
			div++;
		}
	}

	Swap(array + div, array + right);

	return div;
}
int seachdel2(int array[], int left, int right)
{
	int begin = left;	
	int end = right;	
	int pivot = array[right];		

	while (begin < end)
	{
		
		while (begin < end && array[begin] <= pivot)
		{
			begin++;
		}

		array[end] = array[begin];

		while (begin < end && array[end] >= pivot)
		{
			end--;
		}

		array[begin] = array[end];
	}

	array[begin] = pivot;

	return begin;
}
int  seachdel1(int array[],int left,int right)
{
	int begin = left;	
	int end = right;	
	int del = array[right];		

	while (begin < end)
	{
		while (begin < end && array[begin] <= del) {
			begin++;
		}

		array[end] = array[begin];

		while (begin < end && array[end] >= del) {
			end--;
		}

		array[begin] = array[end];
	}

	array[begin] = del;
	return begin;
}
void _quicksort(int array[], int left, int right)
{
	if (left >= right)
	{
		return;
	}
	int del = seachdel1(array, left, right);
	_quicksort(array, left, del-1);
	_quicksort(array, del + 1, right);

}

void Quicksort(int array[],int size)
{
	_quicksort(array, 0, size - 1);
}

归并排序:

在这里插入图片描述
归并排序代码如下:


void merge(int array[], int left, int mid, int right, int extra[])
{
	int left_i=left;//左区间第一个下标
	int right_i = mid;//右区间第一个下标
	int extra_i = left;//临时储存第一个下标
	while (left_i < mid && right_i < right) {
		if (array[left_i] <= array[right_i]) {
			extra[extra_i++] = array[left_i++];
		}
		else {
			extra[extra_i++] = array[right_i++];
		}
	}
	while (left_i < mid) 
	{
		extra[extra_i++] = array[left_i++];
	}

	while (right_i < right)
	{
		extra[extra_i++] = array[right_i++];
	}

	for (int i = left; i < right; i++)
	{
		array[i] = extra[i];
	}
}
void _Mergesort(int array[],int left,int right,int extra[])
	{
		if (left >= right)
		{
			return;//区间内没有元素
		}
		if (left == right - 1)
		{
			return;//区间剩一个元素了,不用在排序了
		}
		int mid = left + (right - left )/ 2;
		_Mergesort(array, left, mid, extra);
		_Mergesort(array, mid, right, extra);
		merge(array, left, mid, right, extra);
	}
void Mergesort(int array[], int size)
{
	int *extra = (int *)malloc(sizeof(int)*size);//申请的空间
	_Mergesort(array, 0, size, extra);
	free(extra);
}
void Mergesort2(int array[],int size)
{
	int i;
	int j;
	int *extra = (int *)malloc(sizeof(int)*size);
	for (i = 1; i < size; i *= 2)
	{
		for (j = 1; j < size; j = j + i * 2)
		{
			int left = i;
			int mid = i + j;
			int right = mid + i;
			if (mid >= size)
			{
				continue;
			}

			if (right > size) 
			{
				right = size;
			}
			merge(array, left, mid, right, extra);
		}
	}
	free(extra);
}

总结如下:
(1)若n较小,可采用直接插入或直接选择排序。
(2)若文件初始状态基本有序,则应选用直接插人、冒泡或随机的快速排序。
(3)若n较大,则应采用排序方法:快速排序。
 快速排序是目前基于比较的内部排序中被认为是最好的方法,当待排序的关键字是随机分布时,快速排序的平均时间最短。
 复杂度和稳定性如下:
 
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值