目录
排序算法图解
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[j-1], numb[j]))
exch(numb[j], numb[j-1]);
}
}
for (i = 0; i < 10; i++){
printf("%d ", numb[i]);
}
}
2、选择排序
每次循环循环找到最小的,与第i个交换。
#include<stdio.h>
#define comp(A,B) (A)>(B) //如果A>B则返回1,否则为0.
#define exch(A,B) {int c = A; A = B; B = c;}
int main(void)
{
int i, j, min;
int numb[10];
for (i = 0; i < 10; i++){
scanf_s("%d", &numb[i]);
}
for (i = 0; i < 9; i++){
min = i;
for (j = i + 1; j < 10; j++){
if (comp(numb[min], numb[j]))
min = j;
}
exch(numb[i], numb[min]);
}
for (i = 0; i < 10; i++){
printf("%d ", numb[i]);
}
}
3、插入排序
#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, a;
int numb[10];
for (i = 0; i < 10; i++){
scanf_s("%d", &numb[i]);
}
for (i = 9; i > 0; i--){
if (comp(numb[i-1], numb[i]))
exch(numb[i-1], numb[i]);
}
for (i = 2; i < 10; i++){
j = i;
a = numb[i];
while (comp(numb[j - 1], a)){
numb[j] = numb[j - 1];
j--;
}
numb[j] = a;
}
for (i = 0; i < 10; i++){
printf("%d ", numb[i]);
}
}
4、希尔排序
h的值是不可以随意确定的,如果h为1、2、4、8······就会出现有些位置重复判断,有些位置始终不能判断;就好像奇数得不到判断,偶数重复判断,会降低运行效率。
h为1,4,13,40 ······这样每一个位置都能访问到。
#include<stdio.h>
#define less(A,B) A < B
#define exch(A,B) {int c = A; A = B; B = c;}
int main()
{
int a[20];
int i, j, h;
for (i = 0; i < 20; i++){
scanf_s("%d", &a[i]);
}
for (h = 0; h <= 20 / 3; h = 3 * h + 1);//h1=1; h2=4; h3=13; h4=40
for (h = h; h > 0; h = h / 3){
printf("%d\n", h);
for (i = h; i < 20; i++){
j = i;
int v = a[i];
while (j >= h && less(v, a[j - h])){
a[j] = a[j - h];
j = j - h;
}
a[j] = v;
}
for (int i = 0; i < 20; i++){
printf("%-4d", a[i]);
}
printf("\n");
}
}
5、归并排序
本程序是将a数组作选择排序,b数组作插入排序。最后在归并到c数组中。
也可以将a作归并排序成一个有序数组,从1个1个开始归并,就有以2个为单位的部分有序,然后2个2个归并,4个4个归并·····直到等于a数组的个数。
/*8.1 归并*/
#include<stdio.h>
#define less(A,B) (A) < (B)
#define exch(A,B) {int c=A; A = B, B = c;}
int main()
{
int a[5] = { 4,6,2,9,5 };
int b[10] = { 0,5,9,3,1,7,2,13,3,6 };
int c[15];
int i, j, k;
/*选择排序对a*/
for (i = 0; i < 5; i++){
int numb = i;
for (j = i + 1; j < 5; j++)
{
if (less(a[j],a[numb]))
numb = j;
}
exch(a[i], a[numb]);
}
printf("a: ");
for (i = 0; i < 5; i++){
printf("%d ", a[i]);
}
printf("\n");
/*插入排序对b*/
for (i = 9; i > 0; i--){
if (less(b[i], b[i - 1]))
exch(b[i], b[i - 1]);
}
for (i = 2; i < 10; i++){
j = i;
int numb = b[i];
while (less(numb, b[j - 1])){
b[j] = b[j - 1];
j--;
}
b[j] = numb;
}
printf("b: ");
for (i = 0; i < 10; i++){
printf("%d ", b[i]);
}
printf("\n");
//两个数组已经有序,再将其排在c中
for (k = 0, i = 0, j = 0; k < 15; k++){
if (i == 5)
{
c[k] = b[j++];
continue;
}
if (j == 10)
{
c[k] == a[i++];
continue;
}
c[k] = less(a[i], b[j]) ? a[i++]: b[j++];
}
printf("c: ");
for (i = 0; i < 15; i++){
printf("%d ", c[i]);
}
}
或者为以下这种
/*8.3 归并图
自顶向下归并排序 自底向上归并排序
3 2 4 6 9 1 5 0 8 7 3 2 4 6 9 1 5 0 8 7
2 3**************** 2 3****************
****4 6************ ****4 6************
2 3 4 6************ ********1 9********
********1 9******** ************0 5****
************0 5**** ****************7 8
************0 1 5 9 2 3 4 6************
0 1 2 3 4 5 6 9**** ********0 1 5 9 7 8
****************7 8 0 1 2 3 4 5 6 9****
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9
*/
#include<stdio.h>
/*对数组部分排序*/
void Merge(int a[], int head, int m, int end);
/*自顶向下归并排序,把数组分区,逐个排序*/
void MergeSortA(int a[], int head, int end);
/*自底向上归并排序,把数组分区,逐个排序*/
void MergeSortB(int a[], int head, int end);
int main()
{
int a[10] = { 3,2,4,6,9,1,5,0,8,7 };
int b[10] = { 3,2,4,6,9,1,5,0,8,7 };
MergeSortB(a, 0, 9);
MergeSortA(b, 0, 9);
for (int i = 0; i < 10; i++)
printf("%d ", a[i]);
}
void Merge(int a[], int head, int m, int end)
{
if (head >= end)
return;
int c[10] = { 0 };/*注意数组的大小*/
int i = head, j = m + 1, t;
for (t = 0; t < end - head + 1; t++)
{
if (i == m + 1)
{
c[t] = a[j++];
continue;
}
if (j == end + 1)
{
c[t] = a[i++];
continue;
}
c[t] = a[i] < a[j] ? a[i++] : a[j++];
}
i = head;
for (t = 0; t < end - head + 1; t++)
{
a[i++] = c[t];
}
}
void MergeSortA(int a[], int head, int end)
{
int m = (end + head) / 2;
if (head >= end)
return;
MergeSortA(a, head, m);
MergeSortA(a, m + 1, end);
Merge(a, head, m, end);
}
void MergeSortB(int a[], int head, int end)
{
int i, m;
for (m = 1; m < end; m = m * 2)
{
for (i = 0; i < end; i = i + m * 2)
{
if (i + m * 2 - 1 < end)
Merge(a, i, i + m - 1, i + m * 2 - 1);
else
{
if (i + m < end)
Merge(a, i, i + m - 1, end);
else
Merge(a, i, (i + end) / 2, end);
}
}
}
}
不去打扰便是最好的守护!