排序算法总结(一)
来源:互联网 发布:mpp数据库类型 编辑:程序博客网 时间:2024/05/17 03:47
今天,我们来总结一下排序算法:
排序分为冒泡排序,选择排序,插入排序,希尔排序,合并排序,快速排序,堆排序,基数排序等等,本篇文章我来详细解析冒泡排序,选择排序,直接插入排序。
冒泡排序
首先说说最简单的冒泡排序:从老谭那本书就开始认识冒泡排序了,这种方法简单易懂:
这张动图可以解释冒泡排序。
接下来,看代码的实现:
#include<stdio.h>#include<stdlib.h>#include<string.h>#include<assert.h>void BubbleSort(char *p){ int i = 0; int len = strlen(p); int j = 0; assert(p); for (i = 0; i < len - 1; i++) { for (j = 0; j < len - 1 - i; j++) { if (*(p + j) > *(p + j + 1)) //进行比较交换 { char tmp = *(p + j); *(p + j) = *(p + j + 1); *(p + j + 1) = tmp; } } }}int main(){ char p[] = "174521789"; BubbleSort1(p); printf("%s\n", p); system("pause"); return 0;}
仔细想一想你就会发现冒泡排序的效率非常低,所以我们当然要选择对此进行优化了,
#include<stdio.h>#include<stdlib.h>#include<string.h>//冒泡排序第一种优化方式:给标志位,不需要进行对有序的进行冒泡排序。void BubbleSort1(char *p){ int i = 0; int len = strlen(p); int j = 0; int flag = 0; //给一个标志 for (i = 0; i < len - 1; i++) { flag = 1; //把标志置1 for (j = 0; j < len - 1 - i; j++) { if (*(p + j) > *(p + j + 1)) { char tmp = *(p + j); *(p + j) = *(p + j + 1); *(p + j + 1) = tmp; flag = 0; //冒泡了以后把标志置0 } } if (flag) //判断标志,如果标志为1表示后面的都为有序,所以不需要再冒泡 { break; } }}int main(){ char p[] = "17452198"; BubbleSort2(p); printf("%s\n", p); system("pause"); return 0;}
上述我们通过flag使得最后对于一些有序的避免了排序,但是,作为一个应该精益求精的人,我想我们都应该做到更好,在这,提供另外一种优化的方法:
//冒泡排序第二种优化方式:记住最后排序好的位置,然后就不需要冒泡后续的。void BubbleSort2(char *p){ int i = 0; int len = strlen(p); int j = 0; int k = len-1; int tmp = 0; int m = 0; //记录你进行冒泡后最后移动到的位置 int flag = 0; //给一个标志 for (i = 0; i < len - 1; i++) { flag = 1; //把标志置1 m = 0; for (j = 0; j < k; j++) //每次进行排序的只有前一半部分 { if (*(p + j) > *(p + j + 1)) { char tmp = *(p + j); *(p + j) = *(p + j + 1); *(p + j + 1) = tmp; flag = 0; //冒泡了以后把标志置0 m = j; //记录每一次的位置 } } if (flag) //判断标志,如果标志为1表示后面的都为有序,所以不需要再冒泡 { break; } k = m; //记住最后排序到的位置,后面再排序就直排前面的 }}int main(){ char p[] = "17452198"; BubbleSort2(p); printf("%s\n", p); system("pause"); return 0;}
这里借助临时变量记住最后一次交换的位置,作为内层循环的边界。
插入排序
上面这张图片就是揭示了插入排序算法的实现过程。在前面为有序的序列,后面为无序序列,把有序序列后的一个每次和有序序列中的元素相比较,插入到它应该出现的位置。
通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。
算法步骤:
1)将第一待排序序列第一个元素看做一个有序序列,把第二个元素到最后一个元素当成是未排序序列。
2)从头到尾依次扫描未排序序列,将扫描到的每个元素插入有序序列的适当位置。(如果待插入的元素与有序序列中的某个元素相等,则将待插入元素插入到相等元素的后面。)
#include<stdio.h>#include<stdlib.h>#include<assert.h>#include<string.h>void InsertionSort(char *p){ assert(p); int len = strlen(p); int i = 0; int j = 0; for (i = 1; i < len - 1; i++) { char tmp = p[i]; //在这里保存有序序列后的一个元素 for (j = i - 1; j >= 0; j--) //进行和有序序列中的元素进行比较 { if (tmp < p[j]) //比较判断 { p[j + 1] = p[j]; //进行有序序列元素的移动 } else { break; } } p[j+1] = tmp; //进行元素插入 }}int main(){ char str[] = "17452198"; InsertionSort(str); printf("%s\n", str); system("pause"); return 0;}
选择排序
这个动图就可以说明选择排序的问题了。
选择排序(Selection sort)也是一种简单直观的排序算法。
算法步骤:
1)首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置
2)再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。
3)重复第二步,直到所有元素均排序完毕。
#define _CRT_SECURE_NO_WARNINGS 1#include<stdlib.h>#include<stdio.h>#include<string.h>#include<assert.h>void SelectSort(char *str){ assert(str); int i = 0; int min = 0; int j = 0; int len = strlen(str); for (i = 1; i < len - 1; i++) { min = i + 1; //首先默认无序第一个为最小的 for (j = i + 1; j < len - 1; j++) { if (str[min]>str[j]) { min = j; //进行无序序列中的比较,得到最小的下标 } } if (min != i) //把无序序列中最小的元素与有序的元素进行替换 { char tmp = str[i]; str[i] = str[min]; str[min] = tmp; } }}int main(){ char str[] = "17452198"; SelectSort(str); printf("%s\n", str); system("pause"); return 0;}
这次就先描述这三种排序算法,后续依然会有更新
- 排序算法总结(一)
- 排序算法总结(一)
- 排序算法总结(一)
- 排序算法总结(一)
- 排序算法总结(一)
- 排序算法总结(一)
- 排序算法总结(一)
- 排序算法总结(一)
- 排序算法总结(一)
- 排序算法总结(一)
- 排序算法总结(一)
- 排序算法总结(一)计数排序
- 排序算法总结一
- 常用排序算法总结(一)----冒泡排序,归并排序
- 排序算法 总结&思考(一)
- Java常见排序算法总结(一)
- 排序算法大总结(一)
- 数据结构-各类排序算法总结(一)
- Spring 之IOC容器(初级)
- 合并查询结果 与 表的别名
- 微电网和主动配电网
- AVR Studio中AVR学习之ADC转换
- Kruskal 最小生成树 & Dijkstra 最短路径
- 排序算法总结(一)
- linux 2.6内核 编译模块Makefile 详解
- 当谨慎变成了常态
- 节点带有属性的xml pull解析
- 在Linux下使用MySQl遇到的小问题集合
- java线程
- HttpURLConnection 的get请求
- Linux sudo一些命令出现 command not found 的原因
- html元素大小与位置讲解