首页 > 其他分享 >冒泡排序(C语言)

冒泡排序(C语言)

时间:2024-06-10 20:58:29浏览次数:16  
标签:sz arr int void 冒泡排序 C语言 ++ printf

一.冒泡排序的原理

冒泡排序的原理是:从左到右,相邻元素进行比较,以升序为例,第1次遍历将最大的数沉底。经过n次遍历这组元素以升序排列

->第1次遍历,两个相邻的数比较大小,若左边的数大于右边的数,则两个元素交换位置,反之,继续向后比较,当第1次遍历结束之后该组元素最大的数就被移动到了末尾

->第2次遍历,除去第一次的最大数,将这组数据中最大的数放至末尾

->根据以上原理,直至将这组元素排至升序,循环结束

二.冒泡排序(Bubble Sort)的代码实现

#include <stdio.h>
void BubbleSort(int arr[], int sz)
{
    int i = 0, j = 0, flag = 0;
    //有sz个数据只需要排列sz-1次就可以完成升序
    for(i = 0; i < sz - 1; i++)
    {
        //每排序一次就有一个数不需要排列了,所以是:sz-i-1
        for(j = 0; j < sz - i - 1; j++)
        {
            if(arr[j] > arr[j + 1])
            {
               int temp = arr[j];
               arr[j] = arr[j+1];
               arr[j + 1] = temp;
               flag = 1;
            }
        }
        //如果flag的值改变就证明这数组是升序不需要排序
        if(!flag)
        {
           break;
        }
    }
}

int main()
{
    int arr[] = {5,6,4,3,8,9,7,2,10,1,};
    printf("没排序之前:");
    int sz = sizeof(arr)/sizeof(arr[0]);
    int i = 0;
    for(i = 0; i < sz; i++)
    {
        printf("%d ", arr[i]);
    }
    printf("\n");
    BubbleSort(arr, sz);
    printf("排序之后:");
    for(i = 0; i < sz; i++)
    {
        printf("%d ", arr[i]);
    }
    printf("\n");
    return 0;
}

但是这种冒泡排序有一个弊端!它只能用来排序整型数据。

C语言给我们提供了一个库函数,可以排序任意类型的数据 qsort

三.qsort的用法

qsort是用快速排序的思想实现的一个排序函数

用到qsort函数我们需要那些参数

void qsort(void* base,
           size_t num,
           size_t width,
           int (*cmp)(const void* e1, const void* e2))

->1.你要排序的数据的起始位置

->2.待排列数据元素的个数

->3.待排列数据元素的大小(一个元素,单位:字节)

->4.函数指针 - 比较大小

知道了qsort函数的参数之后,我们现在来使用一下

用法1:

->测试整型排序

#include <stdio.h>

int cmp(const void* e1, const void* e2)
{
    return *(int*)e1 - *(int*)e2;     //升序
       //  *(int*)e2 - *(int*)e1;  降序
}

int main()    
{
    int arr[] = {5,6,4,3,8,9,7,2,10,1,};
    printf("没排序之前:");
    int sz = sizeof(arr)/sizeof(arr[0]);
    int i = 0;
    for(i = 0; i < sz; i++)
    {
        printf("%d ", arr[i]);
    }
    printf("\n");
    qsort(arr, sz, sizeof(arr[0]), cmp);
    printf("排序之后:");
    for(i = 0; i < sz; i++)
    {
        printf("%d ", arr[i]);
    }
    printf("\n");
    return 0;
}

升序:

降序:

用法2:

->测试使用qsort来排序数据结构

使用结构体的整型成员排序

#include <stdio.h>

typedef struct Stu
{
    char name[20];
    int age;
}Stu;

int cmp_Stu_by_age(const void* e1, const void* e2)
{
    return ((Stu*)e1)->age - ((Stu*)e2)->age;; //升序
    //或者用成员运算符:(*(Stu*)e1).age - (*(Stu*)e2).age  都是升序,反过来就是降序
}

int main()
{
    Stu s[] = {{"zhangsan", 18},
               {"lisi", 25}, 
               {"wangwu", 20}, 
               {"xiaoliu", 19}};
    int sz = sizeof(arr) / sizeof(arr[0]);
    qsort(s, sz, sizeof(s[0]), cmp_Stu_by_age);
    int i = 0;
    for(i = 0; i < sz; i++)
    {
        printf("%s %d\n", s[i].name, s[i].age);
    }
    return 0;
}

使用结构体的字符数组成员排序

include <string.h>
int cmp_stu_by_name(const void* e1, const void* e2)
{
    return strcmp(((*Stu)e1)->name, ((*Stu)e2)->name);
}

我们来模仿一下万能快速排序这个函数

模块一

//测试不同类型
#inciude <stdio.h>
void test1()
{
//根据情况放入   
}

模块二

void BubbleSort(void* arr, int sz, int width, int (*cmp)(const void* e1, const void* e2) )
{
    int i = 0, j = 0, flag = 0;
    for(i = 0; i < sz - 1; i++)
    {
        for(j = 0; j < sz - i - 1; j++)
        {
            if(cmp((char*)arr + j * width, (char*)arr + (j + 1) * width) > 0)
            {
               swap((char*)arr + j * width, (char*)arr + (j + 1) * width, width);
               flag = 1;
            }
        }
        if(!flag)
        {             
           break;
        }
    }
}

模块三

int cmpare(const void* e1, const void* e2)
{
    return *(int*)e1 - *(int*)e2;
    //这里以整型数据为例,别的类型自己临时变换 
}

模块四

void swap(char* buf1, char* buf2, int width)
{
    int i = 0;
    for(i = 0; i < width; i++)
    {
        int temp = *buf1;
        *buf1 = *buf2;
        *buf2 = temp;
        buf1++;
        buf2++;
    }
}

我们用我们模拟的万能排序来试一下

以整型为例

include <stdio.h>
int cmpare(const void* e1, const void* e2)
{
    return *(int*)e1 - *(int*)e2;
}

void swap(char* buf1, char* buf2, int width)
{
    int i = 0;
    for (i = 0; i < width; i++)
    {
        char temp = *buf1;
        *buf1 = *buf2;
        *buf2 = temp;
        buf1++;
        buf2++;
    }
}

void BubbleSort(void* arr, int sz, int width, int (*cmp)(const void* e1, const void* e2))
{
    int i = 0, j = 0, flag = 0;
    for (i = 0; i < sz - 1; i++)
    {
        for (j = 0; j < sz - i - 1; j++)
        {
            if (cmp((char*)arr + j * width, (char*)arr + (j + 1) * width) > 0)
            {
                swap((char*)arr + j * width, (char*)arr + (j + 1) * width, width);
                flag = 1;
            }
        }
        if (!flag)
        {
            break;
        }
    }
}

void test1()
{
    int arr[] = { 5,6,4,3,8,9,7,2,10,1, };
    printf("没排序之前:");
    int sz = sizeof(arr) / sizeof(arr[0]);
    int i = 0;
    for (i = 0; i < sz; i++)
    {
        printf("%d ", arr[i]);
    }
    printf("\n");
    BubbleSort(arr, sz, sizeof(arr[0]), cmpare);
    printf("排序之后:");
    for (i = 0; i < sz; i++)
    {
        printf("%d ", arr[i]);
    }
    printf("\n");  
}

int main()
{
    test1();
    return 0;
}

以上就是万能冒泡排序

标签:sz,arr,int,void,冒泡排序,C语言,++,printf
From: https://blog.csdn.net/m0_73634434/article/details/139574701

相关文章

  • 函数递归(C语言)(详细过程!)
    函数递归一.递归是什么1.1递归的思想1.2递归的限制条件二.递归举例2.1求n的阶乘2.2按顺序打印一个整数的每一位三.递归与迭代3.1求第n个斐波那契数一.递归是什么递归是学习C语言很重要的一个知识,递归就是函数自己调用自己,是一种解决问题的方法,下面就使用......
  • 【C语言】预处理详解(中卷)
    前言预处理完整系列推荐阅读顺序:预处理详解(上卷)——宏(上卷)——宏(下卷)——预处理详解(中卷)——预处理详解(下卷)本文接着讲预处理相关的内容。#和###运算符#可以将宏的一个参数转换成字符串字面量。它仅允许出现在带参数的宏的替换列表中。#运算符所执行的操作可以理解为“......
  • 【C语言】分支与循环(下)
     目录 6. while循环7. for循环8. do-while循环9. break和continue循环10. 循环的嵌套11. goto语句正文开始——6. while循环  C语言提供了三种循环,while就是其中一种。while语句的语法结构与if语句非常相似。6.1 if和while的对......
  • c语言——字符函数与字符串函数
    文章目录一字符函数(1)字符分类函数:(2)字符转换函数:二字符串函数(1)strlen函数的使用与模拟(2)strcpy函数的使用与模拟(3)strcmp函数的使用与模拟(4)strcat函数的使用与模拟两组函数的区别:(5)strncpy函数(6)strncmp函数的使用(7)strncat函数的使用(8)strstr函数的使用与模拟(9)strtok函数......
  • 【C语言】写一个宏,可以将一个整数的二进制位的奇数位和偶数位交换
    思路:10的二进制是00000000000000000000000000001010,然后交换奇数位和偶数位那么就是第一位和第二位交换,第三位和第四位交换,以此类推解题步骤:(1)将00000000000000000000000000001010的奇数位保留,偶数位变为0则变成00000000000000000000000000000000(2)将00000000000000000000......
  • C语言 & 图形化界面方式连接MySQL【C/C++】【图形化界面组件分享】
      博客主页:花果山~程序猿-CSDN博客文章分栏:MySQL之旅_花果山~程序猿的博客-CSDN博客关注我一起学习,一起进步,一起探索编程的无限可能吧!让我们一起努力,一起成长!目录一.配置开发环境 二,接口介绍1.mysql_init2.mysql_real_connect3.mysql_query4.对select结果分析......
  • 线程池原理及c语言实现线程池
    线程池线程池是一种多线程处理机制,其主要目的是提高系统资源利用率、降低系统资源消耗,并通过控制并发线程数量来优化性能。以下是关于线程池的详细解释:定义:线程池是一种线程使用模式,它维护着一组线程,这些线程等待监督管理者分配可并发执行的任务。通过将任务添加到队列中,并......
  • 【C语言】宏offsetof的模拟实现(计算结构体中某变量相对于首地址的偏移)
    首先我们应该特别留意:offsetof是一个宏,并非是一个函数!宏offsetof的介绍:参数:第一个是结构体类型名称,第二个是结构体成员名返回类型:size_t无符号整形引用的头文件:<stddef.h>offsetof的使用举列:#include<stddef.h>structStu//注释为相对于起始位置的偏移量{......
  • C语言——使用函数创建动态内存
    一、堆和栈的区别1)栈(Stack):栈是一种自动分配和释放内存的数据结构,存储函数的参数值、局部变量的值等。栈的特点是后进先出,即最后进入的数据最先出来,类似于我们堆盘子一样。栈的大小和生命周期是由系统自动管理的,不需要程序员手动释放。2)堆(Heap):堆是由程序员手动分配和释......
  • 初始C语言——结构化算法的结构
    C语言程序是一种程序化程序,也就是说,可以用C语言程序来解决的问题,都可以分解成相互独立的几个部分,每个部分都可以通过简单的语句或结构来实现。一般而言,对于结构化的程序,一个完整的算法可以用“顺序结构”,“分支结构”和“循环结构”的有机组合来表示。(一)----------顺序结构......