数据结构实验10.1:内部排序的基本运算

news2025/5/23 22:03:21

文章目录

  • 一,实验目的
  • 二,实验内容
      • 1. 数据生成与初始化
      • 2. 排序算法实现
        • (1)直接插入排序
        • (2)二分插入排序
        • (3)希尔排序
        • (4)冒泡排序
        • (5)快速排序
        • (6)简单选择排序
        • (7)堆排序
        • (8)二路归并排序
      • 3. 统计与输出
  • 三,实验要求
      • (1)实验步骤与要求
      • (2)注意事项
  • 四、数据结构设计
  • 五,示例代码
    • 10-1.cpp源代码
  • 六,操作步骤
  • 七,运行结果


一,实验目的

  1. 深入理解排序原理:掌握排序的基本概念、分类及稳定性等特性,明确不同排序算法的适用场景。
  2. 熟练实现经典算法:通过编码实现直接插入、二分插入、希尔、冒泡、快速、简单选择、堆、二路归并等8种排序算法,加深对算法逻辑的理解。
  3. 提升算法应用能力:运用排序算法解决实际数据处理问题,通过统计比较次数和移动次数量化分析算法效率,增强算法优化思维。

二,实验内容

1. 数据生成与初始化

  • 使用随机数函数 rand() 生成范围在 [1, MAXNUM-1] 的随机整数序列(MAXNUM 设为100),确保序列长度可由用户指定(1~99)。
  • 示例序列(假设长度为8):[49, 38, 65, 97, 76, 13, 27, 49]

2. 排序算法实现

(1)直接插入排序
  • 思想:从第二个元素开始,将当前元素插入到已排序子序列的合适位置,通过顺序比较和移动实现。
  • 稳定性:稳定。
(2)二分插入排序
  • 优化:利用二分查找确定插入位置,减少比较次数,移动次数与直接插入相同。
  • 稳定性:稳定。
(3)希尔排序
  • 思想:按增量序列分组,对每组进行直接插入排序,逐步缩小增量至1。
  • 增量序列5, 3, 1(示例)。
  • 稳定性:不稳定。
(4)冒泡排序
  • 思想:相邻元素比较,逆序时交换,每趟将最大元素“冒泡”到末尾。
  • 优化:设置标记change,若某趟无交换则提前终止。
  • 稳定性:稳定。
(5)快速排序
  • 思想:选择基准值,通过分区操作将序列分为两部分,递归排序。
  • 分区策略:Hoare法(左右指针交替移动)。
  • 稳定性:不稳定。
(6)简单选择排序
  • 思想:每趟选择未排序部分的最小元素,与当前位置交换。
  • 稳定性:不稳定(相同元素相对顺序可能改变)。
(7)堆排序
  • 思想:构建大顶堆,每次将堆顶元素与末尾元素交换,调整堆结构。
  • 步骤:建堆 → 交换堆顶与末尾 → 调整堆。
  • 稳定性:不稳定。
(8)二路归并排序
  • 思想:递归分割序列,合并两个有序子序列。
  • 辅助空间:需要额外数组存储临时合并结果。
  • 稳定性:稳定。

3. 统计与输出

  • 比较次数(cp):记录关键字比较操作的总次数。
  • 移动次数(mv):记录元素赋值操作的总次数(如交换、插入等)。
  • 输出内容
    • 原始序列与排序后序列;
    • 各算法的比较次数和移动次数;
    • 算法效率对比表格。

三,实验要求

(1)实验步骤与要求

  1. 代码补全

    • 参照提供的参考程序,补全各算法中缺失的代码(如循环条件、指针移动逻辑等),确保算法逻辑正确。
    • 示例补全点
      • 快速排序分区函数中左右指针的移动条件(j--/i++);
      • 冒泡排序的交换标记change初始化与更新。
  2. 调试与测试

    • 测试用例
      • 随机序列(如长度10、50、99);
      • 特殊序列(正序、逆序、重复元素多的序列)。
    • 调试要点
      • 确保随机数生成正确,无越界访问;
      • 验证各算法排序结果是否正确,统计计数器(cpmv)是否准确。
  3. 数据记录与分析

    • 表格示例
排序算法比较次数(cp)移动次数(mv)耗时(ms)稳定性
直接插入排序352812稳定
快速排序22155不稳定
  • 分析方向
    • 比较次数与序列初始有序度的关系(如冒泡排序在正序时比较次数最少);
    • 移动次数与算法特性的关联(如归并排序移动次数较多但比较次数稳定);
    • 稳定性对特定场景的影响(如稳定排序适用于多关键字排序)。

(2)注意事项

  • 空间复杂度:归并排序需要额外空间(O(n)),其他算法多为原地排序(O(1),除堆排序的辅助空间)。
  • 时间复杂度对比
    • 最优/平均情况:快速排序、归并排序(O(n log n));
    • 最坏情况:直接插入、冒泡、简单选择(O(n²))。
  • 代码规范:添加必要注释,确保变量命名清晰(如cp为comparison count,mv为movement count)。

四、数据结构设计

#define MAXNUM 100
typedef int KeyType;				// 定义关键字类型为整型
typedef struct {
KeyType	key;					// 关键字项
   	int 		other;				// 其他数据项
}ElemType;						// 元素类型
typedef struct {
   	ElemType	r[MAXNUM+1];  // r[0]闲置或用作哨兵
    int 			length;			// 待排序元素个数
} SqList;							// 顺序表类型

五,示例代码

10-1.cpp源代码

#define MAXNUM 100
#define TRUE 1
#define FALSE 0
#include<stdio.h>
#include<stdlib.h>
#include<time.h>

typedef int KeyType;
typedef struct {			// 定义元素的结构类型
   KeyType  key;	
   int      other;
} ElemType;

typedef struct {			// 定义排序表结构类型
	ElemType r[MAXNUM+1];
    int length;
} SqList;

//(1)创建随机数排序表
void CreatList(SqList &L) {
	int i;
	do {
		printf("  输入排序表长度(1-%d)==>", MAXNUM-1);
		scanf("%d", &L.length);
	} while(L.length<1 || L.length>MAXNUM-1);
	
	srand((unsigned)time(NULL));
	for(i=1; i<=L.length; i++) 			// 随机产生排序表
		L.r[i].key = 1 + rand()%(MAXNUM-1);
}

// (2)直接插入排序
void InsertSort(SqList &L, int &cp, int &mv) {
	int i, j;
	for(i=2; i<=L.length; i++) {
		cp++;
		if (L.r[i].key < L.r[i-1].key) {
			L.r[0] = L.r[i]; mv++;
			for(j=i-1; L.r[0].key < L.r[j].key; j--) 
				{L.r[j+1] = L.r[j]; cp++; mv++;}
			cp++; L.r[j+1] = L.r[0]; mv++;
		}//if
	}
}

// (3)折半插入排序
void BinSort(SqList &L, int &cp, int &mv)  {
	int i, j, low, high, mid;
	for(i=2; i<=L.length; i++) {
		L.r[0] = L.r[i]; mv++;
		low = 1; high = i-1;
		while(low <= high) {		// 定位插入点
			mid = (low + high)/2;  cp++;
			if (L.r[0].key < L.r[mid].key) high = mid-1;
			else low = mid+1;
		}
		for(j=i-1; j>=high+1; j--) 
		{	L.r[j+1] = L.r[j]; mv++;}
		L.r[high+1] = L.r[0]; mv++;
	}
}

// (4)希尔排序
void ShellInsert(SqList &L, int dk, int &cp, int &mv)  {
	//对顺序表L作一趟希尔排序
	int i, j;
	for(i=dk+1; i<=L.length; i++) {
		cp++;
		if(L.r[i].key < L.r[i-dk].key) {		//需将L.r[i]插入有序增量子表
			mv++;
            L.r[0] = L.r[i];  			//L.r[i]暂存入L.r[0]
            for(j=i-dk; j>0 && L.r[0].key < L.r[j].key; j-=dk) 
            {   L.r[j+dk] = L.r[j]; 		//寻找插入位置时记录后移
				cp++; mv++;
			}
            cp++; mv++; L.r[j+dk] = L.r[0];    //插入
       }//if
	}//for
} //ShellInsertSort

void ShellSort(SqList &L, int &cp, int &mv)  {
    //按增量序列5,3,1进行希尔排序
    ShellInsert(L, 5, cp, mv);     //一趟增量为5的希尔排序
    ShellInsert(L, 3, cp, mv);     //二趟增量为3的希尔排序
    ShellInsert(L, 1, cp, mv);     //三趟增量为1的希尔排序
} //ShellInsertSort

//(5)冒泡排序
void BubbleSort(SqList &L, int &cp, int &mv)  {
	int i, j, change;
	for(i = 1, change = TRUE; i < L.length && change; i++) {
		change = FALSE;
		for(j = 1;  j < L.length - i + 1;  ++j) 
		{	cp++;
			if (L.r[j].key > L.r[j+1].key) {
				L.r[0] = L.r[j];    L.r[j] = L.r[j+1]; 
				L.r[j+1] = L.r[0];  change = TRUE; mv += 3;
			}//if
		} //for         
	}//for
} // BubbleSort

//(6)快速排序
int Partition(SqList &L, int low, int high, int &cp, int &mv) {
	int i, j;
	KeyType pivotkey;
	L.r[0] = L.r[low]; mv++; pivotkey = L.r[0].key; i = low; j = high;
	while (i < j) {
       while (i < j && L.r[j].key >= pivotkey) 
			{j--; cp++;}
			if(i < j)  cp++;
       L.r[i] = L.r[j]; mv++;
       while (i < j && L.r[i].key <= pivotkey) 
			{i++; cp++;}
			if(i < j)  cp++;
       	L.r[j] = L.r[i]; mv++;
	}
	L.r[i] = L.r[0]; mv++;
    return i;
}//Partition

void QSort(SqList &L, int low, int high, int &cp, int &mv)  {
      //对L.r[low]~L.r[high]的元素进行快速排序
	int pivotloc;
	if (low < high) { 
        pivotloc = Partition(L, low, high, cp, mv);    //一趟划分
        QSort(L, low, pivotloc-1, cp, mv);
        QSort(L, pivotloc+1, high, cp, mv);
    }//if
} //QSort

//(7)简单选择排序
void SelectSort(SqList &L, int &cp, int &mv)  {
	//对顺序表作简单选择排序
	int i, j, k;				// j保存剩余元素中最小值元素的下标
	for(i=1; i<L.length; i++) {
		for(k=i, j=i; k<=L.length; k++) {
			cp++;
			if(L.r[k].key < L.r[j].key)    j = k;
		}
		if (j != i)  {L.r[0] = L.r[i]; L.r[i] = L.r[j]; L.r[j] = L.r[0]; mv += 3;} 
	} //for          
} // SelectSort

//(8)堆排序
void HeapAdjust(SqList &H, int s, int m, int &cp, int &mv) {
	// H.r[s .. m]中除H.r[s].key外均满足堆的定义
	// 调整H.r[s]的关键字,使H.r[s .. m]成为一个大顶堆
	int j;
	H.r[0] = H.r[s];  mv++;
	for(j=2*s; j<=m; j*=2) {      //沿key较大的孩子结点向下筛选
		if(j<m && H.r[j].key < H.r[j+1].key) ++j; //j为key较大的记录的下标        
		if(j<m)  cp++;
		cp++;  if(H.r[0].key >= H.r[j].key)  break; 
		H.r[s] = H.r[j];    //较大的孩子结点值换到父结点位置
		mv++;
		s = j;
	}
	H.r[s] = H.r[0]; mv++;    //H.r[0]应插入的位置在s处
} // HeapAdjust

void HeapSort(SqList &H, int &cp, int &mv) {  //对顺序表H进行堆排序
	int i;
	for(i=H.length/2; i>0; --i)        // 把H建成大顶堆
		HeapAdjust(H, i, H.length, cp, mv);
	for(i=H.length; i>1; --i) {
		H.r[0] = H.r[1]; H.r[1] = H.r[i]; H.r[i] = H.r[0]; mv += 3;
					//堆顶记录和当前未排子序列中最后一个记录相交换
		HeapAdjust(H, 1, i-1, cp, mv); //将H.r[1 .. i - 1] 重新调整为大顶堆 
    }
}// HeapSort 

//(9)二路归并排序
void Merge(SqList &L, SqList &temp, int i, int m, int n, int &cp, int &mv) 
{	// 引入辅助空间temp
	int b = i, j, k;
	for(j = m+1, k = 1; i <= m && j <= n; ++k) {
		if (L.r[i].key < L.r[j].key) temp.r[k] = L.r[i++];
		else temp.r[k] = L.r[j++];
		cp++; mv++;
	}
	for (; i <= m; ) {temp.r[k++] = L.r[i++]; mv++;}
	for (; j <= n; ) {temp.r[k++] = L.r[j++]; mv++;}
	for(i = b, k = 1; i <= n; )  {L.r[i++] = temp.r[k++]; mv++;}
} // Merge

void MergeSort(SqList &L, SqList &temp, int s, int t, int &cp, int &mv)  {
	//归并排序
	int m;
    if (s < t) {
         m = (s + t)/2;
         MergeSort(L, temp, s, m, cp, mv);
         MergeSort(L, temp, m+1, t, cp, mv);
         Merge(L, temp, s, m, t, cp, mv);   //合并L.r[s]~L.r[m]与L.r[m+1]~L.r[t]
    }//if
} // MergeSort

//(10)输出排序表
void OutputList(SqList L)  {
	int i;
	for(i=1; i<=L.length; i++)
		printf("%3d", L.r[i].key);
	printf("\n");
}

int main() {
	SqList LL, L;		//LL为待排序表,L为排序表
	SqList temp;		//二路归并算法中所使用的临时顺序表
	int cp, mv;		//cp记录元素关键字比较次数,mv记录元素移动次数
	
	printf("(1)创建随机数排序表......\n");
	CreatList(LL);		//待排序序列保存在LL表中
	printf("  排序表输出:");
	OutputList(LL);
	getchar();

	printf("(2)直接插入排序......\n");
	L = LL; cp = mv = 0;
	InsertSort(L, cp, mv);
	printf("  排序结果:");
	OutputList(L);
	printf("  排序效率:比较次数%d,移动次数%d。\n", cp, mv);
	getchar();

	printf("(3)折半插入排序......\n");
	L = LL; cp = mv = 0;
	BinSort(L, cp, mv);
	printf("  排序结果:");
	OutputList(L);
	printf("  排序效率:比较次数%d,移动次数%d。\n", cp, mv);
	getchar();

	printf("(4)希尔排序......\n");
	L = LL; cp = mv = 0;
	ShellSort(L, cp, mv);
	printf("  排序结果:");
	OutputList(L);
	printf("  排序效率:比较次数%d,移动次数%d。\n", cp, mv);
	getchar();

	printf("(5)冒泡排序......\n");
	L = LL; cp = mv = 0;
	BubbleSort(L, cp, mv);
	printf("  排序结果:");
	OutputList(L);
	printf("  排序效率:比较次数%d,移动次数%d。\n", cp, mv);
	getchar();

	printf("(6)快速排序......\n");
	L = LL; cp = mv = 0;
	QSort(L, 1, L.length, cp, mv);
	printf("  排序结果:");
	OutputList(L);
	printf("  排序效率:比较次数%d,移动次数%d。\n", cp, mv);
	getchar();

	printf("(7)简单选择排序......\n");
	L = LL; cp = mv = 0;
	SelectSort(L, cp, mv);
	printf("  排序结果:");
	OutputList(L);
	printf("  排序效率:比较次数%d,移动次数%d。\n", cp, mv);
	getchar();

	printf("(8)堆排序......\n");
	L = LL; cp = mv = 0;
	HeapSort(L, cp, mv);
	printf("  排序结果:");
	OutputList(L);
	printf("  排序效率:比较次数%d,移动次数%d。\n", cp, mv);
	getchar();

	printf("(9)二路归并排序......\n");
	L = LL; cp = mv = 0;
	MergeSort(L, temp, 1, L.length, cp, mv);
	printf("  排序结果:");
	OutputList(L);
	printf("  排序效率:比较次数%d,移动次数%d。\n", cp, mv);
	
	return 0;
}

六,操作步骤

1,双击Visual Studio程序快捷图标,启动程序。
在这里插入图片描述

2,之前创建过项目的话,直接打开即可,这里选择【创建新项目】。
在这里插入图片描述

3,单击选择【空项目】——单击【下一步】按钮。
在这里插入图片描述

4,编辑好项目的名称和存放路径,然后单击【创建】按钮。
在这里插入图片描述

5,创建C++程序文件,右击【源文件】——选择【添加】——【新建项】。
在这里插入图片描述
6,输入项目名称10-1.cpp,单击【添加】按钮。
在这里插入图片描述

7,编写代码,单击运行按钮,运行程序。
在这里插入图片描述

七,运行结果

1,实验要求的测试结果。
在这里插入图片描述

2,编写代码测试测试的结果。
在这里插入图片描述

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

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

相关文章

wps编辑技巧

1、编辑模式 2、图片提取方法&#xff1a;右键保存图片 可以直接右键保存下来看看是否是原始图&#xff0c;如果歪着的图&#xff0c;可能保存下来是正的&#xff0c;直接保存试下 3、加批注

开放世界RPG:无缝地图与动态任务的拓扑学架构

目录 开放世界RPG:无缝地图与动态任务的拓扑学架构引言第一章 地图分块系统1.1 动态加载算法1.2 内存管理模型第二章 任务拓扑网络2.1 任务依赖图2.2 动态可达性分析第三章 NPC行为系统3.1 行为森林架构3.2 日程规划算法第四章 动态事件系统4.1 事件传播模型4.2 玩家影响指标第…

【图像处理入门】1. 数字图像的本质:从像素到色彩模型

作为图像处理的开篇&#xff0c;本文将带你拆解数字图像的底层逻辑&#xff1a;从模拟图像到数字信号的神奇转换&#xff0c;到像素世界的微观构成&#xff0c;再到彩色图像的编码奥秘。通过 Python 代码实战&#xff0c;你将亲手触摸图像的 “基因”—— 像素值&#xff0c;并…

(已解决:基于WSL2技术)Windows11家庭中文版(win11家庭版)如何配置和使用Docker Desktop

目录 问题现象&#xff1a; 问题分析&#xff1a; 拓展&#xff1a; 解决方法&#xff1a; 1、使用WSL2技术&#xff08;亲测有效&#xff09; 注意&#xff1a; 2、开启Hyper-V功能&#xff08;未经亲测&#xff0c;待研究&#xff09; 问题现象&#xff1a; 今天想在本…

Ubuntu20.04部署KVM

文章目录 一. 环境准备关闭防火墙&#xff08;UFW&#xff09;禁用 SELinux更换镜像源检查 CPU 虚拟化支持 二. 安装KVM安装 KVM 及相关组件启动 libvirtd 服务验证安装创建虚拟机 一. 环境准备 4C8G&#xff0c;50G硬盘——VMware Workstation需要给虚拟机开启虚拟化引擎 roo…

OpenCV CUDA 模块图像过滤------创建一个高斯滤波器函数createGaussianFilter()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 cv::cuda::createGaussianFilter 是 OpenCV CUDA 模块中的一个工厂函数&#xff0c;用于创建一个高斯滤波器。这个滤波器可以用来平滑图像&#…

可视化图解算法43:数组中的逆序对

1. 题目 ​牛客网 面试笔试TOP101 描述 在数组中的两个数字&#xff0c;如果前面一个数字大于后面的数字&#xff0c;则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P mod 1000000007 数据范围&…

【Python】使用Python实现调用API获取图片存储到本地

使用Python实现调用API获取图片存储到本地 目录 使用Python实现调用API获取图片存储到本地1、项目概述2、核心功能3、环境准备4、代码实现5、结果查看 1、项目概述 开发一个自动化工具&#xff0c;用于从JSON数据源中提取图像ID&#xff0c;通过调用指定API获取未经压缩的原始…

腾讯2025年校招笔试真题手撕(一)

一、题目 有n 把钥匙&#xff0c;m 个锁&#xff0c;每把锁只能由一把特定的钥匙打开&#xff0c;其他钥匙都无法打开。一把钥匙可能可以打开多把锁&#xff0c;钥匙也可以重复使用。 对于任意一把锁来说&#xff0c;打开它的钥匙是哪一把是等概率的。但你无法事先知道是哪一把…

Vue3 与 Vue2 区别

一、Vue3 与 Vue2 区别 对于生命周期来说&#xff0c;整体上变化不大&#xff0c;只是大部分生命周期钩子名称上 “on”&#xff0c;功能上是类似的。不过有一点需要注意&#xff0c;组合式API的Vue3 中使用生命周期钩子时需要先引入&#xff0c;而 Vue2 在选项API中可以直接…

嵌入式学习笔记 - STM32 U(S)ART 模块HAL 库函数总结

一 串口发送方式&#xff1a; ①轮训方式发送&#xff0c;也就是主动发送&#xff0c;这个容易理解&#xff0c;使用如下函数&#xff1a; HAL_UART_Transmit(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size, uint32_t Timeout); ②中断方式发送&#xff…

【VLNs篇】04:SayNav-为新环境中的动态规划到导航进行大型语言模型的基础构建

栏目内容论文标题SayNav: 为新环境中的动态规划到导航进行大型语言模型的基础构建 (SayNav: Grounding Large Language Models for Dynamic Planning to Navigation in New Environments)研究问题自主代理在未知环境中执行复杂导航任务&#xff08;如MultiON&#xff09;时&…

oracle使用SPM控制执行计划

一 SPM介绍 Oracle在11G中推出了SPM&#xff08;SQL Plan management&#xff09;,SPM是一种主动的稳定执行计划的手段&#xff0c;能够保证只有被验证过的执行计划才会被启用&#xff0c;当由于种种原因&#xff08;比如统计信息的变更&#xff09;而导致目标SQL产生了新的执…

Openwrt下使用ffmpeg配合自建RTSP服务器实现推流

目前在Openwrt下时mjpg_streamer实现UVC摄像头转网络摄像头的方案很多&#xff0c;这种方案视频服在路由模组中&#xff0c;在局域网中使用很方便。但是对于需要远程监控管理的情况&#xff0c;mjpg_streamer不适应&#xff0c;因为不在局域网中的播放器无法访问到路由模组中的…

wifi 如果检查失败,UI 就会出现延迟或缺失打勾的现象。

问题&#xff1a;connectedSsid 的初始化依赖 onCreate 中的状态检查&#xff0c;如果检查失败&#xff0c;UI 就会出现延迟或缺失打勾的现象。 WIFI界面上上的一个标识代表成功连接。重启后出现偶尔不打勾的情况。 原始代码&#xff1a; // if (connectedSsid !…

点云(point cloud):自动驾驶的“三维扫描图“

点云&#xff08;Point Cloud&#xff09;&#xff1a;就是用很多“点”来表示一个物体或场景的三维形状和结构。&#xff08;用点描绘的3D画&#xff0c;好比素描&#xff0c;但不是用线条勾勒&#xff0c;而是“点点点点”拼出物体形状&#xff09; 观察这幅图像&#xff0c;…

Oracle RAC节点时间差异同步测试

前言&#xff1a; Oracle Real Application Clusters (RAC) 集群依赖于各节点间的心跳检测与缓存融合等机制&#xff0c;这些机制对节点间的时钟同步性有极高的要求。如果集群内不同节点之间存在显著的时间偏差&#xff0c;可能会导致整个集群运行异常。在较早版本的RAC中&…

贪心算法之跳跃游戏问题

问题背景 本文背景是leetcode的一道经典题目&#xff1a;跳跃游戏&#xff0c;描述如下&#xff1a; 给定一个非负整数数组 nums&#xff0c;初始位于数组的第一个位置&#xff08;下标0&#xff09;。数组中的每个元素表示在该位置可以跳跃的最大长度。判断是否能够到达最后…

Unity 如何使用Timeline预览、播放特效

在使用unity制作和拟合动画时&#xff0c;我们常用到Timeline&#xff0c;前后拖动滑轨&#xff0c;预览动画正放倒放非常方便。如果我们想对特效也进行这个操作&#xff0c;可以使用下文的步骤。 至此&#xff0c;恭喜你又解锁了一个新的技巧。如果我的分享对你有帮助&#xf…

MySQL篇-其他面试题

MySQL事务 问题&#xff1a;事务是什么&#xff1f;ACID问题 事务是一组操作的集合&#xff0c;它是一个不可分割的工作单位&#xff0c;事务会把所有的操作作为一个整体一起向系统提交或撤销操作请求&#xff0c;即这些操作要么同时成功&#xff0c;要么同时失败。 1、事务…