排序算法总结(一)

原创 2016年06月01日 21:53:20

今天,我们来总结一下排序算法:
排序分为冒泡排序,选择排序,插入排序,希尔排序,合并排序,快速排序,堆排序,基数排序等等,本篇文章我来详细解析冒泡排序,选择排序,直接插入排序。

冒泡排序

首先说说最简单的冒泡排序:从老谭那本书就开始认识冒泡排序了,这种方法简单易懂:
这里写图片描述
这张动图可以解释冒泡排序。
接下来,看代码的实现:

#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;
}

这次就先描述这三种排序算法,后续依然会有更新

版权声明:本文为博主原创文章,未经博主允许不得转载。 举报

相关文章推荐

排序算法总结(一)

【前言】        前一阵子米老师一直在和我们讲算法,米老师给我们讲课的时间并不多,他花了这么多时间来给我们讲算法,可想而知 算法的重要性,通过不断的总结我也发现了算法的魅力。虽然只是简单的排序算...

排序算法总结(一)

排序是最基本的算法,曾经学过很多种排序算法,但从没有总结过,这次总结一下,排序算法有快速排序,桶排序,插入排序,基数排序,归并排序,冒泡排序,选择排序,希尔排序,堆排序,计数排序等,再次一一总结一下。...

精选:深入理解 Docker 内部原理及网络配置

网络绝对是任何系统的核心,对于容器而言也是如此。Docker 作为目前最火的轻量级容器技术,有很多令人称道的功能,如 Docker 的镜像管理。然而,Docker的网络一直以来都比较薄弱,所以我们有必要深入了解Docker的网络知识,以满足更高的网络需求。

排序算法总结(一)

#include using namespace std; void Insert(int r[],int n){ for(int i=2;i<=n;i++){ if(r[i]<r[i-1]...

排序算法总结一

在算法中是比较基础也是相当重要的一部分,在这里将会把各种排序算法那加以总结,并实现;

排序算法总结(一)

在程序设计语言中,有着八大排序算法。分别是:

排序算法总结(一)

1 冒泡排序冒泡排序是最简单的排序之一了,其大体思想就是通过与相邻元素的比较和交换来把小的数交换到最前面。这个过程类似于水泡向上升一样,因此而得名。举个栗子,对5,3,8,6,4这个无序序列进行冒泡排...

排序算法总结(一)

1、排序算法的分类在本文的开始,我们先来看看排序是如何分类的。1.1、稳定排序和非稳定排序在待排序的记录中,如果存在多个关键码相同的记录,经过排序后,这些记录的相对次序依然保持不变,即排序后这两个相同...

排序算法系列总结

声明:引用请注明出处http://blog.csdn.net/finish_dream/article/details/70242890引言最近两周把排序算法学习实现了一遍,主要包括插入排序,选择排序...

常用排序算法总结(一) 比较算法总结

转载链接:http://www.cnblogs.com/eniac12/p/5329396.html 目录 冒泡排序   鸡尾酒排序   选择排序插入排序 二分插入排序  希尔排序   归并...

排序算法总结

排序算法优缺点总结及实现
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)