排序算法 & 迷宫的深度, 广度优先
内容提要
1. 我掌握的排序算法的时间复杂度
2. 我掌握的6种排序算法(插入, 冒泡, 选择, 归并, 快速, 希尔)
3. 迷宫的搜索方法(深度优先 + 广度优先)
各种排序的时间复杂度
名称 | 稳定 否 | 平均时间复杂度 |
插入排序 | 稳定 | n2 |
冒泡排序 | 稳定 | n2 |
选择排序 | 否 | n2 |
归并排序 | 稳定 | nlog2n |
希尔排序 | 否 | n2 |
快速排序 | 否 | nlog2n |
各种排序算法
1. 插入排序
类似打扑克, 来一个数, 从这个数的前一个数开始, 一直到第一个数, 比这个数小的, 比如位置是 a, 那么 a 之前的都比这个数小, 所以, 要移动 a 以后到这个数以前的数, 向后移动一位, 然后将这个数插入到 a+1 的位置上
#include<stdio.h>
int a[10] = {
10, 2, 5, 1, 3, 4, 6, 7, 9, 8
};
void insert_sort()
{
int j = 1; /* 插入location */
int i ;
int key = -1;
for (j=1; j<10; j++) {
i = j - 1;
key = a[j];
/* 移动元素 */
while (i>=0 & a[i] > key) {
a[i+1] = a[i];
i--;
}
a[i+1] = key;
}
}
int main(void)
{
int i = 0;
printf("-------- now the data --------:\n");
for (i=0; i<10; i++) {
printf("%d, ", a[i]);
}
insert_sort();
printf("\n-------- after insert sort --------:\n");
for (i=0; i<10; i++) {
printf("%d, ", a[i]);
}
}
2. 冒泡排序
第一个循环就是控制循环次数, 没有别的意义, 在每次循环内部, 两两比较, 这样, 最大的数, 第一次循环就冒出去了, 以此类推, 逐渐冒出去第2大, 第3大的数.
#include <stdio.h>
#define LEN 10
int a[LEN] = {10, 5, 6, 7, 8, 1, 4, 2, 9, 3};
void maopao_sort(void)
{
int count = 0;
int circle = LEN;
int i = 0;
int j = 1;
int temp;
for (count=0; count<LEN; count++) { // 总循环次数
circle--;
for (i=0; i<circle; i++) {
if (a[i+1] < a[i]) {
temp = a[i+1];
a[i+1] = a[i];
a[i] = temp;
}
}
}
}
int main(void)
{
int i = 0;
maopao_sort();
for (i=0; i<LEN; i++) {
printf("%d,", a[i]);
}
return 0;
}
3. 选择排序
第一个循环是控制循环次数, 每次找出这个循环中最小的数,放在第一个位置, 然后再从第2个数开始找, 找出第二次循环中最小的数,放在第2个的位置上, 以此类推
#include<stdio.h>
#define LEN 10
int a[LEN] = {
10, 2, 5, 3, 4, 1, 7, 6, 8, 9
};
void selectSort()
{
int temp;
int i;
int j;
for (i=0; i<LEN; i++) {
for (j=i+1; j<LEN; j++) {
if (a[j] < a[i]) {
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
}
}
int main(void)
{
int i;
selectSort();
for (i=0; i<LEN; i++) {
printf("%d,", a[i]);
}
return 0;
}
4. 归并排序(个人最喜欢的排序)
递归思想, 首先, 将所有的数分为两部分, 这两部分排好序后,再整合(归并) merge, 整合时, 因为左右两边都是已经排好序的, 所以, 排序起来容易很多.
#include<stdio.h>
#define LEN 10
int a[LEN] = {
10, 7, 4, 2, 3, 1, 8, 9, 5, 6
};
void merge(int start, int mid, int end)
{
int n1 = mid - start + 1;
int n2 = end - mid;
int left[n1];
int right[n2];
int i, j, k;
// init left and right
for (i=0; i<n1; i++) {
left[i] = a[start+i];
}
for (j=0; j<n2; j++) {
right[j] = a[mid+1+j];
}
i = j = 0;
k = start;
// merge
while (i < n1 && j < n2) {
if (left[i] <= right[j]) {
a[k++] = left[i++];
} else {
a[k++] = right[j++];
}
}
while (i < n1) {
a[k++] = left[i++];
}
while (j < n2) {
a[k++] = right[j++];
}
}
void sort(int start, int end)
{
int mid;
if (start < end) {
mid = (end + start) / 2;
sort(start, mid);
sort(mid+1, end);
merge(start, mid, end);
}
}
int main(void)
{
int i;
sort(0, LEN-1);
for(i=0; i<LEN; i++) {
printf("%d,", a[i]);
}
return 0;
}
5. 希尔排序
插入排序的升级版, 算法: 首先定义一个步长, 一般设定为 LEN/2, 然后相隔这个步长的元素进行插入排序, 这个步长逐步缩小, 直到步长为1 .
#include<stdio.h>
# define LEN 10
int a[LEN] = {
10, 2, 4, 1, 6, 8, 3, 5, 9, 7
} ;
void Shell_sort()
{
int d = LEN / 2;
int j;
int i;
int temp;
while (d > 0) { /* 步长控制总的循环次数 */
for (j=d; j<LEN; j++) { /* 类似插入排序中的 j=1 */
i = j-d; /* 从插入为的前一位开始比较, 注意这个前一位是间隔前步长位 */
temp = a[j];
/* 移位 */
while (i>=0 && a[i] > temp) { /* 注意: 这里一定要是 temp, 而不能是 a[j], 因为循环内部已经改变了a[j]的值 */
a[i+d] = a[i];
i -= d;
}
a[i+d] = temp; /* 插入操作 */
}
d = d/2;
}
}
int main(void)
{
int i;
Shell_sort();
for (i=0; i<10; i++) {
printf("%d, ", a[i]);
}
}
6. 快速排序
快速排序是冒泡排序的升级版, 采用了分治策略, 首先把序列分成两个子序列, 递归对子序列进行排序. 首先找到一个轴, 对序列进行重新排序, 比轴小的放到轴左边, 比轴的放到轴右边, 划分后, 轴的位置就是正确的(即数组下标不会在发生改变了), 递归对两个子序列进行重新排序.
#include<stdio.h>
#define LEN 10
int a[LEN] = {
10, 5, 3, 2, 1, 7, 8, 6, 9, 4
};
int position(int start, int end)
{
int dp = start;
int i = start; /* 左边指针 */
int j = end; /* 右边指针 */
int temp;
while (i < j) {
for(; i<dp; i++) {
if (a[i] > a[dp]) {
temp = a[i];
a[i] = a[dp];
a[dp] = temp;
dp = i;
}
}
for (; j>dp; j--) {
if (a[j] < a[dp]) {
temp = a[j];
a[j] = a[dp];
a[dp] = temp;
dp = j;
}
}
}
return dp;
}
void short_sort(int start, int end)
{
int dp;
dp = position(start, end);
printf("\ndp location: %d\n", dp);
if (start < end) {
short_sort(start, dp-1);
short_sort(dp+1, end);
}
}
int main(void)
{
int i;
short_sort(0, LEN-1);
for (i=0; i<LEN; i++) {
printf("%d, ", a[i]);
}
}
迷宫深度优先, 广度优先
参考本blog中的 栈和队列
深度优先 用栈实现
广度优先 用队列实现, 特别的地方是, 用栈实现的广度优先, 在入队列时, 要记录对应的上一步的位置, 因为它不同栈, 栈的上一步的位置是按照栈的先后顺序存储的.
排序算法 & 迷宫的深度, 广度优先的更多相关文章
- 基于python的七种经典排序算法
参考书目:<大话数据结构> 一.排序的基本概念和分类 所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作.排序算法,就是如何使得记录按照要求排列的方法. ...
- 第四百一十五节,python常用排序算法学习
第四百一十五节,python常用排序算法学习 常用排序 名称 复杂度 说明 备注 冒泡排序Bubble Sort O(N*N) 将待排序的元素看作是竖着排列的“气泡”,较小的元素比较轻,从而要往上浮 ...
- 基于python的七种经典排序算法(转)
一.排序的基本概念和分类 所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作.排序算法,就是如何使得记录按照要求排列的方法. 排序的稳定性:经过某种排序后,如果两个 ...
- 排序算法 python实现
一.排序的基本概念和分类 所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作.排序算法,就是如何使得记录按照要求排列的方法. 排序的稳定性: 经过某种排序后,如果两 ...
- 八大排序算法Java
目录(?)[-] 概述 插入排序直接插入排序Straight Insertion Sort 插入排序希尔排序Shells Sort 选择排序简单选择排序Simple Selection Sort 选择 ...
- [Data Structure & Algorithm] 八大排序算法
排序有内部排序和外部排序之分,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存.我们这里说的八大排序算法均为内部排序. 下图为排序 ...
- 排序算法 ----(转载::http://blog.csdn.net/hguisu/article/details/7776068)
1.插入排序—直接插入排序(Straight Insertion Sort) 基本思想: 将一个记录插入到已排序好的有序表中,从而得到一个新,记录数增1的有序表.即:先将序列的第1个记录看成是一个有序 ...
- Python实现各种排序算法的代码示例总结
Python实现各种排序算法的代码示例总结 作者:Donald Knuth 字体:[增加 减小] 类型:转载 时间:2015-12-11我要评论 这篇文章主要介绍了Python实现各种排序算法的代码示 ...
- Java常用排序算法+程序员必须掌握的8大排序算法
概述 排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存. 我们这里说说八大排序就是内部排序. 当n较大, ...
随机推荐
- PHP gmdate() 函数
定义和用法 gmdate() 函数格式化 GMT/UTC 日期/时间. 同 date() 函数 类似,不同的是返回的时间是格林威治标准时(GMT). 语法 gmdate(format,timestam ...
- java多线程解决生产者消费者问题
import java.util.ArrayList; import java.util.List; /** * Created by ccc on 16-4-27. */ public class ...
- ACM题目————放苹果
Description 把M个同样的苹果放在N个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的分法?(用K表示)5,1,1和1,5,1 是同一种分法. Input 第一行是测试数据的数目t(0 ...
- 关于childNodes的length的问题
<ul id="ul1"> <li></li> <li></li> </ul> 这个时候如果 documen ...
- 复利计算--4.0 单元测试之JAVA版-软件工程
复利计算--4.0 单元测试-软件工程 前言:由于本人之前做的是C语言版的复利计算,所以为了更好地学习单元测试,于是将C语言版的复利计算修改为JAVA版的. 一.主要的功能需求细分: 1.本金为100 ...
- html移动开发app-framework2.0使用心得
1.页面切换动画结束时卡(禁用动画) 2.搜索或导航标签需要固定(标签选择器动态修改高度) 3.pancel容器默认生成的时候内容不放 通过动态的的$("").empty().ht ...
- jquery 实现页面局部刷新ajax做法
这个方法就多了去了,常见的有以下几种:下面介绍全页面刷新方法:有时候可能会用到 window.location.reload()刷新当前页面. parent.location.reload()刷新父亲 ...
- 设计模式之——单例模式(Singleton)的常见应用场景
单例模式(Singleton)也叫单态模式,是设计模式中最为简单的一种模式,甚至有些模式大师都不称其为模式,称其为一种实现技巧,因为设计模式讲究对象之间的关系的抽象,而单例模式只有自己一个对象,也因此 ...
- 对“Java”的诞生历史、特点、定义等HR常问的简单题
本人是一个学习Java的新手,在学习了Java以后,对Java的一些总结. 这里共有12点对Java的简单的阐述,如果解释的不怎么样请大家谅解哈. 1.首先我们来看一看,在Java之前的有那些打牌语言 ...
- 2016年11月20日 星期日 --出埃及记 Exodus 20:11
2016年11月20日 星期日 --出埃及记 Exodus 20:11 For in six days the LORD made the heavens and the earth, the sea ...