排序之冒泡排序

冒泡排序概念

两两比较相邻记录的关键字,如果反序则交换,直到没有反序记录为止。

最简单的冒泡排序实现

交换排序:每一个数字都与它后面的每一个数字比较。

这种算法效率很低,前面排好的数字没有作用,3作为一个很小的数字第一次时,反而被排到最后一个位置。

代码:

#include "stdio.h"
#define MAXSIZE 10

typedef int ElemType;
typedef struct
{
    ElemType data[MAXSIZE];
    int length;
} SqList;

//交换传入的值
void swap(SqList *L, int i, int j)
{
    ElemType temp;
    temp = L->data[i];
    L->data[i] = L->data[j];
    L->data[j] = temp;
}

//初级版冒泡排序
void BubbleSort(SqList *L)
{
    int i, j;
    for (i = 0; i < L->length; i++)
    {
        for (j = 0; j < L->length; j++)
        {
            if (L->data[i] > L->data[j])
            {
                swap(L, i, j);
            }
        }
    }
}

int main()
{
    SqList list = {{3, 5, 7, 4, 10, 0, 0, 0, 0, 0}, 5};

    BubbleSort(&list);

    for (int i = 0; i < list.length; i++)
    {
        SqList *L = &list;
        printf("%d ", L->data[i]);
    }
}

正宗的冒泡排序

与第一种比优点:在一次循环中,如上图,不仅把最小值1放到了第一个位置,还把3提到了前面。怎么减少循环呢?详情看下面的优化

#include "stdio.h"
#define MAXSIZE 10

typedef int ElemType;
typedef struct
{
    ElemType data[MAXSIZE];
    int length;
} SqList;

//交换传入的值
void swap(SqList *L, int i, int j)
{
    ElemType temp;
    temp = L->data[i];
    L->data[i] = L->data[j];
    L->data[j] = temp;
}
//冒泡排序(从小到大)
void BubbleSort(SqList *L, int *count)
{
    int i, j, k = 0;
    for (i = 0; i < L->length; i++)//i代表前面已经排好序的数字的索引
    {
        for (j = L->length - 1 - 1; j >= i; j--) //j从后往前循环(j要等于i,是因为j+1个数与j个数比)
        {
            if (L->data[j] > L->data[j + 1]) //前一个大于后一个
            {
                swap(L, j, j + 1);
                k++;
            }
        }
    }
    *count = k;
}

int main()
{
    int count = 0;

    SqList list = {{7, 1, 10, 4, 5, 3, 0, 0, 0, 0}, 6};

    BubbleSort(&list, &count);

    for (int i = 0; i < list.length; i++)
    {
        SqList *L = &list;
        printf("%d ", L->data[i]);
    }
    printf("change %d\n", count);//交换了9次
}

冒泡排序的优化

根据上图,代码如下

避免有序的情况下进行循环判断

#include "stdio.h"
#define MAXSIZE 25
#define TRUE 1
#define FALSE 0
typedef int Status;
typedef int ElemType;
typedef struct
{
    ElemType data[MAXSIZE];
    int length;
} SqList;

//交换传入的值
void swap(SqList *L, int i, int j)
{
    ElemType temp;
    temp = L->data[i];
    L->data[i] = L->data[j];
    L->data[j] = temp;
}
//优化冒泡排序(如果内层循环检测没有需要交换的数据,即排序已经成功了,外层循环就不用再循环了)
void BubbleSort(SqList *L, int *count)
{
    int i, j, k = 0;
    Status flag=TRUE;//用来标记是否还有需要交换的数据
    for (i = 0; i < L->length&&flag; i++) //flag为FALSE则退出循环
    {
        flag=FALSE;//初始flag为FALSE
        for (j = L->length - 1 - 1; j >= i; j--) 
        {
            k++;
            if (L->data[j] > L->data[j + 1])
            {
                swap(L, j, j + 1);
                flag=TRUE;//如果有数据交换,则flag为true
            }
        }
    }
    *count = k;
}

int main()
{
    int count = 0;

    SqList list = {{28, 77, 66, 91, 29, 48, 39, 49, 80, 3, 41, 26, 23, 59, 7, 60, 5, 77, 16, 65}, 20};

    BubbleSort(&list, &count);

    for (int i = 0; i < list.length; i++)
    {
        SqList *L = &list;
        printf("%d ", L->data[i]);
    }
    printf("loop %d\n", count); //循环了187次
}

时间复杂度分析

相同元素的前后顺序并没有改变,冒泡排序是一种稳定排序算法

posted @ 2021-10-17 19:01  Infinite_V胜  阅读(61)  评论(0)    收藏  举报