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

news2024/9/24 11:21:20

目录

  • 冒泡排序
  • 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.coloradmin.cn/o/1596067.html

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

相关文章

ros-param添加参数控制rviz显示掉帧问题

在ros中有一套参数系统可以直接写到launch文件中&#xff0c;这样非常方便&#xff0c;不需要编译就能直接用&#xff0c;这对于c来说非常的有好&#xff0c;这里记录一下如何使用。 主要步骤如下&#xff1a; 首先初始化节点 使用nodehandle进行管理&#xff0c;然后通过param…

停车场道闸系统的实施流程有哪些安装注意事项?

随着城市交通压力的不断增加&#xff0c;停车场道闸系统的安装与优化成为了提升城市交通效率的关键环节。不同类型的停车场&#xff0c;如社区、园区、公共交通站点以及商业综合体等&#xff0c;都有其独特的运营特点和用户需求。因此&#xff0c;了解并掌握停车场道闸系统安装…

腾讯客户端开发实习一面

听说腾讯25年5000offer&#xff0c;我就去了...投完简历&#xff0c;当天晚上做完测评&#xff0c;第二天下午打电话约了第三天面试&#xff0c;额流程很快&#xff0c;快到第三天就寄了... 写在这里做个记录&#xff0c;也可以给学习学妹们经验&#xff0c;文末也有大厂面经合…

VSCode中vue的packag.json报错:unable to load schema from‘ http://json.schema‘...问题解决

package.json有这个报错&#xff0c;类似于这种问题一般是网络连接有问题&#xff0c;无法加载重启一下就好。 但是如果是没有网络或者云桌面等环境不能连接外网&#xff0c;就在设置中把这个设置一下&#xff0c;这样就不报错了&#xff0c;根据需要选择处理。

element问题总结之el-table使用fixed固定列后滚动条滑动到底部或者最右侧的时候错位问题

el-table使用fixed固定列后滚动条滑动到底部或者最右侧的时候错位 效果图前言解决方案纵向滑动滚动条滑动到底部的错位解决横向滚动条滑动到最右侧的错位解决 效果图 前言 在使用el-table固定行的时候移动滚动条会发现移动到底部或者移动到最右侧的时候会出现表头和内容错位或…

CentOS7使用Docker搭建Joplin Server并实现多端同步与公网使用本地笔记

文章目录 1. 安装Docker2. 自建Joplin服务器3. 搭建Joplin Sever4. 安装cpolar内网穿透5. 创建远程连接的固定公网地址 Joplin 是一个开源的笔记工具&#xff0c;拥有 Windows/macOS/Linux/iOS/Android/Terminal 版本的客户端。多端同步功能是笔记工具最重要的功能&#xff0c;…

python怎么输出小数

先将整型转换成float型&#xff0c;再进行计算&#xff0c;结果就有小数了。 >>> a 10 >>> b 4 >>> c a/b >>> a,b,c (10, 4, 2) >>> a float(a) >>> d a/b >>> a,b,d (10.0, 4, 2.5) >>> 注意&…

ES6-2:Iterator、Proxy、Promise、生成器函数...

11-Iterator迭代器 打印出的是里面的内容&#xff0c;如果是for in打印出来的是索引&#xff0c;of不能遍历对象Symbol.iterator是js内置的&#xff0c;可以访问直接对象arr[Symbol.iterator]&#xff0c;()调用对象非线性一般不能迭代 后两个是伪数组&#xff0c;但是是真迭…

QT、ffmpeg视频监控分屏

1、支持分屏&#xff08;4&#xff0c;6&#xff0c;8&#xff0c;9&#xff0c;13&#xff0c;16&#xff0c;25&#xff0c;32&#xff0c;64&#xff09;切换 2、支持拖拽效果 3、支持播放mp4&#xff0c;rtmp等 4、本人亲测支持播放32路&#xff0c;64路没做测试 5、支持读…

12.文件浏览器

子程序参数的使用 1.可空的用法&#xff1b;表示这个参数不写也行。 2.如何使用递归 3.需要注意的事 递归的子程序必须有个退出的条件 注意区分递归和循环&#xff0c;不要混用 流程&#xff1a; 1.插入按钮&#xff0c;输入输出调试文本&#xff08;“按钮被单击”&…

Windows本地部署Ollama+qwen本地大语言模型Web交互界面并实现公网访问

文章目录 前言1. 运行Ollama2. 安装Open WebUI2.1 在Windows系统安装Docker2.2 使用Docker部署Open WebUI 3. 安装内网穿透工具4. 创建固定公网地址 前言 本文主要介绍如何在Windows系统快速部署Ollama开源大语言模型运行工具&#xff0c;并安装Open WebUI结合cpolar内网穿透软…

三次握手与四次挥手到底是怎么回事?

三次握手和四次挥手是TCP/IP协议中建立和断开连接的关键步骤&#xff0c;它们是保证可靠通信的重要机制。这里将探讨这两个概念&#xff0c;并解释它们背后的原理。 三次握手 三次握手用于建立TCP连接&#xff0c;它由客户端和服务器之间发送的三个报文组成&#xff1a; 第一次…

竞赛 基于Django与深度学习的股票预测系统

文章目录 0 前言1 课题背景2 实现效果3 Django框架4 数据整理5 模型准备和训练6 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; **基于Django与深度学习的股票预测系统 ** 该项目较为新颖&#xff0c;适合作为竞赛课题方向&#xff…

怎么使用JMeter进行性能测试?

一、简介 JMeter是Apache软件基金会下的一款开源的性能测试工具&#xff0c;完全由Java开发。它专注于对我们应用程序进行负载测试和性能测量&#xff0c;最初设计用于web应用程序&#xff0c;现在已经扩展到其他测试功能&#xff0c;比如&#xff1a;FTP、Database和LDAP等。…

【题目】【信息安全管理与评估】2022年国赛高职组“信息安全管理与评估”赛项样题5

【题目】【信息安全管理与评估】2022年国赛高职组“信息安全管理与评估”赛项样题5 第一阶段竞赛项目试题 本文件为信息安全管理与评估项目竞赛-第一阶段试题&#xff0c;第一阶段内容包括&#xff1a;网络平台搭建与设备安全防护。 本次比赛时间为180分钟。 介绍 竞赛阶段…

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

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

广西有多少家建筑模板企业?

作为一个建筑大省,广西地区建筑模板企业数量可谓不少。这些企业规模大小不一,生产能力和产品质量参差不齐。然而,在这些企业中,有一家脱颖而出,备受业内推崇,那就是贵港市能强优品木业有限公司。 能强优品木业有限公司是广西知名的建筑模版生产厂家,拥有25年的丰富生产经验。公…

弹性 MapReduce(EMR)

一.产品简介 1产品概述 E腾讯云 EMR 提供基于云服务器&#xff08;CVM&#xff09;和容器服务&#xff08;TKE&#xff09;两种部署运行方式&#xff1a; 2.Agent 的安装目录 Linux 安装目录是/usr/local/qcloud/stargate和/usr/local/qcloud/monitor CoreOs 安装目录是/va…

蓝桥杯之注意事项

1.特殊求解的地方 2.一些数学公式 比如二叉树求全深度数值那道题 3.掌握有关库函数 #include<algorithm> 包含sort&#xff08;&#xff09;函数【排列函数】C sort()排序详解-CSDN博客&#xff0c;next_permutation()函数【求解全排列问题】求解数组大小sizeof(arr…

如何在Windows使用固定公网地址SSH远程访问本地Archcraft系统

文章目录 1. 本地SSH连接测试2. Archcraft安装Cpolar3. 配置 SSH公网地址4. 公网远程SSH连接小结 5. 固定SSH公网地址6. SSH固定地址连接 Archcraft是一个基于Arch Linux的Linux发行版&#xff0c;它使用最简主义的窗口管理器而不是功能齐全的桌面环境来提供图形化用户界面。 C…