数据结构:七种排序及总结

news2024/12/26 18:26:55

文章目录

  • 排序
  • 一插入排序
  • 1直接插入排序
  • 2希尔排序
  • 二选择排序
  • 3直接选择排序
  • 4堆排序
  • 三 交换排序
  • 5冒泡排序
  • 6快速排序
  • 四 归并排序
  • 7归并排序
  • 源码

排序

我们数据结构常见的排序有四大种,四大种又分为七小种,如图所示
在这里插入图片描述

排序:所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作。
稳定性:假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次
序保持不变,即在原序列中,r[i]=r[j],且r[i]在r[j]之前,而在排序后的序列中,r[i]仍在r[j]之前,则称这种排
序算法是稳定的;否则称为不稳定的。
内部排序:数据元素全部放在内存中的排序。
外部排序:数据元素太多不能同时放在内存中,根据排序过程的要求不断地在内外存之间移动数据的排序。

一插入排序

1直接插入排序

void InsertSort(int* a, int n);

从i=0开始遍历,每次i之前的序列都是有序的,通过判断当前i的值能够在i之前哪个位置,找到后直接插入,

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

为什么直接插入排序最坏的情况是n^2?
如果一个开始原序列是降序,想排为升序
第一个循环是n,第二个循环最坏是n,所以是最大n^2

void InsertSort(int* arr, int n) {


	for (int i = 0; i < n-1; i++) {
		int end = i;

		int tem = arr[end + 1];
		while (end >= 0) {
			

	
			if (arr[end] > tem) {

				arr[end + 1] = arr[end];
				end--;
			}
			else
			{
				
		
				break;
			}

		}
		arr[end + 1] = tem;
	
	
	}
	

}

2希尔排序

希尔排序是对直接插入排序的优化,大大优化了时间复杂度
他们是先规定了一个gap值,然后每次进行循环把gap值缩小,最后把 gap值调为1。这样最后一次排序就是直接插入排序,前面的是预排序。
条件就是

while(gap>1){
gap=gap/3+1;//最后一次gap=1随后跳出循环


}


void ShellSort(int* arr, int n) {

	int gap = n;
	while(gap>1){
		gap = gap / 3 + 1;
		for (int i = 0; i < n - gap; i++) {

			
			int end = i;

			int tem = arr[end +gap];
			while (end >= 0) {



				if (arr[end] > tem) {

					arr[end + gap] = arr[end];
					end-=gap;
				}
				else
				{



					break;
				}

			}
			arr[end + gap] = tem;
		}	
	
	}


}

在这里插入图片描述
判断两种排序的时间复杂度
在这里插入图片描述

二选择排序

3直接选择排序

直接选择排序就是一种很暴力的解法,思路简单,代码简单,但是时间复杂度很差,和 冒泡排序差不多
在这里插入图片描述
思路就是分别从两头找最大和最小,然后对下标进行++ – 然后直到相遇。

void SeletSort(int* arr, int n) {
	int end = n - 1;
	int begin = 0;
	int max, min;
	max = min = 0;
	while (begin < end) {
		max = min = begin;
		for (int i = begin + 1; i <= end; i++)
		{
		
			if (arr[i] > arr[max]) {
				max = i;

			}
			if (arr[i] < arr[min])
			{
				min = i;
			}

		}
		if (max == begin) {
			max = min;
		}
		Swap(&arr[min], &arr[begin]);
		Swap(&arr[max], &arr[end]);
		begin++;
		end--;

	}

}

有一种特殊情况要处理就是换的时候max在begin位置,因为先&arr[min], &arr[begin]换,所以要提前max=min.(此时最大值在min下标位置)

	if (max == begin) {	max = min;		}

时间复杂度n*(n/2+n/2)=n^2.

4堆排序

要了解堆排序我们要先了解一些误区:
1无论向下调整算案建堆还是向上调整算法建堆都是形成一个二叉树结构,本身并没有让数组完全有序,
2向下调整算法建堆比向上调整算法建堆时间复杂度更优
3排升序建大堆,排降序 建小堆。

所以我们要先完成堆排序的话要完成两个步骤,
1把原序列进行向下或向上调整遍历,成为一个堆的结构,
2因为头结点一定是最值,我们每次把arr[0]和arr[end]交换,再让end–完成之后就完成排序。

void HeapSort(HeapType* arr, int n) {//第一步

	for (int i = (n - 1 - 1) / 2; i >= 0; i--) {


		AdjustDown(arr, i, n);

	}
	int end = n - 1;
	for (int i = end; i > 0; i--) {//第二步
		Swap(&arr[0], &arr[end]);
		AdjustDown(arr, 0, end);
		end--;



	}
}

因为向下调整算法建堆的时间复杂度大概是O(n)
第二部大概是O(nlogn)
故时间复杂度O(n+n
logn)大概是O(n*logn).

三 交换排序

5冒泡排序

冒泡排序两层循环o(n^2)
加上优化还是最好情况O(n)所以是O(n^2)

void BubbleSort(int* a, int n) {
	for (int i = 0; i < n - 1; i++)
	{
		int xz = 0;
		for (int j = 0; j < n - i - 1; j++) {

			
			if (a[j] > a[j + 1]) {

				swap(&a[j], &a[j + 1]);
				xz = 1;
			}

			
		}
		if (xz == 0) {
			break;
		}

	}

}

6快速排序

快排我们用的找中间值 ,然后分区间,类似堆排序,时间复杂度o(nlogn)
按最情况来说,每次循环排最差情况是n/2+n/2=n,一共是logn次循环(最好情况,每次中间值恰好在中间)
按最坏情况是n次循环,所以时间复杂度为n
logn~n^2.

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

int GetKeyi(int* arr, int left, int right) {
	int keyi = left;
	left++;
	while (right>=left)
	{
		while (left<=right&&arr[right]>arr[keyi]) {
			right--;


		}

		while (left <= right && arr[left] < arr[keyi]) {

			left++;

			}
		if (left <= right) {

			swap(&arr[right--], &arr[left++]);
		}
		

	}

	swap(&arr[keyi], &arr[right]);
	return right;
}
void QuickSort(int* arr, int left,int right) {
	if (left >= right) {
		return;
	}
	int keyi = GetKeyi(arr, left, right);
	QuickSort(arr, left,keyi - 1);
	QuickSort(arr, keyi+1,right);

}

四 归并排序

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

7归并排序

归并排序的思想是通过二分找中间值,[left,中间值] ,[中间值+1,right]两个序列再二分,直到left>=中间值,然后通过递归返回原来的函数栈帧进行排序,因为只有logn个函数栈帧,每次栈帧内最坏排n个数据。

为了不破坏arr序列,我们定义了tem序列接收,然后最后把tem数组覆盖arr,
时间复杂度为n*logn

void MergeSort(int* arr, int n) {
	int* tem = (int*)malloc(sizeof(int) * n);
	_MergeSort(arr,0, n - 1,tem);
	free(tem);



}
void _MergeSort(int* arr, int left, int right, int* tem) {
	if (left >= right) {
		return;
	}
	int mid = (left + right) / 2;
	_MergeSort(arr, left, mid, tem);
	_MergeSort(arr, mid+1, right, tem);
	int begin1 = left;
	int begin2 = mid + 1;
	int end1 = mid;
	int end2 = right;
	int x = begin1;
	while (begin1 <= end1 && begin2 <= end2) {

		if (arr[begin1] < arr[begin2]) {	
			tem[x++] = arr[begin1++];
		}
		else
		{
			tem[x++] = arr[begin2++];
		}
	}
	while (begin1 <= end1) {
		tem[x++] = arr[begin1++];
	}
	
	while (begin2 <= end2) {
		tem[x++] = arr[begin2++];
	}
	for (int i = left; i < right; i++)
	{
		arr[i] = tem[i];
	}
}

最后总结一下所有排序时间
在这里插入图片描述

源码

Sort.h

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<assert.h>
#include<stdbool.h>
typedef int HeapType;
typedef struct Heap {

	HeapType* a;
	int capacity;
	int size;

}Heap;
void SeletSort(HeapType* arr, int n);
void Inite(Heap* p);
void Push(Heap* p, HeapType x);
void Pop(Heap* p);
bool Empty(Heap* p);
HeapType Top(Heap* p);
void Print(Heap* p);
void Destry(Heap* p);
void Swap(HeapType* a, HeapType* b);
void AdjustUp(HeapType* a, int child);
void AdjustDown(HeapType* a, int parent, int n);
void HeapSort(HeapType* arr, int n);

void BubbleSort(int* a, int n);
void swap(int* a, int* b);
void InsertSort(int* arr, int n);
void ShellSort(int* arr, int n);
int GetKeyi(int* arr, int left, int right);
void QuickSort(int* arr, int left, int right);
void MergeSort(int* arr,int n);
void _MergeSort(int* arr, int left, int right, int* tem);

void test();

test.c

#define  _CRT_SECURE_NO_WARNINGS 1
#include"Sort.h"
#include"time.h"
#include"stdlib.h"

int main() {
	test();




	return 0;
}

Sort.c

#define  _CRT_SECURE_NO_WARNINGS 1
#include"Sort.h"


void test() {
	srand((unsigned)time(0));
	const int N = 100000;
	int* a1 = (int*)malloc(sizeof(int) * N);//创建100000个空间的数组

	int* a2 = (int*)malloc(sizeof(int) * N);//创建100000个空间的数组
	int* a3 = (int*)malloc(sizeof(int) * N);//创建100000个空间的数组

	int* a4 = (int*)malloc(sizeof(int) * N);
	int* a5 = (int*)malloc(sizeof(int) * N);
	int* a6 = (int*)malloc(sizeof(int) * N);
	int* a7 = (int*)malloc(sizeof(int) * N);
	for (int i = 0; i < N; i++) {
		a1[i] = rand();//循环100000次,每次赋予a1数组随机值

		a2[i] = a1[i];//赋值值来自上次一数组
		a3[i] = a1[i];
		a4[i] = a1[i];
		a5[i] = a1[i];
		a6[i] = a1[i];
		a7[i] = a1[i];


	}
	int begin1 = clock();
	InsertSort(a1, N);
	int end1 = clock();
	int begin2 = clock();
	ShellSort(a2, N);
	int end2 = clock();
	int begin3= clock();
	SeletSort(a3, N);
	int end3 = clock();
	int begin4 = clock();
	HeapSort(a4, N);
	int end4 = clock();
	int begin5 = clock();
	BubbleSort(a5, N);
	int end5 = clock();
	int begin6= clock();
	QuickSort(a6, 0,N-1);
	int end6 = clock();
	int begin7 = clock();
	MergeSort(a7,  N - 1);
	int end7 = clock();
	
	
	printf("InsertSort:%d\n", end1 - begin1);
	printf("ShellSort:%d\n", end2 - begin2);
	printf("SelectSort:%d\n", end3 - begin3);
	printf("HeapSort:%d\n", end4 - begin4);
	printf("BubbleSort:%d\n", end5 - begin5);
	printf("QuickSort:%d\n", end6 - begin6);
	printf("MergeSort:%d\n", end7 - begin7);






}
void swap(int* a, int* b) {
	int tmp = *a;

	*a = *b;
	*b = tmp;



}
void BubbleSort(int* a, int n) {
	for (int i = 0; i < n - 1; i++)
	{
		int xz = 0;
		for (int j = 0; j < n - i - 1; j++) {

			
			if (a[j] > a[j + 1]) {

				swap(&a[j], &a[j + 1]);
				xz = 1;
			}

			
		}
		if (xz == 0) {
			break;
		}

	}

}

void InsertSort(int* arr, int n) {


	for (int i = 0; i < n - 1; i++) {
		int end = i;

		int tem = arr[end + 1];
		while (end >= 0) {



			if (arr[end] > tem) {

				arr[end + 1] = arr[end];
				end--;
			}
			else
			{


				break;
			}

		}
		arr[end + 1] = tem;


	}


}
void ShellSort(int* arr, int n) {

	int gap = n;
	while (gap > 1) {
		gap = gap / 3 + 1;
		for (int i = 0; i < n - gap; i++) {


			int end = i;

			int tem = arr[end + gap];
			while (end >= 0) {



				if (arr[end] > tem) {

					arr[end + gap] = arr[end];
					end -= gap;
				}
				else
				{



					break;
				}

			}
			arr[end + gap] = tem;
		}

	}


}
void SeletSort(int* arr, int n) {
	int end = n - 1;
	int begin = 0;
	int max, min;
	max = min = 0;
	while (begin < end) {
		max = min = begin;
		for (int i = begin + 1; i <= end; i++)
		{

			if (arr[i] > arr[max]) {
				max = i;

			}
			if (arr[i] < arr[min])
			{
				min = i;
			}

		}
		if (max == begin) {
			max = min;
		}
		Swap(&arr[min], &arr[begin]);
		Swap(&arr[max], &arr[end]);
		begin++;
		end--;

	}

}
void Inite(Heap* p) {
	p->a = NULL;
	p->capacity = p->size = 0;



}
void Push(Heap* php, HeapType x)
{
	assert(php);

	if (php->size == php->capacity)
	{
		int newcapacity = php->capacity == 0 ? 4 : php->capacity * 2;
		HeapType* tmp = (HeapType*)realloc(php->a, newcapacity * sizeof(HeapType));
		if (tmp == NULL)
		{
			perror("realloc fail");
			return;
		}

		php->a = tmp;
		php->capacity = newcapacity;
	}

	php->a[php->size] = x;
	php->size++;

	AdjustUp(php->a, php->size - 1);
}
void Pop(Heap* p) {
	Swap(&p->a[0], &p->a[p->size - 1]);



	p->size--;
	AdjustDown(p->a, 0, p->size);


}
bool Empty(Heap* p) {
	return p->size == 0;


}
HeapType Top(Heap* p) {

	return p->a[0];

}
void Print(Heap* p) {
	{
		while (!Empty(p))
		{
			printf("%d ", Top(p));
			Pop(p);
		}

	}
}
void Swap(HeapType* a, HeapType* b) {

	int tem = *a;
	*a = *b;
	*b = tem;

}
void AdjustUp(HeapType* a, int child) {


	int parent = (child - 1) / 2;
	while (child > 0) {
		if (a[child] < a[parent])
		{
			Swap(&a[child], &a[parent]);
			child = parent;
			parent = (child - 1) / 2;

		}

		else
		{
			break;
		}

	}

}



void AdjustDown(HeapType* a, int parent, int n) {
	int child = parent * 2 + 1;
	while (child < n)
	{
		if (child + 1 < n && a[child] > a[child + 1]) {
			child = child + 1;


		}
		if (a[parent] > a[child]) {
			Swap(&a[parent], &a[child]);
			parent = child;
			child = child * 2 + 1;
		}
		else
		{
			break;
		}

	}

}
void HeapSort(HeapType* arr, int n) {

	for (int i = (n - 1 - 1) / 2; i >= 0; i--) {


		AdjustDown(arr, i, n);

	}
	int end = n - 1;
	for (int i = end; i > 0; i--) {
		Swap(&arr[0], &arr[end]);
		AdjustDown(arr, 0, end);
		end--;



	}
}
int GetKeyi(int* arr, int left, int right) {
	int keyi = left;
	left++;
	while (right>=left)
	{
		while (left<=right&&arr[right]>arr[keyi]) {
			right--;


		}

		while (left <= right && arr[left] < arr[keyi]) {

			left++;

			}
		if (left <= right) {

			swap(&arr[right--], &arr[left++]);
		}
		

	}

	swap(&arr[keyi], &arr[right]);
	return right;
}
void QuickSort(int* arr, int left,int right) {
	if (left >= right) {
		return;
	}
	int keyi = GetKeyi(arr, left, right);
	QuickSort(arr, left,keyi - 1);
	QuickSort(arr, keyi+1,right);

}
void MergeSort(int* arr, int n) {
	int* tem = (int*)malloc(sizeof(int) * n);
	_MergeSort(arr,0, n - 1,tem);
	free(tem);



}
void _MergeSort(int* arr, int left, int right, int* tem) {
	if (left >= right) {
		return;
	}
	int mid = (left + right) / 2;
	_MergeSort(arr, left, mid, tem);
	_MergeSort(arr, mid+1, right, tem);
	int begin1 = left;
	int begin2 = mid + 1;
	int end1 = mid;
	int end2 = right;
	int x = begin1;
	while (begin1 <= end1 && begin2 <= end2) {

		if (arr[begin1] < arr[begin2]) {	
			tem[x++] = arr[begin1++];
		}
		else
		{
			tem[x++] = arr[begin2++];
		}
	}
	while (begin1 <= end1) {
		tem[x++] = arr[begin1++];
	}
	
	while (begin2 <= end2) {
		tem[x++] = arr[begin2++];
	}
	for (int i = left; i < right; i++)
	{
		arr[i] = tem[i];
	}
}



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

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

相关文章

基于STM32H7XX的Bootloader启动与FOTA

1. Bootloader是如何工作的: 2.正常情况下,程序从flash启动时的启动流程,如下图所示: 首先程序从flash启动,根据中断向量表找到复位中断处理函数的地址(0x0800 0004处是中断向量表的起始地址,记录了复位中断处理函数的地址)。执行复位中断处理函数,初始化系统环境之后…

语音 AI 迎来爆发期,也仍然隐藏着被低估的机会丨RTE2024 音频技术和 Voice AI 专场

在人工智能快速发展的今天&#xff0c;语音交互技术正经历一场革命性的变革。从语音识别到语音合成&#xff0c;再到端到端的语音对话系统&#xff0c;这一领域的创新正以前所未有的速度推进。这些进步不仅提升了技术指标&#xff0c;更为实时翻译、虚拟数字人、智能客服等实时…

【自学笔记】神经网络(1)

文章目录 介绍模型结构层&#xff08;Layer&#xff09;神经元 前向传播反向传播Q1: 为什么要用向量Q2: 不用激活函数会发生什么 介绍 我们已经学习了简单的分类任务和回归任务&#xff0c;也认识了逻辑回归和正则化等技巧&#xff0c;已经可以搭建一个简单的神经网络模型了。 …

在内蒙考驾照需要注意什么呢?

一、报名条件 年满18周岁&#xff0c;具有完全民事行为能力的中国公民。持有有效的身份证明文件。身体健康&#xff0c;无妨碍驾驶机动车的疾病&#xff0c;并需要通过体检。 二、选择驾校 可以先向身边已经拿到驾照的朋友咨询&#xff0c;了解驾校的距离、位置、口碑等信息。…

C++builder中的人工智能(8)什么是神经网络中的恒等激活函数?

在这篇文章中&#xff0c;我们将回答以下问题&#xff1a; 你想了解神经网络中最简单的激活函数是什么吗&#xff1f;什么是恒等函数&#xff1f;作为AI术语&#xff0c;我们需要了解激活函数和转移函数的哪些知识&#xff1f;激活函数与净输入函数是一回事吗&#xff1f;是否…

django图书管理系统-计算机毕业设计源码00648

摘要 图书管理系统在数字化阅读趋势、图书馆自动化管理、用户体验需求和信息技术应用等方面具有重要的研究意义。图书馆自动化管理系统的引入和应用提高了图书借阅过程的效率和准确性&#xff0c;减少了对手工操作和纸质记录的需求。用户对系统的易用性、查询速度、借还流程有更…

文件系统和日志管理

文件系统 文件系统&#xff1a; 文件系统提供了一个接口&#xff0c;用户用来访问硬件设备硬件设备上对文件的管理 存储单位 文件存储在硬盘上&#xff0c;硬盘最小的存储单位是512字节 扇区&#xff0c;文件在硬盘上的最小存储单位&#xff1a;块block&#xff0c;一个块的…

【代码转换】如何用 GPT 将 Python2代码 转换为 Python3代码 :实战教程

文章目录 1. 为什么要将 Python 2 代码迁移到 Python 3&#xff1f;2. 使用 ChatGPT 进行代码转换的步骤步骤1&#xff1a;打开CodeMoss步骤2&#xff1a;在输入框输入符号&#xff0c;选择代码转换步骤3&#xff1a;在这里选择你要更改的具体代码步骤4&#xff1a;准备 Python…

「Mac畅玩鸿蒙与硬件27」UI互动应用篇4 - 猫与灯的互动应用

本篇将带领你实现一个趣味十足的互动应用&#xff0c;用户点击按钮时猫会在一排灯之间移动&#xff0c;猫所在的位置灯会亮起&#xff08;on&#xff09;&#xff0c;其余灯会熄灭&#xff08;off&#xff09;。应用会根据用户的操作动态更新灯光状态和文本提示当前亮灯的位置&…

ES海量数据插入如何优化性能?

2024年10月NJSD技术盛典暨第十届NJSD软件开发者大会、第八届IAS互联网架构大会在南京召开。百度文心快码总经理臧志分享了《AI原生研发新范式的实践与思考》&#xff0c;探讨了大模型赋能下的研发变革及如何在公司和行业中落地&#xff0c;AI原生研发新范式的内涵和推动经验。 …

OTFS基带通信系统(脉冲导频,信道估计,MP解调算法)

Embedded Pilot-Aided Channel Estimation for OTFS in Delay–Doppler Channels | IEEE Journals & Magazine | IEEE Xplore 一、OTFS通信系统 如下图简要概括了OTFS基带通信系统过程&#xff0c;废话不多说给出完整系统详细代码。 以下仿真结果基于四抽头信道 估计信道…

理解Web登录机制:会话管理与跟踪技术解析(二)-JWT令牌

JWT令牌是一种用于安全地在各方之间传递信息的开放标准&#xff0c;它不仅能够验证用户的身份&#xff0c;还可以安全地传递有用的信息。由于其结构简单且基于JSON&#xff0c;JWT可以在不同的系统、平台和语言间无缝传递&#xff0c;成为现代Web开发中不可或缺的一部分。 文章…

微积分复习笔记 Calculus Volume 1 - 4.8 L’Hôpital’s Rule

4.8 L’Hpital’s Rule - Calculus Volume 1 | OpenStax

用户流定义:绘制产品交互流程图

产品经理在进行产品设计时&#xff0c;经常利用交互流程图来提升团队的工作效率。这种流程图适用于传达方案、评审目标等需要团队协作的场景&#xff0c;使得视觉设计师、产品开发等团队成员能够迅速理解图示内容&#xff0c;节省了理解时间&#xff0c;有效提高了沟通效率。 …

Linux -- 冯诺依曼体系结构(硬件)

目录 概念 五大组成部分 为什么需要存储器&#xff1f; 计算机存储金字塔层状结构 为什么程序需要加载到内存中 概念 冯诺依曼体系结构是以数学家冯诺依曼的名字命名的一种计算机体系结构。这种体系结构是现代计算机的基础&#xff0c;它定义了计算机的基本组件及其相互…

群控系统服务端开发模式-应用开发-本地上传工厂及阿里云上传工厂开发

记住业务流程图&#xff0c;要不然不清楚自己封装的是什么东西。 一、本地工厂开发 在根目录下extend文件夹下Upload文件夹下channel文件夹中&#xff0c;我们修改LocalUpload业务控制器。具体代码如下&#xff1a; <?php /*** 本地上传工厂* User: 龙哥 三年风水* Date: …

鹧鸪云光伏小程序上线啦

为了适应市场的发展需求&#xff0c;现推出了手机端SaaS版的光伏小程序&#xff0c;里面包含很多免费的小工具&#xff0c;供给我们业务人员、施工人员方便手机上操作&#xff0c;省去了带着电脑的笨重。下面给大家介绍下里面的免费小工具。 功率的换算&#xff1a;这里主要计…

WireShark入门学习笔记

学习视频&#xff1a;WireShark入门使用教程 扩展学习&#xff1a;wireshark分析常见的网络协议 文章目录 WireShark介绍WireShark抓包入门操作WireShark过滤器使用WireShark之ARP协议分析WireShark之ICMP协议TCP连接的3次握手协议TCP连接断开的4次挥手协议WireShark抓HTTP协…

人工智能之人脸识别(人脸采集人脸识别)

文章目录 前言PySimpleGUI 库1-布局和窗口2 文本框组件3-视频处理图片处理数据库操作数据采集&#xff08;重要部分&#xff09;人脸识别&#xff08;综合部分&#xff09; 前言 例如&#xff1a;随着人工智能的不断发展&#xff0c;本文主要介绍关于人工智能中GUI和PyMysql相…

qt5将程序打包并使用

一、封装程序 (1)、点击创建项目->库->clibrary &#xff08;2&#xff09;、填写自己想要封装成库的名称&#xff0c;这里我填写的名称为mydll1 &#xff08;3&#xff09;、如果没有特殊的要求&#xff0c;则一路下一步&#xff0c;最终会出现如下文件列表。 (4)、删…