数据结构初阶--排序2

news2024/11/23 4:37:27

目录

  • 前言
  • 快速排序
    • 思路
      • hoare版本
      • 代码实现
      • 挖坑法
      • 代码实现
      • 前后指针法
      • 代码实现
    • 快排优化
      • 三项取中法
      • 代码实现
      • 三指针
      • 代码实现
    • 快排非递归
      • 代码实现
  • 归并排序
    • 思路
    • 代码实现
    • 归并非递归
      • 代码实现
  • 计数排序
    • 思路
    • 代码实现

前言

本篇文章将继续介绍快排,归并等排序算法以及其变式。

快速排序

快速排序是Hoare于1962年提出的一种二叉树结构的交换排序方法。

思路

其基本思想为:任取待排序元素序列中的某元素作为基准值,按照该排序码将待排序集合分割成两子序列,左子序列中所有元素均小于基准值,右子序列中所有元素均大于基准值,然后最左右子序列重复该过程,直到所有元素都排列在相应位置上为止。
这里我们讲解三种方法:

hoare版本


hoare版本就是hoare这位大佬经过不断总结得出的方法,但这个方法存在很多需要注意的点,稍不注意就会出现bug。
首先,我们在找比key大或者小的数时,要保证left必须要小于right,因为完全有可能出现极端情况,所有数都比key小或者比key大,如果我们不添加这样的限制条件,就可能出现越界访问的情况。而且我们还需要注意书写的顺序,我们看下面这两个代码书写

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

显然,第一种书写才是正确的,因为我们要先判断再访问,这个顺序不能乱。
其次,我们还要特别注意的是,如果keyi在左边,那么右边就要先走,反之如果keyi在右边,那么左边就要先走,因为我们最后在交换keyi和左右相遇点的值时,要保证keyi的值大于相遇点的值,这时候我们就要注意,如果是左边先走,那么最后一次走是left走向right停下,这时候相遇的点是right,而right指向的值此时是比keyi大的,如果再交换,那么这个大的值就会跑到keyi的位置,这与我们的想得到的结果是背道而驰的,所以我们需要先让右先走,最后一次走就是right走left,这样再交换就对了。

这两个顺序不能换!(假设左边为keyi的情况下)
这是一趟找key将大于key和小于key分到左右两边的过程,接下来我们再递归key左边和右边直到begin和end相等为截止条件

代码实现

hoare版本的代码实现如下

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

		Swap(&arr[right], &arr[left]);
	}
	Swap(&arr[keyi], &arr[left]);
	return left;
}
void QuickSort(int arr[],int begin,int end)
{
	if (begin >= end)
	{
		return;
	}

	int keyi = PartSort1(arr,begin,end);

	QuickSort(arr,begin,keyi-1);
	QuickSort(arr,keyi+1,end);
}

挖坑法

挖坑法在hoare版本上做出了一定的优化,它可以有效避免我们需要考虑选左边为key时右边先走,右边为key时左边先走,因为我们在左边挖坑,肯定要右边找数来填,右边挖坑,肯定也要左边找数来填,我们通过图来分析

我们先将最左端下标赋值给hole,然后用key把最左端的值储存起来,避免被覆盖,然后右边先开始找小,找到了就把值放到左边的坑中,这样就形成了新坑(相当于把hole移到了新的位置),如此反复,直到左右相遇,再将我们一开始保存的key值放到hole中,整个流程就走完了。

代码实现

挖坑法的代码实现如下

int PartSort2(int arr[], int left, int right)
{
	int midi = GetMidiIndex(arr, left, right);
	Swap(&arr[left], &arr[midi]);

	int hole = left;
	int key = arr[left];
	while (left < right)
	{
		while (left < right && arr[right] >= key)
		{
			right--;
		}
		arr[hole] = arr[right];
		hole = right;
		while (left < right && arr[left] <= key)
		{
			left++;
		}
		arr[hole] = arr[left];
		hole = left;

	}
	arr[hole] = key;
	return hole;
}
void QuickSort(int arr[],int begin,int end)
{
	if (begin >= end)
	{
		return;
	}

	int keyi = PartSort2(arr,begin,end);

	QuickSort(arr,begin,keyi-1);
	QuickSort(arr,keyi+1,end);
}

前后指针法

前后指针的方法思路就是定义cur和prev两个指针,curleft+1的位置,而prev就在left的位置,cur不停往右走,走到right时停止,在走的过程中,遇到比key小的值就把该值与prev对调,同时prev也往后走,相当于prev和cur指针之间的值一直是大于key的,在对调的过程中交替着往后走,这样最终大于key的都在右边,小于key的都在做变了,我们再通过下面这幅图来分析。

代码实现

前后指针法的代码实现如下

int PartSort3(int arr[], int left, int right)
{
	int midi = GetMidiIndex(arr, left, right);
	Swap(&arr[left], &arr[midi]);

	int keyi = left;
	int prev = left;
	int cur = left + 1;
	while (cur <= right)
	{
		if (arr[cur] < arr[keyi] && ++prev != cur)
		{
			Swap(&arr[prev], &arr[cur]);
		}
		cur++;
	}
	Swap(&arr[prev], &arr[keyi]);
	keyi = prev;
	return keyi;
}
void QuickSort(int arr[],int begin,int end)
{
	if (begin >= end)
	{
		return;
	}

	int keyi = PartSort3(arr,begin,end);

	QuickSort(arr,begin,keyi-1);
	QuickSort(arr,keyi+1,end);
}

快排优化

快排在大部分情况下性能都十分的优越,但数组难免会有一些极端的情况,比如我们在取key的值时,通常都是直接取最左或者最右的值,但是不排除最左或最右的值一直或大部分时候都是当前这段数列中最大或最小的,那么在排序的时候需要移动数据的次数就会大大增加,这是得不偿失的。还有一种情况,整组数据中与key相等的值占绝大部分,我们在前面三种方法中都没有单独考虑这种情况,这样移动数据的次数同样会增加很多,而且完全没有必要。接下来我们就通过三项取中三指针法对以上两种特殊情况进行优化。

三项取中法

首先是三项取中,我们可以考虑从最左,最右和中间的三个数中取第二大的值作为key值。这样就可以得到一个较平均的值。

代码实现

三项取中的代码如下,我们单独写一个函数,再将返回值与最左边/最右边的值互换(因为key还是取最左边或最右边的值)。

int GetMidiIndex(int arr[], int left, int right)
{
	int mid = (left + right) / 2;
	if (arr[mid] < arr[left])
	{
		if (arr[left] < arr[right])
		{
			return left;
		}
		else if (arr[right] < arr[mid])
		{
			return mid;
		}
		else
		{
			return right;
		}
	}
	else
	{
		if (arr[left] > arr[right])
		{
			return left;
		}
		else if (arr[right] > arr[mid])
		{
			return mid;
		}
		else
		{
			return right;
		}
	}
}

三指针

我们来看力扣里的一道题
力扣–排序数组
题目描述如下

描述很简单,就是让你排序数组,但是当我们把快排代码书写进去,发现居然显示超出时间限制了,我们来看未通过的测试用例:

我们发现这个测试用例的值全部都是2,这就是刚刚提到的大部分或全部和key值相等的情况,所以我们要采用hoare和前后指针结合的新方法–三指针来解决这类特殊情况。
三指针的基本思路是:创建left,right和cur三个指针,其中left到right之间放置和key值相等的值,cur用来从左往右遍历当前范围内的数据.
1,arr[cur]<key,交换arr[cur]和arr[left]的值,left++,cur++.
2,
3,

代码实现

三指针代码实现如下

void QuickSort(int arr[],int begin,int end)
{
	//三指针
	if (begin >= end)
	{
		return;
	}
	int left = begin;
	int right = end;
	int cur = left + 1;

	int midi = GetMidiIndex(arr, left, right);
	Swap(&arr[left], &arr[midi]);
	int key = arr[midi];

	while (cur <= right)
	{
		if (arr[cur] < key)
		{
			Swap(&arr[left], &arr[cur]);
			++left;
			++cur;
		}
		if (arr[cur] > key)
		{
			Swap(&arr[cur], &arr[right]);
			--right;
		}
		else
		{
			cur++;
		}
	}

	QuickSort(arr, begin, left - 1);
	QuickSort(arr, right + 1, end);
}

快排非递归

在学习完快排的递归操作后,我们现在来学习快排的非递归实现。
要实现快排非递归,我们需要借助栈这个数据结构,每次将左右端值压栈,然后再取出进行单趟排序,再修改左右端值再压栈,再取出,直到栈为空截止
和递归时的区间一样,此时数组被分为了[left,mid-1]mid[mid+1,right]三个部分,和递归终止条件begin>=end类似,只有当left<mid-1和mid+1<right才会继续进行压栈操作,否则不用再往里放入数据了
还要注意栈后进先出的原则,如果先放左再放右,那么取的时候取出来的顺序就是先右后左

代码实现

快排非递归的代码实现如下(栈的操作就没有具体写出了 可以参照栈的实现:栈的实现(C语言))

int PartSort1(int arr[],int left,int right)
{
	int midi = GetMidiIndex(arr, left, right);
	Swap(&arr[left], &arr[midi]);

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

		Swap(&arr[right], &arr[left]);
	}
	Swap(&arr[keyi], &arr[left]);
	return left;

}
void QuickSortNonR(int arr[], int left, int right)
{
	ST st;
	STInit(&st);
	STPush(&st, left);
	STPush(&st, right);

	while (!STEmpty(&st))
	{
		int right = STTop(&st);
		STPop(&st);
		int left = STTop(&st);
		STPop(&st);
		int mid = PartSort1(arr, left, right);

		if (right > mid + 1)
		{
			STPush(&st, mid + 1);
			STPush(&st, right);
		}

		if (left < mid - 1)
		{
			STPush(&st, left);
			STPush(&st, mid - 1);

		}
	}
	
	STDestroy(&st);
}

归并排序

归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide andConquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。

思路

归并的递归思路和二叉树的后序遍历操作思想类似,这个是有别于快排的,快排前序操作思想,每次选出一个key值,将比key大的放右边,比key小的放左边,再在小区间里选出key,再重复操作,而归并排序思想和这个完全相反,我们要先保证最后的数组是有序的,再两两归并,四四归并,八八归并,直到整个数组都有序。所以我们要把递归操作写在归并操作前面,下面来讲归并操作:
归并操作和力扣一道合并两个有序数组类似,我们要能进行归并操作也是首先要保证两个子序列有序,感兴趣的读者可以去做一下这道题:
力扣–合并两个有序数组
我们归并的主体思路是:
1,再动态开辟一个数组temp
2,分别用begin1和begin2作为下标遍历两个数组,依次比较,将较小值尾插
3,设定end1和end2分别作为两个数组的截止条件,当某一个数组走到尾后,另一个数组剩余的值一定大于走完这个数组的所有值,所以直接把剩余数值依次拷贝到temp数组即可
4,最后再将temp数组拷贝回arr进行递归

代码实现

归并排序的代码实现如下:

void _MergeSort(int arr[],int temp[],int begin,int end)
{
	if (begin == end)
	{
		return;
	}
	int mid = (begin + end) / 2;
	_MergeSort(arr, temp, begin, mid);
	_MergeSort(arr, temp, mid + 1, end);
	
	int begin1 = begin, end1 = mid;
	int begin2 = mid+1, end2 = end;
	int i = begin;
	while (begin1 <= end1 && begin2 <= end2)
	{
		if (arr[begin1] < arr[begin2])
		{
			temp[i++] = arr[begin1++];
		}
		else
		{
			temp[i++] = arr[begin2++];
		}
	}
	while (begin1 <= end1)
	{
		temp[i++] = arr[begin1++];
	}
	while (begin2 <= end2)
	{
		temp[i++] = arr[begin2++];
	}

	memcpy(arr + begin, temp + begin, sizeof(int) * (end - begin + 1));
}
void MergeSort(int arr[], int n)
{
	int* temp = (int*)malloc(sizeof(int) * n);
	if (temp == NULL)
	{
		perror("malloc fail");
		return;
	}
	_MergeSort(arr,temp,0,n-1);
	free(temp);
}

归并非递归

在学完归并排序的递归操作后,我们再来学习归并操作非递归实现。
我们要想实现非递归,其实就相当于从递归操作最深处开始利用循环逐步往浅走即我们首先要两两归并(一个数据我们默认可以看作有序),再四四归并,再八八归并,直到全部有序,但我们会发现一个问题,只有当数据个数为2的整数倍次方时,才能保证每次归并都不会发生越界,否则无法保证
可能有些抽象,我们通过画图来理解:
假设我们有10个数据。

我们定义gap为间隔,第一次是1,第二次是2,以此类推,我们再用i来每次遍历数组归并(每次往后走2gap),每两组需要归并的数组(比如图中第一次归并的2和3)左右区间分别为 i i+gap-1 i+gap i+2gap-1.,因为i我们添加了限制条件,是恒小于长度的,所以不会越界,但剩下三个边界都有可能超出范围,我们依据图来分析

我们可以把这三种情况的修正分为两类
1,第一种和第二种情况,有一个区间根本不存在,所以我们直接break。
2,第三种情况,两个区间都存在,我们只需要将右区间的右边界修改为n-1即可

如果我们在最后才拷贝数据,数组最后可能会有随机值出现,所以我们归并一次,就拷贝一次

代码实现

归并排序非递归代码实现如下

void MergeSortNonR(int arr[], int n)
{
	int* temp = (int*)malloc(sizeof(int) * n);
	if (temp == NULL)
	{
		perror("malloc fail");
	}
	int gap = 1;
	while (gap < n)
	{
		int j = 0;
		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;
			}
			if (end2 >= n)
			{
				end2 = n - 1;
			}
			while (begin1 <= end1 && begin2 <= end2)
			{
				if (arr[begin1] < arr[begin2])
				{
					temp[j++] = arr[begin1++];
				}
				else
				{
					temp[j++] = arr[begin2++];
				}
			}

			while (begin1 <= end1)
			{
				temp[j++] = arr[begin1++];
			}
			while (begin2 <= end2)
			{
				temp[j++] = arr[begin2++];
			}
			memcpy(arr + i, temp + i, sizeof(int) * (end2 - i + 1));
		}
		gap *= 2;
	}
	free(temp);
}

计数排序

计数排序是一种非比较排序,计数排序又称为鸽巢原理,是一种对哈希表的变形应用。

思路

计数排序的思路比较简单,先遍历一遍数组,确定最大和最小值,作为我们创建哈希表的边界依据,我们把最小的数作为基准。然后我们再遍历一遍数组,统计相同元素出现的次数,即在对应的位置++(每个位置最初的值都为0).
然后再遍历一遍哈希表将统计的结果放回到原数组中即可。
我们不难发现,当数据很集中时,它的时间复杂度为0(N),是比堆排,希尔排序甚至比快排(O(N*logN))还要快的,但我们也就可以发现它的劣势,那就是当数据非常分散时,它的效果是很不好的。

代码实现

计数排序的代码实现如下;

void CountSort(int* a, int n)
{
	int min = a[0], max = a[0];
	for (int i = 0; i < n; i++)
	{
		if (a[i] < min)
		{
			min = a[i];
		}

		if (a[i] > max)
		{
			max = 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 k = 0;
	for (int j = 0; j < range; j++)
	{
		while (countA[j]--)
		{
			a[k++] = j + min;
		}
	}
}

到这里,六大排序的全部内容就讲完了,如有出入,欢迎指正。

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

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

相关文章

2023年iOS App Store上架流程详解(上)

目录 1.注册开发者账号 2.登录并配置人员 3.申请证书和配置文件 一.证书管理​ 二.新建证书​ 三.使用appuploader服务同步证书​ 1&#xff09;申请证书 2&#xff09;添加Identifiers和配置App ID 3&#xff09;申请配置文件 1.在Xcode项目中配置签名 2.上传应用包…

数据库应用:死锁、悲观锁、乐观锁

目录 一、理论 1.死锁 2.悲观锁 3.乐观锁 二、总结 一、理论 1.死锁 &#xff08;1&#xff09;概念 死锁是指两个或两个以上的进程在执行过程中&#xff0c;因争夺资源而造成的一种互相等待的现象&#xff0c;若无外力作用&#xff0c;它们都将无法推进下去。此时称系…

INVDIA GPU参数列表:P100,V100,A100,A800,H100等性能参数

一、P100与V100 训练深层神经网络的时候&#xff0c;V100比P100快大约2倍 二、A100 三、A800 四、H100 引用 1、 世上最全NVDIA GPU参数列表&#xff1a; V100&#xff0c; A100&#xff0c; A800&#xff0c;H100&#xff0c;3090&#xff0c;4090&#xff0c; A40&#xf…

Unity使用Android Stdio接入SDK制作AAR包

最近需要在Unity2021版本中接入SDK&#xff0c;发现和直接接入SDK有些区别&#xff0c;这里把接入的流程记录一下。 Unity在最新的版本中把UnityPlayActivity.java&#xff0c;从Class.jar中移除&#xff0c;需要在Unity的工程内找到这个文件&#xff0c;并把其加入到Android …

【监控系统】Prometheus监控组件Mysql-Exporter配置实战

Mysql-Exporter主要监控Mysql数据库的稳定性、吞吐量、连接情况、缓冲池使用情况、查询性能等各项指标&#xff0c;是我们压测时常常需要监控的一些指标。 目前&#xff0c;Exporter 支持高于5.6版本的 MySQL 和高于10.1版本的 MariaDB。在 MySQL/MariaDB 低于5.6版本时&#…

MobPush 最佳实践:消息重弹

功能概述 消息重弹功能&#xff0c;可在安卓在线通道送达的消息被其他消息挤下去时&#xff0c;重新置顶&#xff0c;增加消息的曝光度和点击率。 适用场景 仅支持Mob通过自有TCP通道下发的通知消息&#xff0c;不支持自定义推送消息支持开发者后台和推送API配置使用 功能使…

安天逆向教程——常用汇编语句

一.汇编基础 二.条件分支 反汇编时更多关注这些条件分支。如果看懂这些条件分支&#xff0c;会对程序的大体逻辑有一个整体的了解。 至于程序里面的细节&#xff0c;有时会省略掉。往往关键的跳转理解了甚至进行一点点的改动&#xff0c;就会使得程序发生翻天覆地的变化。 三…

读书笔记怎么写?《金字塔原理》读书笔记

​生活工作中有很多需要表达的场景&#xff0c;表达最重要的是逻辑清晰&#xff0c;表达出来的想法才能被理解&#xff0c;进而解决生活或工作中的困境。 《金字塔原理》详细地介绍了思维表达的方法&#xff0c;金字塔原理除了能够帮助人们以书面形式组织和表达思想以外&#x…

Vue3 组件之间父子通信

文章目录 Vue3 组件之间父子通信概述选项式API父传子子传父 组合式API父传子子传父 Vue3 组件之间父子通信 概述 所有的 props 都遵循着单向绑定原则&#xff0c;props 因父组件的更新而变化&#xff0c;自然地将新的状态向下流往子组件&#xff0c;而不会逆向传递。 选项式…

虚拟现实:将数字融入现实

随着科技的不断进步&#xff0c;虚拟现实正逐渐走进我们的现实生活&#xff0c;为我们带来了许多新的体验和可能性。虚拟现实技术将数字世界与真实世界融合在一起&#xff0c;为我们创造了令人惊叹的沉浸式体验。让我们一起探索虚拟现实正在走进现实的意义和影响。 虚拟现实为我…

C语言进阶之通讯录的实现(静态版和动态版)以及动态内存管理

通讯录的实现及动态内存管理 1.通讯录实现要求2.静态版通讯录实现2.1 contact.h文件实现2.2 contact.c文件实现2.3 main.c文件实现2.4 静态版通讯录全部文件代码 3.动态内存管理3.1 为什么存在动态内存分配3.2 动态内存函数的介绍3.3 常见的动态内存错误3.4 C/C程序的内存开辟3…

海盗搜身-2022年全国青少年信息素养大赛Python国赛第9题

[导读]&#xff1a;超平老师计划推出《全国青少年信息素养大赛Python编程真题解析》50讲&#xff0c;这是超平老师解读Python编程挑战赛真题系列的第11讲。 全国青少年信息素养大赛&#xff08;原全国青少年电子信息智能创新大赛&#xff09;是“世界机器人大会青少年机器人设…

vue3+ts+element-plus管理系统实际开发业务之增删改查

文章目录 功能一&#xff1a; 实现一个表格增、删、改、查功能✏️ 1. 表格、添加按钮、删除按钮、搜索框和搜索按钮、编辑按钮添加&#x1f4d2; 运行后页面效果&#xff1a;如下 ✏️ 2. 使用添加按钮添加一条新纪录&#xff0c;逻辑点击按钮弹出带有表单的弹窗进行输入添加。…

Elasticsearch--查询(nested、join)

nested 嵌套类型 数据的某个值是json、object对象&#xff1b;不再是简单的数据类型&#xff0c;或者简单数据类型的数组&#xff1b;那么还用之前的查询方式就有问题了。因为ES在存储复杂类型的时候会把对象的复杂层次结果扁平化为一个键值对列表 。此时&#xff0c;需要用n…

一文了解OLED拼接屏优点

随着科技的不断发展&#xff0c;显示技术也在不断地更新换代。其中&#xff0c;OLED技术是目前最为先进的显示技术之一。 OLED拼接屏是一种利用OLED技术制作的大屏幕显示设备&#xff0c;可以将多个OLED屏幕拼接在一起&#xff0c;形成一个更大的显示屏幕。济南OLED拼接屏是一…

分布式锁的实现方式

文章目录 一、分布式锁概述1.1 为什么需要分布式锁1.2 概述分布式锁1.3 分布式锁的特性1.4 分布式锁的类型1.5 实现重点 二、Mysql数据库实现分布式锁2.1 表结构2.2 加锁2.3 解锁2.4 锁超时2.5 实现重入锁 三、Redis实现分布式锁3.1 加锁3.2 解锁3.3 锁超时3.4 redlock的容错性…

设计模式-简单工厂模式

文章目录 简单工厂设计模式什么是简单工厂?为什么使用简单工厂工厂模式代码实现简单工厂优缺点优点&#xff1a; 简单工厂设计模式 学习视频 什么是简单工厂? 简单工厂模式属于类的创建型模式&#xff0c;又叫做静态工厂方法模式。通过专门定义一个类来负责创建其他类的实…

GitLab CICD Day 08 - 环境变量

1.局部/全局环境变量 stages:- testing # stage编排- build- deployvariables:global_var: "全部变量" #全部变量build_image:stage: buildvariables: #局部环境变量my_name: "局部环境变量" tags:- shell script:- …

14款奔驰R400升级ACC自适应巡航系统,增加您的行车安全性

有的时候你是否厌倦了不停的刹车、加油&#xff1f;是不是讨厌急刹车&#xff0c;为掌握不好车距而烦恼&#xff1f;如果是这样&#xff0c;那么就升级奔驰原厂ACC自适应式巡航控制系统&#xff0c;带排队自动辅助和行车距离警报功能&#xff0c;感受现代科技带给你的舒适安全和…

window.getComputedStyle

遇见一个问题&#xff0c;一个元素样式用的 固定定位。但是 top 属性没有在 元素树&#x1f332;种显示。js获取不到。这个方法可以获取到 style 里面设置的样式