目录
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
时间可以磨平所有棱角!