使用冒泡排序模拟实现qsort函数

目录

  • 冒泡排序
  • qsort函数的使用
    • 1.使用qsort函数排序整型数据
    • 2.使用qsort函数排序结构数据
  • 冒泡排序模拟实现qsort函数
  • 今日题目
    • 1. 字符串旋转结果
    • 2.杨氏矩阵
    • 3.猜凶手
    • 4.杨辉三角
  • 总结

冒泡排序

冒泡排序的核心思想是:两两相邻的元素进行比较

代码如下:

//⽅法1 
void bubble_sort(int arr[], int sz)//参数接收数组元素个数 
{int i = 0;for(i=0; i<sz-1; i++){int j = 0;for(j=0; j<sz-i-1; j++){if(arr[j] > arr[j+1]){int tmp = arr[j];arr[j] = arr[j+1];arr[j+1] = tmp;}}}
}
int main()
{int arr[] = {3,1,7,5,8,9,0,2,4,6};int sz = sizeof(arr)/sizeof(arr[0]);bubble_sort(arr, sz);int i = 0;for(i=0; i<sz; i++){printf("%d ", arr[i]);}return 0;
}//⽅法2 - 优化
void bubble_sort(int arr[], int sz)//参数接收数组元素个数
{int i = 0;for (i = 0; i < sz - 1; i++){int flag = 1;//假设这⼀趟已经有序了int j = 0;for (j = 0; j < sz - i - 1; j++){if (arr[j] > arr[j + 1]){flag = 0;//发⽣交换就说明,⽆序int tmp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = tmp;}}if (flag == 1)//这⼀趟没交换就说明已经有序,后续⽆序排序了break;}
}
int main()
{int arr[] = { 3,1,7,5,8,9,0,2,4,6 };int sz = sizeof(arr) / sizeof(arr[0]);bubble_sort(arr, sz);int i = 0;for (i = 0; i < sz; i++){printf("%d ", arr[i]);}return 0;
}

qsort函数的使用

在cpp帮助文档中,qsort函数是这样定义的

在这里插入图片描述

作用是可以比较任意类型的数据,不限于整形,结构体类型等
其需要接受四个参数, 第一个参数可以理解为数组首元素地址, 第二参数为元素个数, 第三个为每个元素的大小, 第四个为一个函数指针,需要使用者自己定义, 函数指针有两个指针类型参数, 返回值为整形,当p1 > p2时返回1, 当p1 < p2 时返回-1, 当p1 = p2 时返回0.

在这里插入图片描述

1.使用qsort函数排序整型数据

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
//使用qsort函数排序整形数据
int int_cmp(const void* p1, const void* p2) {return (*(int*)p1 - *(int*)p2);
}
int main() {int arr[] = { 1,3,5,7,9,2,4,6,8,0 };qsort(arr, 10, sizeof(arr[0]), int_cmp);for (int i = 0; i < sizeof(arr)/sizeof(arr[0]); i++) {printf("%d ", arr[i]);}printf("\n");return 0;
}

2.使用qsort函数排序结构数据

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct Stu
{char name[20];int age;
};
//假设按照年龄来比较
int cmp_stu_by_age(const void* p1, const void* p2) 
{return ((struct Stu*)p1)->age - ((struct Stu*)p2)->age;
}
//假设按照名字来比较
int cmp_stu_by_name(const void*p1,const void *p2)
{return strcmp(((struct Stu*)p1)->name, ((struct Stu*)p2)->name);
}
void test1() 
{struct Stu s[] = { {"zhangsan",20},{"lisi",30},{"wangwu",15} };int sz = sizeof(s) / sizeof(s[0]);//qsort(s, sz, sizeof(s[0]), cmp_stu_by_age);qsort(s, sz, sizeof(s[0]), cmp_stu_by_name);
}int main() 
{test1();return 0;
}

冒泡排序模拟实现qsort函数

//两个整形比较函数
int int_cmp(const void*p1, const void*p2)
{return (*(int*)p1 - *(int*)p2);//强制类型转换成int*,解引用进行比较
}
//进行数据交换
void _swap(void* p1, void* p2,int size)
{for (int i = 0; i < size; i++) {//强制泪下转换成char*,解引用每次交换一个字节的内容,直到i==size为止char temp = *((char*)p1 + i);*((char*)p1 + i) = *((char*)p2 + i);*((char*)p2 + i) = temp;}
}
//模拟实现qsort
void bubble(void* base, int count, int size, int(*cmp)(const void*,const void*))
{for (int i = 0; i < count - 1; i++) {for (int j = 0; j < count - 1 - i; j++) {if (cmp((char*)base + j * size, (char*)base + (j + 1) * size) > 0) //如果比较结果>0则进行数据的交换,把base强制类型转换成字符型指针,并且加上
//j*size大小个字节			{_swap((char*)base + j * size, (char*)base + (j + 1) * size,size);}}}
}int main()
{int arr[] = { 1,3,5,7,9,2,4,6,8,0 };bubble(arr, sizeof(arr) / sizeof(arr[0]), sizeof(arr[0]), int_cmp);//这里传递比较整形类型函数for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++) {printf("%d ",arr[i]);}printf("\n");return 0;
}

今日题目

1. 字符串旋转结果

写一个函数,判断一个字符串是否为另外一个字符串旋转之后的字符串。

例如:给定s1 =AABCD和s2 = BCDAA,返回1

给定s1=abcd和s2=ACBD,返回0.

AABCD左旋一个字符得到ABCDA

AABCD左旋两个字符得到BCDAA

AABCD右旋一个字符得到DAABC

问题解析:

本题当然可以将所有旋转后的结果放到一个数组里,然后进行查找,但是这种做法既不好操作,也太费事,但是这题有一个很简单的做法:
其实ABCDE无论怎么旋,旋转后的所有结果,都包含在了ABCDEABCD这个字符串里了。
所以做法很简单,只需要将原字符串再来一遍接在后面,然后找一找待查找的字符串是不是两倍原字符串的子集即可。

代码如下:

int my_cmp(const char *src,const char *find) 
{char temp[256] = { 0 };strcpy(temp, src);strcat(temp, src);return strstr(temp, find) != NULL;
}int main() {char str1[100] = { 0 };char str2[100] = { 0 };scanf("%s %s", str1, str2);int ret = my_cmp(str1, str2);printf("%d\n", ret);return 0;
}

2.杨氏矩阵

有一个数字矩阵,矩阵的每行从左到右是递增的,矩阵从上到下是递增的,请编写程序在这样的矩阵中查找某个数字是否存在。

要求:时间复杂度小于O(N);

问题解析:

我们仔细分析,不难发现,对于杨氏矩阵老说,右上角和左下角的元素是有特点的。右上角的元素是一行中最大的,一列中最小的。左下角的元素是一行中最小的,是一列中最大的。所以我们可以从右上角或者左下角开始查找。比如:从右上角开始查找的时候,右上角的元素比我们要查找元素小,我们就可以去掉右上角元素所在的这一行;右上角的元素比我们要查找的元素大,我们就可以去掉右上角元素所在的这一列。然后依然找右上角的元素继续和要查找的元素与比较。这样每一次比较去掉一行或者去掉一列。这个查找效率是高于遍历数组元素的,所以时间复杂度是小于O(N),也满足题目要求。

代码如下:

int find_num(int a[3][3], int x, int y, int f)
{int i = 0;int j = y - 1;while (i < x && j >= 0){if (a[i][j] > f){i++;}else if (a[i][j] < f){j--;}else {return 1;}}return 0;
}
int main() 
{int arr[3][3] = {{1,3,5},{3,5,7},{5,7,9}};int ret = find_num(arr, 3, 3, 6);if (ret == 1) {printf("It has been found!\n");}else {printf("It hasn't been found!\n");}return 0;
}

3.猜凶手

日本某地发生了一件谋杀案,警察通过排查确定杀人凶手必为4个嫌疑犯的一个。

以下为4个嫌疑犯的供词:

A说:不是我。
B说:是C。
C说:是D。
D说:C在胡说
已知3个人说了真话,1个人说的是假话。
现在请根据这些信息,写一个程序来确定到底谁是凶手。

问题解析:

这个题就是按照正常方式,假设凶手是a,b,c,d其中的一个,看是不是满足题目条件,如果满足就找出了凶手。

代码如下:

int main() {int killer = 0;for (killer = 'a'; killer <= 'd';killer++) {if (('a' != killer) + ('c' == killer) + ('d' == killer) + ('d' != killer) == 3) {printf("凶手是:%c", killer);}}return 0;
}

4.杨辉三角

在屏幕上打印杨辉三角。

1

1 1

1 2 1

1 3 3 1

……

问题解析:

能发现数字规律为:d[i][j] = d[i - 1][j] + d[i - 1][j - 1]。所以我们只要按照这个方法填表即可。

代码如下:

void YangHui(int arr[][4], int n)
{for (int i = 0; i < n; i++){for (int j = 0; j <= i; j++){if (i == j || j == 0){arr[i][j] = 1;}else{arr[i][j] = arr[i - 1][j] + arr[i - 1][j - 1];}}}
}
void printArr(int arr[][4],int n)
{for (int i = 0; i < n; i++){for (int j = 0; j <= i; j++){printf("%d ", arr[i][j]);}printf("\n");}
}
int main() {int arr[4][4] = { 0 };YangHui(arr, 4);printArr(arr, 4);return 0;
}

总结

本文介绍了如何通过冒泡排序实现qsort函数的功能. 首先冒泡排序是一种简单直观的排序算法, 通过比较相邻元素的大小进行交换位置来实现排序, 而qsort是c语言标准库中提供的用于快速排序的函数, 示例中模拟实现了使用qsort对整形排序, 也可以实现对结构数据的排序, 让我们跟进一步理解qsort的底层原理. 如有错误 , 请评论留言 , 如果觉得文章有用的话 , 记得 点 赞 收 藏 !

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/817509.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Linux】线程的控制

目录 POSIX线程库 常用的POSIX线程库接口声明&#xff1a; 注意事项 创建一个进程 pthread_create函数 参数 返回值 使用示例 线程ID和进程地址空间布局 线程ID 进程地址空间布局 示例图 获取一个进程的线程ID 函数原型 返回值 使用示例 注意事项 线程终止 p…

设计模式系列:责任链模式

简介 责任链模式是一种行为型设计模式&#xff0c;它允许你将请求沿着处理者链进行发送。每个处理者都可以对请求进行处理&#xff0c;或者将其传递给链上的下一个处理者。责任链模式主要应用于面向对象编程中&#xff0c;特别是当系统中的对象需要根据其属性来决定如何处理请…

嘴尚绝美味健康:探索美食背后的健康密码

在快节奏的现代生活中&#xff0c;人们对美食的追求从未停止。然而&#xff0c;随着健康意识的提升&#xff0c;越来越多的人开始关注美食与健康的平衡。今天&#xff0c;我们就来一起探讨“嘴尚绝美味健康”这一话题&#xff0c;看看如何在享受美食的同时&#xff0c;保持身体…

JMeter入门教程 —— 事务!

简介&#xff1a; JMeter中事务的基本介绍 1.任务背景 JMeter中的事务是通过事务控制器实现的。&#xff0c;为了衡量服务器对某一个或一系列操作处理的响应时间&#xff0c;需要定义事务。下面我们详细介绍在JMeter中如何使用事务 2.任务目标 掌握基于JMeter性能测试脚本开…

speccpu2017安装与使用

国产化桌面下Speccpu2017安装与使用 1、 安装依赖库 安装speccpu2017前需要安装依赖包&#xff0c;通过终端命令对依赖包进行安装 sudo apt-get install gcc g gfortran &#xff08;以上是已经安装好的&#xff09; 注&#xff1a;若安装不上&#xff0c;需替换/etc/apt下的s…

Docker部署SpringBoot服务(Jar包映射部署)

介绍 项目在docker部署运行以后&#xff0c;每次需更新jar包时&#xff0c;都得重新制作镜像&#xff0c;再重新制作容器。流程及其繁琐&#xff0c;效率极低。 以下步骤是在不更新镜像和容器的前提下&#xff0c;直接更新jar完成项目更新的操作。 不更新镜像 1. 创建你存放…

几款高效在线文档编辑器推荐,编辑文档更轻松

在数字化时代&#xff0c;文档编辑工作变得越来越重要。无论是工作报告、学习笔记还是创意文稿&#xff0c;一个优秀的在线文档编辑器都能让你的工作事半功倍。现在市面上也有很多优秀的在线文档编辑器&#xff0c;比如WPS Office、腾讯文档、 Microsoft Word Online。今天&…

openGauss_5.0.1 企业版安装及问题记录(CentOS系统):主备模式服务器安装

目录 &#x1f4da;第一章 官方地址&#x1f4d7;安装包下载地址&#x1f4d7;文档指南 &#x1f4da;第二章 安装&#x1f4d7;准备工作&#x1f4d7;开始安装&#x1f4d5;创建XML配置文件&#x1f4d5;初始化安装环境&#x1f4d5;执行安装&#x1f4d5;验证 &#x1f4da;第…

【数据结构】第三节:单链表

前言 本篇要求掌握的C语言基础知识&#xff1a;指针、结构体 目录 前言 单链表 概念 对比链表和顺序表 创建链表 实现单链表 准备工作 打印链表 创建节点并初始化 尾插 二级指针的调用 尾插代码 头插 尾删 头删 查找&#xff08;返回节点&#xff09; 在指定位…

C#硬件接口开发------一文了解WMI

&#x1f388;个人主页&#xff1a;靓仔很忙i &#x1f4bb;B 站主页&#xff1a;&#x1f449;B站&#x1f448; &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏 &#x1f917;收录专栏&#xff1a;C# 硬件接口开发 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足…

优优嗨聚集团:如何优雅地解决个人债务问题,一步步走向财务自由

在快节奏的现代生活中&#xff0c;个人债务问题似乎已成为许多人不得不面对的挑战。正确处理个人债务&#xff0c;不仅关系到个人信用和财务状况&#xff0c;更是实现财务自由的重要一步。本文将为您提供一些实用的建议&#xff0c;帮助您优雅地解决个人债务问题&#xff0c;走…

设计模式之备忘录模式(下)

3&#xff09;实现多次撤销 1.结构图 对负责人类MementoCaretaker进行了修改&#xff0c;在其中定义了一个ArrayList类型的集合对象来存储多个备忘录。 2.代码实现 import java.util.*;public class MementoCaretaker {//定义一个集合来存储多个备忘录private ArrayList mem…

学员分享丨十年架构师感悟:敢于“提出问题”

最近呢小誉收到了一位工作十年的学员投稿&#xff0c;这位学员是2011年从誉天学习HCIE课程并顺利拿证&#xff0c;先后在华为等大厂工作。他想把他这十年的工作经验分享给各位学弟学妹们。 这些经验并非来自于具体的技术实现&#xff0c;而是在架构设计和实施过程中所体会到的一…

Github 2024-04-09 Python开源项目日报 Top10

根据Github Trendings的统计,今日(2024-04-09统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Python项目10Vue项目1JavaScript项目1系统设计指南 创建周期:2507 天开发语言:Python协议类型:OtherStar数量:241693 个Fork数量:42010 次…

C++生成动态库,C++和C#以及Java在windows和linux调用

Windows生成dllC库 1、创建动态链接库项目 源文件编写函数 // dllmain.cpp : 定义 DLL 应用程序的入口点。 #include "pch.h"int sum(int a, int b) {return a b; }BOOL APIENTRY DllMain( HMODULE hModule,DWORD ul_reason_for_call,LPVOID lpReserved) {switch…

【LAMMPS学习】八、基础知识(1.8)键的断裂

8. 基础知识 此部分描述了如何使用 LAMMPS 为用户和开发人员执行各种任务。术语表页面还列出了 MD 术语&#xff0c;以及相应 LAMMPS 手册页的链接。 LAMMPS 源代码分发的 examples 目录中包含的示例输入脚本以及示例脚本页面上突出显示的示例输入脚本还展示了如何设置和运行各…

取出/var/log/secure中一小时内登录失败超过三次的IP

取出/var/log/secure中一小时内登录失败超过三次的IP 前两个字段是日期&#xff0c;第三个字段是小时&#xff0c;第四个字段是IP cat /var/log/secure | sort -i | awk -F [ :] /Failed/{a[$1" "$2" "$3" "$4" "$(NF-3)]}END{for(i …

使用 Python 实现复制粘贴的功能

pandas 里面有一个 pd.read_clipboard 函数&#xff0c;可以根据你复制的内容生成DataFrame。是的&#xff0c;就是我们平时选中&#xff0c;然后 CtrlC 时拷贝的内容。所以比较神奇&#xff0c;那么 pandas 到底是怎么做到的&#xff0c;它是怎么读出我们使用 Ctrl C 复制的内…

【面试题】s += 1 和 s = s + 1的区别

文章目录 1.问题2.发现过程3.解析 1.问题 以下两个程序真的完全等同吗&#xff1f; short s 0; s 1; short s 0; s s 1; 2.发现过程 初看s 1 和 s s 1好像是等价的&#xff0c;没有什么区别。很长一段时间内我也是这么觉得&#xff0c;因为当时学习c语言的时候教科书…

更优性能与性价比,从自建 ELK 迁移到 SLS 开始

作者&#xff1a;荆磊 背景 ELK (Elasticsearch、Logstash、Kibana) 是当下开源领域主流的日志解决方案&#xff0c;在可观测场景下有比较广泛的应用。 随着数字化进程加速&#xff0c;机器数据日志增加&#xff0c;自建 ELK 在面临大规模数据、查询性能等方面有较多问题和挑…