使用冒泡排序模拟实现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的底层原理. 如有错误 , 请评论留言 , 如果觉得文章有用的话 , 记得 点 赞 收 藏 !

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

柯桥地区职业学校日语口语常用成人零基础入门

在日语中,“做饭”有几种表达方式: 1. 料理する 是最常用的说法,意思就是“做料理”。 例句: 毎日妻が料理をしている。 每天妻子都在做饭。 2. 食事を作る 意思是“做饭”,“制作膳食”。 例句: 友達のために食事#15857575376を作った。 为朋友做了饭。 编辑搜图 请点…

在uni-app使用iconfont中的图标

uni-app 如何使用iconfont中的图标 在uni-app中使用Iconfont图标通常涉及以下几个步骤&#xff1a; 步骤一&#xff1a;获取Iconfont资源 访问 iconfont-阿里巴巴矢量图标库&#xff0c;注册并登录账号。 浏览或搜索所需的图标&#xff0c;将它们添加至购物车或直接创建项目进…

下一代换脸和数字人生成神器Facefusion又更新了(懒人包)

号称“下一代换脸和数字人生成神器”的Facefusion软件在2024年3月底发布了最新的2.4.1版本&#xff0c;带来了一系列的更新和改进&#xff0c;使得人脸融合和分析技术更加易用和高效&#xff0c;以及一些性能和功能方面的全面提升。 Facefusion2.4.1版本更新亮点 Facefusion新…

【面试题】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语言的时候教科书…

Python学习笔记23 - 目录操作

os模块操作目录相关函数 os.path模块操作目录相关函数 案例1 —— 列出指定目录下的所有.py文件 案例2 —— walk()

模电和数电哪个更难学?

模电和数电各有其难点&#xff0c;因此很难说哪个更难。 模拟电路&#xff08;模电&#xff09;涉及到连续的电压和电流信号&#xff0c;其分析和设计需要考虑许多因素&#xff0c;如信号失真、噪声、频率响应等。模电的设计通常需要考虑更多的物理参数和元件特性&#xff0c;…

李廉洋:4.15黄金,原油最新资讯,美盘走势分析及策略。

由于欧洲央行很可能先于美联储降息&#xff0c;美元走强。法国兴业银行分析师基特•朱克斯表示&#xff0c;市场“假设我们看到欧洲央行将在6月降息&#xff0c;但美联储不会”&#xff0c;这对美元有利。朱克斯表示&#xff0c;尽管在货币政策决定之前会公布一些相关数据&…

Web应用程序中的常见安全漏洞

大家好&#xff0c;我是咕噜铁蛋&#xff01;今天&#xff0c;我想和大家聊聊一个在我们日常开发中经常遇到的问题——Web应用程序中的安全漏洞。在这个数字化时代&#xff0c;Web应用几乎无处不在&#xff0c;它们不仅方便了我们的生活&#xff0c;也推动了社会的进步。然而&a…

中霖教育:一建需不需要继续教育?

根据规定&#xff0c;一级建造师必须在其注册期内完成规定的继续教育学时&#xff0c;否则无法进行注册延期。 一级建造师的注册证书的有效期限设定为三年&#xff0c;为确保资格的有效性并申请续期&#xff0c;持证者需在该有效期内满足制定的继续教育标准。 继续教育课程结…

windows应急中的快捷键

windows应急中的快捷键 应急的时候&#xff0c;快捷键很重要&#xff0c;记录一下windows主机排查需要用到的快捷键 windows快捷键 appwiz.cpl 是打开安装面板 程序和功能 控制面板程序和功能 搜索程序和功能 控制而板主页 卸载或更改程序 若要卸酸程序,请从列表中将其…

【Java探索之旅】数组概念与初始化指南:动静结合

&#x1f3a5; 屿小夏 &#xff1a; 个人主页 &#x1f525;个人专栏 &#xff1a; Java编程秘籍 &#x1f304; 莫道桑榆晚&#xff0c;为霞尚满天&#xff01; 文章目录 &#x1f4d1;前言一、初识数组1.1 为什么要有数组&#xff1f;1.2 数组的的概念 二、数组的创建及初始化…

多模态(clip/ALBEF)

一. CLIP 1. clip的核心思想是通过海量的弱监督文本对通过对比学习&#xff0c;将图片和文本通过各自的预训练模型获得的编码向量在向量空间上对齐。 clip 的text encode: 在Text Encoder中&#xff0c;我们会对每个句子增加一个Class Token&#xff0c;用于整合特征&#x…

排序算法—堆排序

文章目录 堆排序堆思路过程建堆排序 代码实现 堆排序 时间复杂度&#xff1a;O(N*logN) 稳定性&#xff1a;不稳定&#xff08;相同元素排序后的相对位置改变&#xff09; 堆 堆的逻辑结构是一棵完全二叉树&#xff1b;堆的物理结构是一个数组&#xff0c;通过下标表示父子结…

推荐5款 深受欢迎 的AI开源项目

本周 GitHub圈选 项目推荐&#xff1a; InstantID&#xff08;小红书AI图像生成工具&#xff09; CWMP&#xff08;ChatGPT Web Midjourney Proxy&#xff09; aicover&#xff08;AI红包封面制作神器&#xff09; ML-YouTube-Courses&#xff08;机器学习的学习库&#xff…

深入K8S实战

K8S: 深入K8S实战进阶篇 1、搭建 Kubernetes 集群 1.1、搭建方案 1.1.1、minikube minikube 是一个工具&#xff0c; 能让你在本地运行 Kubernetes。 minikube 在你的个人计算机&#xff08;包括 Windows、macOS 和 Linux PC&#xff09;上运行一个一体化&#xff08;all-i…

Gartner 《2024安全和风险管理技术路线图》:高价值技术 DSP 进入广泛部署阶段

近期&#xff0c;Gartner 发布《2024年技术采用路线图&#xff1a;安全与风险管理》&#xff08;以下简称&#xff1a;《路线图》&#xff09;&#xff0c;该信息图表识别了全球企业正在采用的 44 种与安全相关的技术&#xff0c;并根据采用阶段、部署风险和企业价值进行了映射…

HuggingFists-如何复用流程(二)

上一篇文章中&#xff0c;我们介绍了如何在HuggingFists系统中复用流程。如何定义流程,接收外部数据流以及写出数据流。通过接收和写出数据流实现流程的嵌套引用。在实际的应用场景中&#xff0c;被引用的子流程除了需要与主流程的数据流进行交互外&#xff0c;有时其流程内部的…

悬镜安全持续霸榜安全牛《中国网络安全全景图》供应链安全赛道

2024年4月12日&#xff0c;国内知名网络安全专业咨询机构安全牛正式发布了第十一版网络安全行业全景图&#xff08;以下简称“全景图”&#xff09;&#xff0c;悬镜安全凭借沉淀多年的技术创新和应用实践&#xff0c;连续四年强势领跑数字供应链安全领域&#xff0c;引领DevSe…

MyBatis-Spring整合

引入Spring之前需要了解mybatis-spring包中的一些重要类&#xff1b; http://www.mybatis.org/spring/zh/index.html 什么是 MyBatis-Spring&#xff1f; MyBatis-Spring 会帮助你将 MyBatis 代码无缝地整合到 Spring 中。 知识基础 在开始使用 MyBatis-Spring 之前&#x…