数据结构-二叉树结尾+排序

news2024/11/17 13:34:46

一、二叉树结尾

1、如何判断一棵树是完全二叉树。

我们可以使用层序遍历的思路,利用一个队列,去完成层序遍历,但是这里会有些许的不同,我们需要让空也进队列。如果队列里到最后只剩下空那么这棵树就是完全二叉树。具体的实现如下:

借助了,按层序走,非空节点一定是连续的。

int TreeComplete(BTNode* root)
{
	assert(root);
	Queue q;
	QueueInit(&q);
	QueuePush(&q,root);
	while (!QueueEmpty(&q))
	{
		BTNode* front = QueueFront(&q);
		QueuePop(&q);
		if (front == NULL)
			break;
		QueuePush(&q, front->left);
		QueuePush(&q, front->right);
	}

	//判断是不是完全二叉树
	//后面非空,说明非空节点不是连续的,不是完全二叉树
	while (!QueueEmpty(&q))
	{
		BTNode* front = QueueFront(&q);
		QueuePop(&q);
		if (front)
			return false;
	}
    QueueDestory(&q);
	return true;
}

二叉树的销毁

使用后序去销毁

void TreeDestory(BTNode* root)
{
	if (root == NULL)
		return;

	TreeDestory(root->left);
	TreeDestory(root->right);
	free(root);
}

二、排序

1、插入排序。

把一个数据插入到有序的区间,定义一个end变量用来标识区间

void InsertSort(int* a, int n)
{
	for (int i = 1; i < n; i++)
	{
		//单躺排序
		int temp = a[i];
		int end = i - 1; 
		while (end >= 0)
		{
			if (temp < a[end])
			{
				a[end + 1] = a[end];
				end--;
			}
			else
			{
				//为什么要break,这里会有end为-1的位置
				break;
			}
		}
		a[end + 1] = temp;
	}
}

 2、希尔排序

(1)预排序--目标:数组接近有序,分组插入排序,间隔为gap分为一组,对每组数据插入排序,假设gap == 3;

gap为3时的一趟直接插入排序

	int end;
	int gap = 3;
	int temp = a[end+gap];

	while (end >= 0)
	{
		if (temp < a[end])
		{
			a[end + gap] = a[end];
			end -= gap;
		}
		else
		{
			break;
		}	
	}
	a[end + gap] = temp;

gap为3时的红色组数据的排序

void ShellSort(int* a, int n)
{
	int gap = 3;
	for (int i = gap; i < n; i += gap)
	{
		int end = i - gap;
		int temp = a[end + gap];

		while (end >= 0)
		{
			if (temp < a[end])
			{
				a[end + gap] = a[end];
				end -= gap;
			}
			else
			{
				break;
			}
		}
		a[end + gap] = temp;
	}
	
}

三组都排完

void ShellSort(int* a, int n)
{
	int gap = 3;
	for (int j = 0; j < gap; j++)
	{
		for (int i = gap + j; i < n; i += gap)
		{
			int end = i - gap;
			int temp = a[end + gap];

			while (end >= 0)
			{
				if (temp < a[end])
				{
					a[end + gap] = a[end];
					end -= gap;
				}
				else
				{
					break;
				}
			}
			a[end + gap] = temp;
		}
	}
}

把上述代码改成i++可以减少一层循环,就变成了多组并排的方式

gap到底时多少合适呢?

gap越大,跳的越快,越不接近有序

gap越小,跳的越慢,越接近有序 

gap = gap/1

gap = gap/3 + 1

//希尔排序
void ShellSort(int* a, int n)
{
	int gap = n;
	while (gap > 1)
	{
		gap = gap / 2;
		for (int j = 0; j < gap; j++)
		{
			for (int i = gap + j; i < n; i += gap)
			{
				int end = i - gap;
				int temp = a[end + gap];
				while (end >= 0)
				{
					if (temp < a[end])
					{
						a[end + gap] = a[end];
						end -= gap;
					}
					else
					{
						break;
					}
				}
				a[end + gap] = temp;
			}
		}
	}
}

(2)直接插入排序

gap为1的时候为直接插入排序

gap >1的时候为预排序

时间复杂度O(n^1.3)左右的样子

3、选择排序

我们可以找到最大的交换到右边和最小的交换到左边,但是如果left == maxi,一交换mini和left的值就会把maxi里的值交换到mini上。我们需要做一个修正,maxi = mini

void Swap(int* a, int* b)
{
	int temp = *a;
	*a = *b;
	*b = temp;
}
void SelectSort(int* a, int n)
{
	//首先进行选数
	int left = 0;
	int right = n - 1;
	while (left < right)
	{
		int maxi = left, mini = left;
		for (int i = left; i <= right; i++)
		{
			if (a[i] < a[mini])
				mini = i;

			if (a[i] > a[maxi])
				maxi = i;
		}
		//选数完毕交换两个数
		Swap(&a[mini], &a[left]);
		//进行矫正
		if (left == maxi)
			maxi = mini;
		Swap(&a[maxi], &a[right]);

		left++;
		right--;
	}
}

选择排序最坏和最好的时间复杂度为O(n^2)

4、堆排序已经在二叉树堆已经讲过了

5、冒泡排序

void BubbleSort(int* a, int n)
{
	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < n - i; j++)
		{
			if(a[j] > a[j+1])
				Swap(&a[j], &a[j + 1]);
		}
	}
}

优化:

void BubbleSort(int* a, int n)
{
	for (int i = 0; i < n; i++)
	{
		bool exchange = false;
		for (int j = 0; j < n - i; j++)
		{
			if (a[j] > a[j + 1])
			{
				Swap(&a[j], &a[j + 1]);
				//没有改成true证明已经有序了
				exchange = true;
			}
		}
		if (exchange == false)
			break;
	}
}

部分有序时插入排序和冒泡排序就是有差距的。

6、快速排序

选出一个关键值key,把它放到正确的位置(最终排好序要在的位置)单趟排序

左边放比key小的,右边放比key大的

HOARE版本

左边做key,右边先走(相遇后,相遇位置正好是小的),右边找比key小的。左边找比key大的,然后交换

快排是一个递归的思想,分成左右区间,然后再排

         begin  = 0    keyi = end   

        end = 1        keyi + 1 = 2   end = 1    左大于等于右不存在这个区间  (递归的出口)

void QuickSort(int* a, int left,int right)
{
	if (left >= right)
	{
		return;
	}
	int keyi = left;
	int begin = left, end = right;
	while (left < right)
	{
		//相等的话没有必要交换
		//不加前面的条件会越界访问
		//一定先让右先走
		//右边找小
		while (left < right && a[right] >= a[keyi])
			right--;
		//左边找大
		while(left < right && a[left] <= a[keyi])
			left++;
		
		Swap(&a[left], &a[right]);
	}
	Swap(&a[left], &a[keyi]);
	keyi = left;
	//[begin,keyi-1][keyi][keyi+1,end]
	QuickSort(a,begin, keyi - 1);
	QuickSort(a, keyi + 1, end);
}

时间复杂度O(NlogN)

上面有一个错误应该是n-2^i+1

最坏的情况是逆序和顺序的时候。它的时间复杂度就已经变到了O(N^2),可能会栈溢出。

优化

我们可以随机选key也可以使用三数取中法选key

int GetMidNumi(int* a, int left, int right)
{
	int midi = (right + left) / 2;
	if (a[left] < a[midi])
	{
		if (a[midi] < a[right])
		{
			return midi;
		}
		else if (a[left] > a[right])
		{
			return left;
		}
		else
		{
			return right;
		}
	}
	else  //a[left] > a[midi]
	{
		if (a[midi] > a[right])
		{
			return midi;
		}
		else if (a[left] < a[right])
		{
			return left;
		}
		else
		{
			return right;
		}
	}
}
void QuickSort(int* a, int left,int right)
{
	if (left >= right)
	{
		return;
	}
	/*int randi = left + (rand() % (right - left));
	Swap(&a[left], &a[randi]);*/
	//三数取中找到下标
	//int keyi = left;
	int midi = GetMidNumi(a, left, right);
	Swap(&a[left], &a[midi]);
	int keyi = left;
	int begin = left, end = right;
	while (left < right)
	{
		//相等的话没有必要交换
		//不加前面的条件会越界访问
		//一定先让右先走
		//右边找小
		while (left < right && a[right] >= a[keyi])
			right--;
		//左边找大
		while(left < right && a[left] <= a[keyi])
			left++;
		
		Swap(&a[left], &a[right]);
	}
	Swap(&a[left], &a[keyi]);
	keyi = left;
	//[begin,keyi-1][keyi][keyi+1,end]
	QuickSort(a,begin, keyi - 1);
	QuickSort(a, keyi + 1, end);
}

那么为什么相遇的位置一定比key小

左边做key,右边先走,保证相遇位置比key要小

1、R找小,L找大没有找到,L遇到R或者就是key的位置

2、R找小找不到,R直接跟L相遇,要么就是一个比key小的位置,或者直接到keyi

类似的道理右边做key左边先走也是这样的。相遇的位置比key要大

挖坑法


 

void QuickSort2(int* a, int left, int right)
{
	if (left >= right)
	{
		return;
	}
	/*int randi = left + (rand() % (right - left));
	Swap(&a[left], &a[randi]);*/
	//三数取中找到下标
	//int keyi = left;
	int midi = GetMidNumi(a, left, right);
	Swap(&a[left], &a[midi]);


	int begin = left, end = right;
	int key = a[left];
	int hole = left;
	while (left < right)
	{
		//相等的话没有必要交换
		//不加前面的条件会越界访问
		//一定先让右先走
		//右边找小
		while (left < right && a[right] >= key)
			right--;
		//找到以后把值放到left上面
		a[hole] = a[right]; //形成新的坑位
		hole = right;
		//左边找大
		while (left < right && a[left] <= key)
			left++;
		//找到后把值放到right上面
		a[hole] = a[left]; //形成新的坑位
		hole = left;
	}
	a[hole] = key;
	//[begin,keyi-1][keyi][keyi+1,end]
	QuickSort(a, begin, hole - 1);
	QuickSort(a, hole + 1, end);
}

双指针法

1、cur找到比key小的值++prev,cur和prev位置的值交换,++cur

2、cur找到比key大的值,++cur

说明:prev要么紧跟着cur(prev下一个就是cur)

prev跟cur中间间隔着比key大的一段值的区间。

把比key大的值往右翻,比key小的值,翻到左边。

void QuickSort3(int* a, int left, int right)
{
	if (left >= right)
		return;
	int midi = GetMidNumi(a, left, right);
	Swap(&a[left], &a[midi]);
	int keyi = left;
	int cur = left + 1;
	int prev = left;
	while (cur <= right)
	{
		//cur找到比key小的值,++prev,然后交交换两个位置的值,cur++
		//cur找到比key大的值,++cur
		if (a[keyi] > a[cur]&&++prev != cur)
			Swap(&a[prev], &a[cur]);
		cur++;
	}
	Swap(&a[prev], &a[keyi]);
	keyi = prev;
	QuickSort3(a, left, keyi-1);
	QuickSort3(a, keyi + 1, right);
}

小区间优化

到了递归的最后三层的时候,我们可以使用直接插入排序来排序,这样我们会减少百分之87.5的递归。这样的优化为小区间优化。小区间直接插入排序

void QuickSort3(int* a, int left, int right)
{
	if (left >= right)
		return;

	//加上小区间优化
	if ((right - left + 1) > 10)
	{
		int keyi = PartSort3(a, left, right);
		QuickSort3(a, left, keyi - 1);
		QuickSort3(a, keyi + 1, right);
	}
	else
	{
		InsertSort(a + left, right - left + 1);
	}
}

快排的非递归

递归的问题

效率,深度太深,会栈溢出。

递归改非递归

直接改成循环

使用栈辅助改循环 

如何改非递归,递归栈帧里面放的是区间。区间在变化,所以我们可以在栈里面存区间。最开始存0 - 9,进行单趟排,左区间是0 4,有区间是[ 6 ,9] 可以把这两个区间入栈,每次入栈如此反复。先入右区间,再入左区间。

1、栈里面取一段区间,单趟排序

2、单趟分割子区间入栈

3、子区间只有一个值或者不存在就不入栈

//实质就是利用自己实现的栈,来模拟编译器中的栈帧
void QuickSortNonR(int* a, int left, int right)
{
	ST st;
	STInit(&st);
	//先让0-9区间入栈
	STPush(&st, right);
	STPush(&st, left);

	while (!STEmpty(&st))
	{
		//第二步,出栈,得到区间
		int begin = STTop(&st);
		STPop(&st);
		int end = STTop(&st);
		STPop(&st);

		//取出区间后进行一趟排序
		int keyi = PartSort3(a, begin, end);
		
		//然后划分出区间
		//[begin,keyi-1][keyi][keyi+1,end]
		if (keyi + 1 < end)
		{
			STPush(&st, end);
			STPush(&st, keyi + 1);
		}

		if (begin < keyi - 1)
		{
			STPush(&st, keyi - 1);
			STPush(&st, begin);
		}
	}
	STDestory(&st);
}

7、归并排序

两个有序区间归并:依次比较,小的尾插到新空间。

但是不满足有序区间呢。我们可以使用分治的思想,使左右区间有序。相当于二叉树的后续遍历,先分区间,再归并。时间复杂度为O(NlogN)。

开一个临时数组,归并到临时数组,完了以后再拷贝回去。递归左区间再递归右区间

左右有序,再归并

void _MergeSort(int* a, int left, int right, int* temp)
{
	//递归返回条件
	if (left >= right)
	{
		return;
	}
	//首先划分区间
	int mid = (right + left) / 2;
	//然后使左右区间有序,采用分治的思想
	//[left,mid][mid + 1,right]
	_MergeSort(a, left, mid, temp);
	_MergeSort(a, mid + 1, right, temp);
	//接下来进行归并
	int begin1 = left, end1 = mid;
	int begin2 = mid + 1, end2 = right;
	//谁小就尾插进去
	int i = left;
	while (begin1 <= end1 && begin2 <= end2)
	{
		if (a[begin1] < a[begin2])
		{
			temp[i++] = a[begin1++];
		}
		else
		{
			temp[i++] = a[begin2++];
		}
	}
	while (begin1 <= end1)
	{
		temp[i++] = a[begin1++];
	}
	while (begin2 <= end2)
	{
		temp[i++] = a[begin2++];
	}
	//归并完成进行拷贝
	memcpy(a + left, temp + left, sizeof(int) * (right - left + 1));
}
void MergeSort(int* a, int n)
{
	int* temp = (int*)malloc(sizeof(int) * n);
	if (temp == NULL)
	{
		perror("malloc");
		return;
	}
	_MergeSort(a, 0, n - 1, temp);
	free(temp);
}

归并排序的非递归可以使用循环来实现,思路是

但是这个方法的边界处理有点麻烦
gap是归并过程中每组的个数,边界的控制

第一组:[i, i+gap-1]

第二组:[i + gap,i+2*gap-1]

那么如果遇到是奇数个可能会导致越界访问。

1、end1越界了怎么办? 不归并了

 2、end1没有越界 begin2越界了,跟1一样处理

 3、end2越界了,前面的都没有越界,修正end2到n-1

void MergeSortNonR(int* a, int n)
{
	int* temp = (int*)malloc(sizeof(int) * n);
	if (temp == NULL)
	{
		perror("malloc");
		return;
	}
	int gap = 1;
	//接下来进行归并
	while (gap < n)
	{
		for (int i = 0; i < n; i += 2 * gap)
		{
			int begin1 = i, end1 = i + gap - 1;
			int begin2 = i + gap, end2 = i + 2 * gap - 1;
			//谁小就尾插进去
			//如果是奇数个怎么办,我们可以分类讨论进行修正
			if (end1 >= n || begin2 >= n)
			{
				break;
			}
			else if (end2 >= n)
			{
				end2 = n - 1;
			}
			int j = i;
			while (begin1 <= end1 && begin2 <= end2)
			{
				if (a[begin1] < a[begin2])
				{
					temp[j++] = a[begin1++];
				}
				else
				{
					temp[j++] = a[begin2++];
				}
			}
			while (begin1 <= end1)
			{
				temp[j++] = a[begin1++];
			}
			while (begin2 <= end2)
			{
				temp[j++] = a[begin2++];
			}
			//归并完成进行拷贝
			memcpy(a + i, temp + i, sizeof(int) * (end2 - i + 1));
		}
		gap *= 2;
	}
	free(temp);
}

 上面的排序除了归并排序外,都是内排序,也就是在内存中排序。归并排序内外都可以。

非比较排序:

1、计数排序

统计每个数据出现的个数

进行排序

总结:

void CountSort(int* a,int n)
{
	//先求出范围
	int max = a[0], min = a[0];
	for (int i = 0; i < n; i++)
	{
		if (a[i] > max)
			max = a[i];
		if (a[i] < min)
			min = a[i];
	}
	int range = max - min + 1;
	//求出每个数出现的次数
	int* countA = (int*)malloc(sizeof(int) * range);
	memset(countA, 0, sizeof(int) * range);
	for (int i = 0; i < n; i++)
	{
		countA[a[i] - min]++;
	}

	//进行排序
	int j = 0;
	for (int i = 0; i < range; i++)
	{
		while (countA[i]--)
		{
			a[j++] = i + min;
		}
	}

	free(countA);
}

2、基数排序

3、桶排序

上面的排序基本上不会用到,这里就不在描述

时间复杂度总结

稳定性:相同数据的相对顺序是否稳定,注意是相等的数谈稳定性

稳定:冒泡排序,插入排序,归并排序。

不稳定:选择排序,希尔排序,堆排序,快速排序。

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

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

相关文章

【Flask 系统教程 2】路由的使用

Flask 是一个轻量级的 Python Web 框架&#xff0c;其简洁的设计使得构建 Web 应用变得轻而易举。其中&#xff0c;路由是 Flask 中至关重要的一部分&#xff0c;它定义了 URL 与视图函数之间的映射关系&#xff0c;决定了用户请求的处理方式。在本文中&#xff0c;我们将深入探…

关于安装Tensorflow的一些操作及问题解决

关于conda和tensorflow&#xff1a; 由于在安装tensorflow遇到各种问题&#xff0c;遇坑则进&#xff0c;耗费了很多时间。由此想整理一些关于安装tensorflow的操作和方法。欢迎各位补充和指正&#xff01; 1.conda: 1&#xff09;conda list 查看安装了哪些包。 2&#xff…

OpenCV人脸识别C++代码实现Demo

OpenCV&#xff08;Open Source Computer Vision Library&#xff09;是一个开源的计算机视觉库&#xff0c;它提供了很多函数&#xff0c;这些函数非常高效地实现了计算机视觉算法。 官网&#xff1a;https://opencv.org/ Github: https://github.com/opencv/opencv Gitcode…

如何打包Apk适配32和64位

一个表格了解lib下的文件夹 .so文件描述armeabi-v7a第七代及以上的ARM处理器&#xff0c;2011年以后生产的大部分Android设备都使用。arm64-v8a第8代、64位ARM处理器&#xff0c;很少设备&#xff0c;三星GalaxyS6是其中之一。armeabi第5代、第6代的ARM处理器&#xff0c;早期…

C语言数据结构之队列

目录 1.队列的概念及结构2.队列的实现逻辑3.队列的代码实现4.相关例题选择题 •͈ᴗ•͈ 个人主页&#xff1a;御翮 •͈ᴗ•͈ 个人专栏&#xff1a;C语言数据结构 •͈ᴗ•͈ 欢迎大家关注和订阅!!! 1.队列的概念及结构 队列&#xff1a;只允许在一端进行插入数据操作&#x…

Ubuntu系统安装nvfortran详细步骤【笔记】

实践设备&#xff1a;华硕FX-PRO&#xff08;NVIDIA GeForce GTX 960M&#xff09; Ubuntu系统安装NVFORTRAN&#xff08;NVIDIA Fortran Compiler&#xff09;步骤如下&#xff1a; 安装依赖项&#xff1a;在安装NVFORTRAN之前&#xff0c;你需要确保系统已经安装了一些必要…

IoTDB 入门教程 基础篇①——时序数据库为什么选IoTDB ?

文章目录 一、前文二、性能排行第一三、完全开源四、数据文件TsFile五、乱序数据高写入六、其他七、参考 一、前文 IoTDB入门教程——导读 关注博主的同学都知道&#xff0c;博主在物联网领域深耕多年。 时序数据库&#xff0c;博主已经用过很多&#xff0c;从最早的InfluxDB&a…

c语言刷题——输出图案

1.输出用“*”组成的X形图案 题目&#xff1a;请打印用“*”组成的X形图案 描述&#xff1a; 多组输入&#xff0c;一个整数&#xff08;2~20&#xff09;&#xff0c;表示输出的行数&#xff0c;也表示组成“X”的反斜线和正斜线的长度。 输出描述&#xff1a; 针对每行输…

一觉醒来 AI科技圈发生的大小事儿 05月04日

&#x1f4f3;CVPR 2024 Highlight | 基于单曝光压缩成像&#xff0c;不依赖生成模型也能从单张图像中重建三维场景 本文介绍了一种基于单曝光压缩成像&#xff08;SCI&#xff09;系统和神经辐射场&#xff08;NeRF&#xff09;的三维场景拍摄与重建方法&#xff0c;实现了不…

杭电acm2018 母牛的故事 Java解法 经典递归

标准递归题 先模拟 接着找递归出口 再找递归通式 想想看 今天的母牛等于前一天的母牛数加上今天出生的母牛 而三天前的母牛所有母牛都能生一头 import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner scnew Scanner(System.in);l…

单例、工厂、策略、装饰器设计模式

1. 单例模式&#xff08;Singleton Pattern&#xff09;&#xff1a; 单例模式是一种常用的设计模式&#xff0c;用于确保一个类只有一个实例&#xff0c;并提供一个全局访问点。这种模式的特点是类自己负责保存其唯一的实例&#xff0c;并控制其实例化过程。单例模式广泛应用…

(六)SQL系列练习题(下)#CDA学习打卡

目录 三. 查询信息 16&#xff09;检索"1"课程分数小于60&#xff0c;按分数降序排列的学生信息​ 17&#xff09;*按平均成绩从高到低显示所有学生的所有课程的成绩以及平均成绩 18&#xff09;*查询各科成绩最高分、最低分和平均分 19&#xff09;*按各科成绩…

【在线oj系统】02-开发环境版本说明

目录 一、前置环境版本介绍 二、SpringCloud组件停更/替换/更新 服务注册和发现 服务调用和负载均衡 分布式事务 服务熔断和降级 服务链路追踪 服务网关 分布式配置管理 三、客户端版本 一、前置环境版本介绍 使用Cloud的版本决定Boot的版本&#xff0c;SpringCloud的…

【C语言】分支和循环(上)

【C语言】分支和循环&#xff08;上&#xff09; 1、if语句1.2 else1.3分支中包含多条语句1.4嵌套if1.5悬空else问题 2、关系操作符3、条件操作符4、逻辑操作符&#xff1a;与、或、非&#xff08;取反&#xff09;&#xff08;&&&#xff0c;||&#xff0c;&#xff0…

从零开始学AI绘画,万字Stable Diffusion终极教程(五)

【第5期】ControlNet 欢迎来到SD的终极教程&#xff0c;这是我们的第五节课 这套课程分为六节课&#xff0c;会系统性的介绍sd的全部功能&#xff0c;让你打下坚实牢靠的基础 1.SD入门 2.关键词 3.Lora模型 4.图生图 5.controlnet 6.知识补充 在SD里面&#xff0c;想要…

Mysql复习笔记: 基础概念(待补充)

一. 基础概念 通用概念: 网络连接必须得分配给一个线程去进行处理&#xff0c;由一个线程来监听请求以及读取请求数据&#xff0c;比如从网络连接中读取和解析出来一条我们的系统发送过去的SQL语句 在数据库中&#xff0c;哪怕执行一条SQL语句&#xff0c;其实也可以是一个独立…

FLIR LEPTON3.5 热像仪wifi 科研实验测温采集仪

点击查看详情!点击查看详情点击查看详情点击查看详情点击查看详情点击查看详情点击查看详情点击查看详情点击查看详情点击查看详情点击查看详情点击查看详情点击查看详情点击查看详情点击查看详情 1、描述 这是一款桌面科研实验测温热成像多功能热像记录仪&#xff0c;小巧轻便…

【C/C++】

创作不易&#xff0c;本篇文章如果帮助到了你&#xff0c;还请点赞 关注支持一下♡>&#x16966;<)!! 主页专栏有更多知识&#xff0c;如有疑问欢迎大家指正讨论&#xff0c;共同进步&#xff01; &#x1f525;c系列专栏&#xff1a;C/C零基础到精通 &#x1f525; 给大…

## 01深度学习介绍与安装PyTorch

文章目录 深度学习的发展历史和基本概念早期历史兴起与发展基本概念 如何安装和设置PyTorch环境系统要求安装步骤验证安装 结语 深度学习的发展历史和基本概念 深度学习&#xff0c;一种通过使用具有多层结构的神经网络来学习数据的复杂模型的机器学习技术&#xff0c;近年来已…

Scikit是什么?

目录 一、Scikit是什么&#xff1f; 二、用Scikit做一个简单房价预测例子 三、sklearn知识点 一、Scikit是什么&#xff1f; Scikit就是scikit-learn&#xff0c;是一个免费软件机器学习库。 https://scikit-learn.org/stable/https://scikit-learn.org/stable/ 用于预测数…