温习排序算法(基于C指针)
以前学过的数据结构课,貌似已经忘得一干二净了,偶然又翻起,书中最后一章详细介绍了7种排序算法,现在对其中4种做个总结。(为啥只总结4种,当然是因为偷懒,只想总结简单又常用的!)
先贴一张排序分类图:
1.冒泡法:
主要思想:每次比较相邻的两个数,较小的数向上冒,较大的数向下沉。
|
演示效果:
C代码:(指针p指向待排序列的首地址,length是待排序列的总长度,下同)
swap(int *p1, int *p2) { int tmp; tmp = *p1; *p1 = *p2; *p2 = tmp; } Msort(int *p, int length) { BOOLEAN flag = TRUE; for (int i = 0; i < length && flag; i++){ flag = FALSE; for (int j = length - 1; j > i; j--) if (*(p + j) < *(p + j - 1)) { swap(p + j, p + j - 1); flag = TRUE; } } }
2.简单选择法:
主要思想:每轮循环找到一个最小数的标号,循环结束后进行一次交换。 |
演示效果:
C代码:
swap(int *p1, int *p2) { int tmp; tmp = *p1; *p1 = *p2; *p2 = tmp; }
Xsort(int *p, int length) { for (int i = 0; i < length - 1; i++){ int min = i; for (int j = i + 1; j < length; j++){ if (*(p + j) < *(p + min)) min = j; } if (min != i) swap(p + i, p + min); } }
3.直接插入法:
主要思想:每轮循环都是实现将一个新来的数插入到原有的一个有序子序列中。 |
演示效果:
C代码:
swap(int *p1, int *p2) { int tmp; tmp = *p1; *p1 = *p2; *p2 = tmp; } Csort(int *p, int length) { for (int i = 1; i < length; i++){ if (*(p + i) < *(p + i - 1)){ int tmp = *(p + i); int j; for (j = i - 1; j >= 0 && *(p + j) > tmp; j--) *(p + j + 1) = *(p + j); *(p + j + 1) = tmp; } } }
4.快速排序法:
冒泡排序的升级版,同属于交换排序。
主要思想:通过递归,不断地二分序列,使相对较大的数位于一边,相对较小的数位于另一边。 |
演示效果:
C代码:
swap(int *p1, int *p2) { int tmp; tmp = *p1; *p1 = *p2; *p2 = tmp; } int partition(int *p, int startIdx, int endIdx) { int pivotkey; pivotkey = *(p + startIdx); while (startIdx < endIdx) { while (startIdx < endIdx && *(p + endIdx) >= pivotkey) endIdx--; swap(p + startIdx, p + endIdx); while (startIdx < endIdx && *(p + startIdx) <= pivotkey) startIdx++; swap(p + startIdx, p + endIdx); } return startIdx; } Ksort(int *p, int startIdx,int endIdx) { int pivot; if (startIdx < endIdx) { pivot = partition(p,startIdx,endIdx); Ksort(p, startIdx, pivot - 1); Ksort(p, pivot + 1, endIdx); } }
5.举例:
//2018-8-20 //by-lengwawa #include<stdio.h> #include<Windows.h> //程序中的BOOLEAN在该头文件中定义
main() { int n, i; int *p; p = NULL; printf("请输入需要排序的个数:"); scanf_s("%d", &n); p = (int *)malloc(n*sizeof(int)); printf("\n请输入%d个待排序的数:", n); for (int k = 0; k < n; k++) scanf_s("%d", p + k); printf("\n你要使用哪种排序法(1——冒泡 2——选择 3——插入 4——快排):"); scanf_s("%d", &i); printf("\n"); if (i == 1) { printf("使用冒泡排序法的结果是:"); Msort(p, n); for (int j = 0; j < n; j++) printf("%d ", *(p + j)); printf("\n\n\n"); } else if (i == 2) { printf("使用选择排序法的结果是:"); Xsort(p, n); for (int j = 0; j < n; j++) printf("%d ", *(p + j)); printf("\n\n\n"); } else if (i == 3) { printf("使用插入排序法的结果是:"); Csort(p, n); for (int j = 0; j < n; j++) printf("%d ", *(p + j)); printf("\n\n\n"); } else { printf("使用快速排序法的结果是:"); Ksort(p, 0, n - 1);//这里是标号,所以是n-1 for (int j = 0; j < n; j++) printf("%d ", *(p + j)); printf("\n\n\n"); } }
6.输出:
7.把另外3个的gif演示放一下吧,有兴趣的看看
选择法升级版——堆排序:
插入法升级版——希尔排序:
归并排序: