C语言排序:交换排序、原位排序、关键字索引统计、快速排序、三路划分的快速排序。

目录

1、交换排序

2、原位排序

3、关键字索引统计

4、快速排序

5、三路划分的快速排序


1、交换排序

#include<stdio.h>

#define comp(A,B) (A)>(B)
#define exch(A,B) {int c = A; A = B; B = c;}

int main(void)
{
	int i, j;
	int numb[10];
	for (i = 0; i < 10; i++)
	{
		scanf_s("%d", &numb[i]);
	}

	for (i = 0; i <10; i++)
	{
		for (j = i + 1; j < 10; j++)
		{
			if (comp(numb[i], numb[j]))
				exch(numb[i], numb[j]);
		}
	}

	for (i = 0; i < 10; i++)
	{
		printf("%d  ", numb[i]);
	}
}

2、原位排序

/*6.14 原位排序要知道数组data排序后的第几位元素,在data(没排序)中的位置,并记录在a数组中*/

#include<stdio.h>
#define N 10

int main()
{
	int data[10] = { 5,7,1,0,9,6,8,3,2,4 }; //比如5是data的第一位,对应a中为3,
	int a[10]   =  { 3,2,8,7,9,0,5,1,6,4 }; //则data的第1个最小数据,在data的第3个
	int i, j, k;

	for (i = 0; i < 10; i++)
	{
		int numb = data[i];
		for (k = i; a[k] != i; k = a[j], a[j] = j)
		{
			j = k;
			data[k] = data[a[k]];
		}
		data[k] = numb;
		a[k] = k;  //对a排序
	}

	printf("data:");
	for (i = 0; i < 10; i++)
	{
		printf("%d  ", data[i]);
	}
	printf("\n");
	printf("   a:");
	for (i = 0; i < 10; i++)
	{
		printf("%d  ", a[i]);
	}

	return 0;
}

3、关键字索引统计

适用于重复数据多的。

/*关键字排序适用于,数据重复次数多的类型*/
#include<stdio.h>

int main()
{
	int a[15] = { 0,3,3,0,1,1,0,3,0,2,0,1,1,2,0 }; //0有6个,1有4个,2有2个,3有3个。
	int i, j, b[15] = { 0 }, c[15];
	
	//对a中数据统计出现的次数,记录在b[a+1]中,如0,有6个,则b[1] = 6
	for (i = 0; i < 15; i++)
		b[a[i]+1]++;
	
	//输出数组b
	printf("第一次循环数组b:");
	for (i = 0; i < 15; i++)
		printf("%-3d", b[i]);
	printf("\n");

	//确定a中数据对应c数组中的位置范围,如0,在c中的位置为0~~5
	for (i = 1; i < 15; i++)
		b[i] = b[i] + b[i - 1];

	//输出数组b
	printf("第二次循环数组b:");
	for (i = 0; i < 15; i++)
		printf("%-3d", b[i]);
	printf("\n");

	//把a的数据,在c中排好
	for (i = 0; i < 15; i++)
		c[b[a[i]]++] = a[i];  //数组b中的数据会变

	printf("第三次循环数组b:");
	for (i = 0; i < 15; i++)
		printf("%-3d", b[i]);
	printf("\n");
	
	for (i = 0; i < 15; i++)
		a[i] = c[i];

	printf("          数组a:");
	for (i = 0; i < 15; i++)
		printf("%-3d", a[i]);
	printf("\n");
	
}

4、快速排序

/*
快速排序
第一次进入Partition,把比16小的放在左边,大的放在右边,
最后再把16与比16大的(该数的左边是比16小的数)交换位置,
确定了16在数组中的最终位置,该位置不变。
再分为16左边、16右边的进行分类,再次确定下一个数的位置。
*/
#include<stdio.h>
#define less(A,B) (A) < (B)                  //比较,A<B返回 1
#define exch(A,B) {int c = A; A = B; B = c;} //交换

int Partition(int a[], int head, int end);
void QuickSort(int a[], int head, int end);

int main()
{
	int a[10] = { 12,44,54,21,2,6,87,5,22,16 };
	QuickSort(a, 0, 9);

	for (int i = 0; i < 10; i++)
	{
		printf("%d  ", a[i]);
	}
	printf("\n");
}

/*区域划分*/
void QuickSort(int a[], int head, int end)
{
	int i;
	if (end <= head)
		return;
	i = Partition(a, head, end);
	QuickSort(a, head, i-1);
	QuickSort(a, i + 1, end);
}

/*分类,把数分为左边比它小的,右边比它大的*/
int Partition(int a[], int head, int end)
{
	int i = head - 1, j = end;
	int numb = a[end];
	for (;;)
	{                                 //第一次进入的效果:
		while (less(a[++i], numb));   // a[i]: 44 54 21 21   12 5 6 2 21 54 87 44 22 16
		while (less(numb, a[--j]))    // a[j]: 5  6  2  16   12 5 6 2 16 54 87 44 22 21
		{
			if (j == head)
				break;
		}
		if (i >= j)
			break;
		exch(a[i], a[j]);
	}
	exch(a[i], a[end]);
	return i;
}

5、三路划分的快速排序

适用于重复数据多的。

/*
三路划分的快速排序
*/
#include<stdio.h>
#define less(A,B) (A) < (B)                  //比较,A<B返回 1
#define exch(A,B) {int c = A; A = B; B = c;} //交换

void QuickSort(int a[], int head, int end);

int main()
{
	int a[15] = { 1,1,3,4,1,2,3,4,2,3,4,0,0,1,2 };

	for (int i = 0; i < 15; i++){
		printf("%d  ", a[i]);
	}
	printf("\n");
	QuickSort(a, 0, 14);

	for (int i = 0; i < 15; i++){
		printf("%d  ", a[i]);
	}
	printf("\n");
}

/*区域划分*/
void QuickSort(int a[], int head, int end)
{
	int i, j, k, p, q;
	int v;
	if (end <= head){
		return;
	}
	v = a[end];
	i = head - 1;
	j = end;
	p = head - 1;
	q = end;
	while (1)
	{
		while (less(a[++i], v));
		while (less(v, a[--j])) {
			if (j == head)
				break;
		}

		if (i >= j)
			break;
		exch(a[i], a[j]);

		if (a[i] == v) {
			p++;
			exch(a[p], a[i]);
		}
		if (v == a[j]) {
			q--;
			exch(a[q], a[j]);
		}
	}

	exch(a[i], a[end]);

	for (int i = 0; i < 15; i++)
	{
		printf("%d  ", a[i]);
	}
	printf("\n");

	j = i - 1;
	i = i + 1;

	for (k = head; k < p; k++, j--) {
		exch(a[k], a[j]);
	}
	for (k = end - 1; k > q; k--, i++) {
		exch(a[k], a[i]);
	}

	QuickSort(a, head, j);
	QuickSort(a, i, end);
}

1、运行输出

1  1  3  4  1  2  3  4  2  3  4  0  0  1  2 //首先先确定元素位置 .
2  1  1  0  1  0  1  2  3  3  4  3  4  2  4 //再分为三路,把比该数据大的放右边,小的放左边.
1  0  0  1  1  1  2  2  3  3  4  3  4  2  4 //再递归到 end <= head.
0  0  1  1  1  1  2  2  3  3  4  3  4  2  4
0  0  1  1  1  1  2  2  3  3  4  3  4  2  4
0  0  1  1  1  1  2  2  3  3  2  3  4  4  4
0  0  1  1  1  1  2  2  2  3  3  3  4  4  4
0  0  1  1  1  1  2  2  2  3  3  3  4  4  4
0  0  1  1  1  1  2  2  2  3  3  3  4  4  4
0  0  1  1  1  1  2  2  2  3  3  3  4  4  4

时间可以磨平所有棱角!

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值