排序算法总结(一)

来源:互联网 发布: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;}

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

2 0
原创粉丝点击