【排序】快速排序(C语言实现)

news2024/11/20 14:35:00

文章目录

  • 前言
  • 1. Hoare思想
  • 2. 挖坑法
  • 3. 前后指针法
  • 4. 三路划分
  • 5. 快速排序的一些小优化
    • 5.1 三数取中
      • 常规的三数取中
      • 伪随机的三数取中
    • 5.2 小区间优化
  • 6. 非递归版本的快排
  • 7. 快速排序的特性总结




前言


快速排序是Hoare于1962年提出的一种二叉树结构的交换排序方法,其基本思想为:任取待排序元素序列中的某元素作为基准值,按照该排序码将待排序集合分割成两子序列,左子序列中所有元素均小于基准值,右子序列中所有元素均大于基准值,然后最左右子序列重复该过程,直到所有元素都排列在相应位置上为止。

本章会重点讲解快速排序的四种思想:

  1. Hoare思想
  2. 挖坑法
  3. 前后指针法
  4. 三路划分

以及快速排序的一些小优化,和递归与非递归的实现方式。

阅读本章建议有一点二叉树的基础,如果对二叉树不太了解的可以看看:《初阶二叉树》这篇文章


1. Hoare思想


我们先看一下Hoare的思想是怎么样实现的:
请添加图片描述
这里来解释一下这个思想的意思:

  1. 首先我们将数组起始位置的数据定义成key
  2. 我们从右边开始往前找一个比key的数
  3. 找到比key小的数,我们在从左边开始找一个比key的数
  4. 做完上面两个步骤以后,当R与L相遇时,我们再将key放到R和L相遇的位置上,此刻key已经排到了它所应该在的位置(就是排好序以后的位置),我们介绍的这几种方法本质都是将key放到它所应该在的位置

注意⚠️:
在实现这个代码之前,我们要注意几个点:

  1. 如果是排升序的话,一定是要先从右边开始找,再从左边找,这样就能确保找到的数,一定是小于key的,具体原因如下:
    在这里插入图片描述
  2. 我们要注意如果数组中所有数都比key大,那么我们往右边找比key小的数的时候,控制不当就会导致越界;同理,如果数组中所有的数都比key要小,那么我们往左边找比key大的数的时候,控制不当也会导致越界。
  3. 我们在交换R和L的值的时候,可能会遇到R和L遇到等于key的数,如果不做处理的话,这样R和L就会一直交换,导致死循环。

说了那么多,我们一起来看看Hoare版的快排用代码是怎么实现的:

int PartSort_Hoare(int* a, int begin, int end)
{
	int left = begin;
	int right = end - 1;
	// 在这块将key定义成下标,
	// 因为我们在后面的过程中会涉及将key与我们锁定的位置的数交换位置,
	// 如果写成int key = a[left]就不方便后面的交换
	int key_i = left;

	while (left < right)
	{
		// 先走右边,再走左边
		while (left < right && a[right] >= a[key_i]) // 防止越界 && 找小
		{
			--right;
		}

		while (left < right && a[left] <= a[key_i]) // 防止越界 && 找大 
		{
			++left;
		}
		// 找到大的数和小的数,将它们交换位置
		Swap(&a[left], &a[right]);
	}
	// 出循环以后此刻left=right
	// 将在left位置和key_i位置的数交换一下位置
	Swap(&a[left], &a[key_i]);

	return left;
}

void Quick_Sort(int* a, int begin, int end)
{
	if (begin >= end)
		return;

	int key = PartSort_Hoare(a, begin, end); 
	// 区间分为: [begin, key) key[key + 1, end), 这里要注意, 我们给的区间是左闭右开的
	Quick_Sort(a, begin, key);
	Quick_Sort(a, key + 1, end);

}

这里有一个细节不知道大家有没有发现
在这里插入图片描述
我在处理这两个地方的时候是先判断left是否小于right,这样处理的好处是有效的防止了我们对数组的越界访问,如果是后判断left是否小于right,那么在进行a[right] >= a[key_i]这步操作的时候,我们可能会进行越界访问数组的操作。


2. 挖坑法


我们先看一下挖坑法是怎么样实现的:
请添加图片描述

这里来解释一下这个思想的意思:

  1. 先将第一个数据存放在一个临时变量key中,然后形成一个坑位
  2. 右边开始找一个key小的数,将这个数放进坑位中,然后又将这个位置设置成坑位
  3. 左边开始找一个key大的数,将这个数放进坑位中,然后又将这个位置设置成坑位
  4. 当L和R相遇时,此时坑位一定是在L和R的交点处,我们将前面保存的临时变量key放入坑位中,此刻key已经排到了它所应该在的位置(就是排好序以后的位置)

我们来看一下挖坑法实现快排用代码是怎么实现的:

int PartSort_Hole(int* a, int begin, int end)
{
	int left = begin;
	int right = end - 1;
	// 这里不用像Hoare法那样设置成下标,
	// 因为我们在最后是直接将数据放入坑位中
	int key = a[begin];
	int hole = left; // 设置坑位
	while (left < right)
	{
		// 先从右边走
		while (left < right && a[right] >= key)  //  防止越界 && 找小
		{
			--right;
		}
		//找到小于key的数了,将该数放在hole中,再将该位置设置为hole
		a[hole] = a[right];
		hole = right;

		while (left < right && a[left] <= key)  // 防止越界 && 找大
		{
			++left;
		}
		//找到小于key的数了,将该数放在hole中,再将该位置设置为hole
		a[hole] = a[left];
		hole = left;
	}
	a[hole] = key;

	return hole;
}

void Quick_Sort(int* a, int begin, int end)
{
	if (begin >= end)
		return;

	int key = PartSort_Hole(a, begin, end);
	// 区间分为: [begin, key) key[key + 1, end), 这里要注意, 我们给的区间是左闭右开的
	Quick_Sort(a, begin, key);
	Quick_Sort(a, key + 1, end);
}


3. 前后指针法


我们先看一下前后指正法是怎么样实现的:
请添加图片描述
这里来解释一下这个思想的意思:

  1. 我们先定义两个指针prevcurkeyprevkey指向数组的起始位置,cur指向prev的下一个位置
  2. 我们先移动cur,找到比key小的数,就将cur位置的数据和 prev+1位置的数据交换位置,但这里出于考虑省略一些交换数据的消耗,我们可以判断prev+1位置的数据是否等于cur位置的数据,如过a[cur] < cur && a[prev+1] != a[cur],就将两个位置的数据进行交换
  3. 直到cur指针越界,我们这个过程就结束了,然后再将key的值放到prev的位置,此刻key已经排到了它所应该在的位置(就是排好序以后的位置)

我们来看一下前后指针实现快排用代码是怎么实现的:

int PartSort_PC_Point(int* a, int begin, int end)
{
	// 创建两个变量来指向数组
	int prev = begin;
	int cur = prev + 1;
	// 这里将key设置成
	int key_i = begin;

	while (cur < end)
	{
		if (a[cur] < a[key_i] && ++prev != cur) // 找比key小的值 && 防止与自身交换
		{
			Swap(&a[cur], &a[prev]);
		}
		cur++;
	}
	// 此时cur已经比right大了,将prev与key_i位置的数换位置
	Swap(&a[key_i], &a[prev]);
	return prev;
}

void Quick_Sort(int* a, int begin, int end)
{
	if (begin >= end)
		return;

	int key = PartSort_PC_Point(a, begin, end);
	// 区间分为: [begin, key) key[key + 1, end), 这里要注意, 我们给的区间是左闭右开的
	Quick_Sort(a, begin, key);
	Quick_Sort(a, key + 1, end);
}


4. 三路划分


三路划分这个思想用来处理大量重复数据的时候,效率特别高。

我们先看一下三路划分是怎样实现的:
请添加图片描述
这里来解释一下这个思想的意思:

  1. 我们先定义一个key等于数组起始位置的数据 ,之后在数组起始位置定义一个L指针,在L的下一个位置定义一个cur指针,最后在末尾位置定义一个R指针
  2. 我们从cur位置开始,找一个比key小的数,找到以后,交换curL的位置的值,并且++cur++L
  3. 如果cur等于key,++cur
  4. 如果cur遇到一个比key大的数,交换交换curR的位置的值,并且--R,这里要注意不能动cur的值,因为从R位置交换过来的值,我们没办法判断它与key的大小关系,所以保持cur的位置不变,再继续将cur位置的值与key做比较
  5. cur > R的时候,这个过程就结束了

在实现这个代码的过程中,我们需要返回的是一个范围:[begin,L)[R + 1,end)

为什么是这样呢?
在这里插入图片描述
因为我们在进行一次三路划分过后,已经将key与key相等的数排好位置了,剩下的就只剩[begin,L)[R + 1,end)需要排序(这里我是设置成左闭右开区间,大家写的时候,也可以自己设置成左闭右闭区间),因为实现三路划分需要得到一个范围,所以写成函数不太好控制,所以我就直接将这个过程写在Quick_Sort函数中了

我们来看一下三路划分法实现快排用代码是怎么实现的:

void Quick_Sort(int* a, int begin, int end)
{
	if (begin >= end)
		return;
	
	int left = begin;
	int right = end - 1;
	int cur = left + 1;
	int key = a[left];
	while (cur <= right) // cur > right 循环才结束
	{
		if (a[cur] < key) // cur位置的值小于key
		{
			// 交换cur和L的位置的值,并且++cur ,++left
			Swap(&a[cur], &a[left]);
			++cur;
			++left;
		}
		else if (a[cur] > key) // cur位置的值大于key
		{
			// 交换cur和L的位置的值,并且--right
			Swap(&a[cur], &a[right]);
			--right;
		}
		else // cur位置的值等于key
		{
			++cur;
		}
	}

	// [begin, left) 和 [right + 1, end)
	Quick_Sort(a, begin, left);
	Quick_Sort(a, right + 1, end);
}


5. 快速排序的一些小优化


我们在上面实现排序的时候,面对一些情况我们写的快排也还是有些吃力,所以我们也还需要对一些情况做一些处理

这里有一点,可以注意一下:
就是我在上面写4种思想实现快排的时候,前三种思想我是将递归过程单独写成子函数来调用的,这样做的目的是使我写这篇博客时的可读性提高。但如果是我们自己写的时候,也可以不用单独写成一个子函数来调用,可以直接将这些思想的过程写进函数体里面。毕竟函数调用时,还是会有一点消耗的,当然这些消耗可以忽略不计

5.1 三数取中

三数取中有两种取法(当然不止两种),这里我要介绍的是两种思想:

常规的三数取中

这个思想主要是:我们通过比较数组起始位置和中间位置还有末尾位置的数据,第二大的数作为key

具体我们写代码来看一下:

int GetMidi(int* a, int begin, int end) // 三数取中
{
	int left = begin;
	int right = end - 1;
	int mid = (left + right) / 2;
	if (a[left] < a[mid])                // a[left] < a[mid]
	{
		if (a[mid] < a[right])           // a[left] < a[mid] < a[right]
			return mid;
		else if (a[left] < a[right])     // a[mid] >= a[right] > a[left]
			return right;
		else                             // a[mid] > a[left] >= a[right]
			return left;
	}
	else                                 // a[left] >= a[mid]
	{
		if (a[left] < a[right])          // a[mid] <= a[left] < a[right]
			return left;
		else if (a[right] > a[mid])      // a[left] >= a[right] > a[mid]
			return right;
		else                             // a[left] > a[mid] >= a[right]
			return mid;
	}
}

伪随机的三数取中

这个思想主要是:我们通过比较数组起始位置和数组中一个随机的位置,和他们中间位置的数据,第二大的数作为key

具体实现过程如下:

int GetMidi_random(int* a, int begin, int end) 
{
	int left = begin;
	int right = begin + rand() % (end - begin); // 后面加的数是整个数组的范围
	int mid = (left + right) / 2;
	if (a[left] < a[mid])                // a[left] < a[mid]
	{
		if (a[mid] < a[right])           // a[left] < a[mid] < a[right]
			return mid;
		else if (a[left] < a[right])     // a[mid] >= a[right] > a[left]
			return right;
		else                             // a[mid] > a[left] >= a[right]
			return left;
	}
	else                                 // a[left] >= a[mid]
	{
		if (a[left] < a[right])          // a[mid] <= a[left] < a[right]
			return left;
		else if (a[right] > a[mid])      // a[left] >= a[right] > a[mid]
			return right;
		else                             // a[left] > a[mid] >= a[right]
			return mid;
	}
}

int main()
{
	srand((unsigned)time(NULL)); // 生成随机数种子

	return 0;
}

我们在用三数取中时,获取到的是想要的数的位置,然后将这个位置的数和数组起始位置的数交换一下,这样就方便我们定义key了。具体实现方式,我写在了本小节的最后。

5.2 小区间优化

在这里插入图片描述

我们在学过二叉树以后,应该知道,完全二叉树,倒数第二层和最后一层加起来占了整个节点75%的节点,而我们在处理大量数据使用快排实现递归时当只有10个数据时,还会递归多次:
在这里插入图片描述
而在处理这些大量数据,我们递归下来时,无疑会产生大量范围为10及10以下的多组数据,如果我们此时继续递归,无疑会产生很多组小范围的数据。所以范围小于等于10的时候,就没必要使用快排继续递归了,这里可以考虑使用直接插入排序来排每组范围小于等于10的数组。这样就大大降低了递归时开辟栈帧的消耗了。在使用插入排序时,我们必须要弄清楚所需排序的范围:
在这里插入图片描述

下面我以三路划分的思想写一个我上述优化后的排序,里面有用到直接插入排序,这个不是本章的重点,不了解的可以看看这篇博客:《简单排序》:

int GetMidi_random(int* a, int begin, int end) 
{
	int left = begin;
	int right = begin + rand() % (end - begin); // 后面加的数是整个数组的范围
	int mid = (left + right) / 2;
	if (a[left] < a[mid])                // a[left] < a[mid]
	{
		if (a[mid] < a[right])           // a[left] < a[mid] < a[right]
			return mid;
		else if (a[left] < a[right])     // a[mid] >= a[right] > a[left]
			return right;
		else                             // a[mid] > a[left] >= a[right]
			return left;
	}
	else                                 // a[left] >= a[mid]
	{
		if (a[left] < a[right])          // a[mid] <= a[left] < a[right]
			return left;
		else if (a[right] > a[mid])      // a[left] >= a[right] > a[mid]
			return right;
		else                             // a[left] > a[mid] >= a[right]
			return mid;
	}
}

void Quick_Sort(int* a, int begin, int end)
{
	if (begin >= end)
		return;

	if (end - begin > 10)  // 小区间优化
	{
		int left = begin;
		int right = end - 1;
		int cur = left + 1;
		int mid = 0;
		if (left < end)
		{
			mid = GetMidi(a, left, end); //三数取中,获取我们要找的数
			Swap(&a[mid], &a[left]); // 将三数取中得到的数换到第一个位置
		}
		int key = a[left];

		while (cur <= right)
		{
			if (a[cur] < key)
			{
				Swap(&a[cur], &a[left]);
				++left;
				++cur;
			}
			else if (a[cur] > key)
			{
				Swap(&a[cur], &a[right]);
				--right;
			}
			else
				++cur;
		}
		// 分区间进行递归
		Quick_Sort(a, begin, left);
		Quick_Sort(a, right + 1, end);
	}
	else
	{
		// 使用插入排序时,要注意使用的范围
		InsertSort(a + begin, end - begin);
	}
}



6. 非递归版本的快排


在我们使用快排时,其实用递归也递归不了多少层。所以在平时我们要使用快排时,使用递归版的完全够用了。但由于现在还在学习阶段,所以掌握一下非递归版的快排还是有必要的。

我们实现非递归版本的快排时,用到的思想是我上面介绍的几种思想,只不过接下来讲的不是用递归去完成这个过程,这里我们要使用一个工具——,能够看到这里的我相信大家都对栈有一定的了解了,所以我在下面代码中,就将直接使用我写的栈了。不太了解栈的也可以看看这篇文章:《栈和队列》

void QuickSortNonR(int* a,int begin, int end)
{
	int left = begin;
	int right = end;
	Stack stack; // 创建一个栈的数据结构
	StackInit(&stack); // 将这个栈初始化一下
	StackPush(&stack, left); // 插入最开始的数
	StackPush(&stack, right); // 插入最后一位数的下一位,因为我们上面实现的三种方法都是左闭右开的
	while (!StackEmpty(&stack))
	{
		right = StackTop(&stack); // 我们是先插入最右边的数,所以我们应该先拿出最右边的数
		StackPop(&stack); // 栈顶元素删除
		left = StackTop(&stack); // 在上面删除right时,栈顶元素就是left了
		StackPop(&stack); // 栈顶元素删除
		int key = PartSort_Hoare(a, left, right); // 将这段区间进行排序
		// [left,key) key [key+1,right)
		
		if (right > key + 1) // 如果这个区间存在,就将这个区间表示的范围入栈(这里要注意入栈顺序和出栈顺序)
		{
			StackPush(&stack, key + 1);
			StackPush(&stack, right);
		}
 		if (left < key) // 如果这个区间存在,就将这个区间表示的范围入栈(这里要注意入栈顺序和出栈顺序)
		{
			StackPush(&stack, left);
			StackPush(&stack, key);
		}
	}
	// 销毁栈
	StackDestroy(&stack);
}

有人可能会问我们递归时用到的栈帧和我们自己做的栈,有什么区别呢?

因为我自己做的栈是在堆上开辟的空间,而如果使用递归版本的栈帧是在栈上开辟的空间。32位机器下,栈上的空间只有8MB左右,而堆上的空间有4G左右。所以这里选择在堆上开辟空间,可以很好的节约空间,也能减少递归时产生的消耗。


7. 快速排序的特性总结


  1. 快速排序整体的综合性能和使用场景都是比较好的,所以才敢叫快速排序

  2. 时间复杂度:O(N*logN)
    在这里插入图片描述

  3. 空间复杂度:O(logN)

    • 快速排序的空间复杂度取决于递归深度和每个递归函数栈空间的大小。
    • 在最坏情况下,快速排序的空间复杂度为O(n);在平均情况下,快速排序的空间复杂度为O(logn)1。
    • 快速排序是一种原地排序算法,它的工作原理是选择一个基准值,将待排序的数组划分为两个子数组,一个小于等于基准值,一个大于基准值,然后对两个子数组递归进行快速排序,直到整个数组有序。
  4. 稳定性:不稳定

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

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

相关文章

设计模式之组合模式【结构型模式】

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档> 学习的最大理由是想摆脱平庸&#xff0c;早一天就多一份人生的精彩&#xff1b;迟一天就多一天平庸的困扰。各位小伙伴&#xff0c;如果您&#xff1a; 想系统/深入学习某…

Python expandtabs()与endswith()方法

Python expandtabs()方法 描述 Python expandtabs() 方法把字符串中的 tab 符号(\t)转为空格&#xff0c;默认的空格数 tabsize 是 8。 语法 expandtabs()方法语法&#xff1a; string.expandtabs(tabsize8) 参数 tabsize -- 指定转换字符串中的 tab 符号(\t)转为空格的字…

边缘计算AI智能分析网关V4算力分析及应用场景

一、硬件介绍 智能分析网关V4是TSINGSEE青犀视频推出的一款高性能、低功耗的软硬一体AI边缘计算硬件设备&#xff0c;硬件采用BM1684芯片&#xff0c;集成高性能8核ARM A53&#xff0c;主频高达2.3GHz。硬件内置近40种AI算法模型&#xff0c;支持对接入的视频图像进行人、车、…

msvcr120.dll是什么?msvcr120.dll丢失要怎么去修复?

随着计算机技术的不断发展&#xff0c;我们在使用软件或游戏时经常会遇到各种错误提示&#xff0c;其中找不到msvcr120.dll就是一种常见的错误。那么&#xff0c;msvcr120.dll是什么&#xff1f;它的作用是什么&#xff1f;如何修复msvcr120.dll丢失的问题&#xff1f;本文将为…

20个很棒的SEO博客和网站

搜索引擎优化 &#xff08;SEO&#xff09; 标准在不断变化。与社交媒体、电子邮件营销和人工智能 &#xff08;AI&#xff09; 等新兴技术一样&#xff0c;搜索引擎正在改进它们每天向用户提供结果的方式。 为此&#xff0c;他们专注于本地化、页面权限、点击率&#xff0c;甚…

数据结构与算法之美学习笔记:46 | 概率统计:如何利用朴素贝叶斯算法过滤垃圾短信?

目录 前言算法解析总结引申 前言 本节课程思维导图&#xff1a; 上一节我们讲到&#xff0c;如何用位图、布隆过滤器&#xff0c;来过滤重复的数据。今天&#xff0c;我们再讲一个跟过滤相关的问题&#xff0c;如何过滤垃圾短信&#xff1f; 垃圾短信和骚扰电话&#xff0c;我…

【MYSQL】MYSQL 的学习教程(十二)之 MySQL 啥时候用记录锁,啥时候用间隙锁

在「读未提交」和「读已提交」隔离级别下&#xff0c;都只会使用记录锁&#xff1b;而对于「可重复读」隔离级别来说&#xff0c;会使用记录锁、间隙锁和 Next-Key 锁 那么 MySQL 啥时候会用记录锁&#xff0c;啥时候会用间隙锁&#xff0c;啥时候又会用 Next-Key 锁呢&#xf…

美客多本土店与跨境店有何区别?本土店如何入驻运营?

美客多被誉为“拉美亚马逊”&#xff0c;作为拉美地区最大的跨境电商平台&#xff0c;吸引了不少跨境电商卖家入驻。但在入驻过程中也会遇到一个问题&#xff0c;本土店与跨境店分别是什么&#xff1f;有何区别&#xff1f;应该选择本土店还是跨境店入驻呢&#xff1f;下面为你…

使用YOLOv5训练自己的数据集 --- 老鼠识别

方式一&#xff1a;YOLOv5开源地址&#xff1a;https://github.com/ultralytics/yolov5/blob/master/README.zh-CN.md 方式二&#xff1a;YOLOv5源码&#xff1a;https://pan.baidu.com/s/12khk-Wkc5_J5ho4oZ7_FhA?pwdxtru 安装环境依赖包&#xff1a; 项目目录地址栏中输入…

MobaXterm游戏讲解

前言 没想到吧&#xff0c;这里还有游戏&#xff0c;以下是玩法 玩法 注 点击Type可以自由更改地图大小 1.Netwalk 这个游戏是用鼠标点击每一个格子&#xff0c;进行旋转方向&#xff0c;使得所有方块连接接来&#xff0c;全部变成亮蓝色 2.Mines 这个就是扫雷了&#xff…

算法训练营Day42(背包问题)

基础 非竞赛只需要搞懂0-1背包和完全背包 0-1背包基础 0-1背包是完全背包和多重背包的基础 n个物品&#xff0c;每个物品一个&#xff0c;每个物品有自己的重量和价值&#xff0c;&#xff0c;一个背包能装m物品&#xff0c;问最多装多少物品。 暴力解法&#xff0c;n个物品…

循环中的continue和break | python

1 continue continue关键字用于:中断本次循环&#xff0c;直接进入下一次循环 continue可以用于:for循环和while循环&#xff0c;效果一致 上侧代码: 在循环内&#xff0c;遇到continue就结束当次循环&#xff0c;进行下一次所以&#xff0c;语句2是不会执行的。 1.1 应用场…

网点分散难管理?组网是物流企业的正解!

物流企业服务网点分散、难以管理是企业面临的一个问题&#xff0c;而组网是解决这一问题的正解。通过建立统一的网络&#xff0c;物流企业可以实现更好的资源管理和信息流动&#xff0c;从而提高运营效率和服务水平&#xff0c;实现企业的可持续发展。 随着物流业务的不断拓展…

pycharm导入etree报Cannot find reference ‘etree‘ in ‘__init__.py‘ more... (Ctrl+F1)

问题 发现 from lxml import etree的时候&#xff0c;etree报错了。提示Cannot find reference etree in __init__.py more... (CtrlF1)。 解决办法 后面发现是pycharm自己的BUG&#xff0c;所以写了新的写法

黑马苍穹外卖学习Day2

文章目录 员工管理模块实现新增员工需求设计分析代码开发功能测试代码完善 员工分页查询需求分析与设计代码开发功能测试代码完善 启用禁用员工账号需求分析和设计代码开发功能测试 编辑员工需求分析代码开发 导入分类模块功能代码需求分析设计 员工管理模块实现 新增员工 需…

小程序基础学习(组件化)

&#xff08;一&#xff09;创建 找到components文件夹下面创建新的文件夹 然后再文件夹内创建component格式的文件 创建后这样 我创建的是my-info的文件夹以及my-info的components文件&#xff0c;跟着普通的页面一样 &#xff08;二&#xff09; 注册组件 找到你需要使用组…

刚开始学习 c++ 要注意哪些方面?

刚开始学习 c 要注意哪些方面&#xff1f; 在开始前我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「c的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区回复“888”之后私信回复“888”&#xff0c;全部无偿共享给大家&#xff01;&#xff01;&…

API获取商品详情电商补单及价格监控调用api

很多电商系统&#xff0c;如返利系统、ERP、OMS软件等&#xff0c;需要通过商品API接口获取商品详情信息&#xff0c;来满足业务场景需要。具体包括&#xff1a;商品的标题、价格、SKU、主图、评价等维度信息 获取key和密钥 返回数据&#xff1a; {"item": {"…

MacOS安装Miniforge、Tensorflow、Jupyter Lab等(2024年最新)

大家好&#xff0c;我是邵奈一&#xff0c;一个不务正业的程序猿、正儿八经的斜杠青年。 1、世人称我为&#xff1a;被代码耽误的诗人、没天赋的书法家、五音不全的歌手、专业跑龙套演员、不合格的运动员… 2、这几年&#xff0c;我整理了很多IT技术相关的教程给大家&#xff0…

查看Linux磁盘空间

(1)、该命令会列出当前系统所有挂载的文件系统以及它们的使用情况&#xff0c;包括总容量、已用空间、可用空间、使用百分比等信息 df -h如果查看某一个文件夹的,可以 df -h folderName (2)、计算指定目录下所有文件和子目录所占用的磁盘空间大小&#xff0c;并以人类可读的格…