,数据结构,
第十章 (上 )
数据结构
tjm
第十章 内部排序
10.1 概述
10.2 插入排序
10.2.1 直接插入排序
10.2.2 其它插入排序
10.2.3 希尔排序
10.3 快速排序
10.4 选择排序
10.4.1 简单选择排序
10.4.3 堆排序
10.5 归并排序
10.6 基数排序
10.6.1 多关键字的排序
10.6.2 链式基数排序
10.7 各种内部排序方法的比较讨论
数据结构
tjm
10.1 概述
排序:将一个数据元素(或记录)的任意序列,重新
排列成一个按关键字有序的序列。
有序表与无序表,一组记录按关键字的递增或递减次
序排列得到的结果被称之为有序表, 相应地, 把排序
前的状态称为无序表 。
内部排序和外部排序:
内部排序:待排序记录存放在内存
外部排序:排序过程中需对外存进行访问的排序
正序表与逆序表, 若有序表是按关键字升序排列的,
则称为升序表或正序表,否则称为降序表或逆序表。
不失普遍性,一般只讨论正序表。
数据结构
tjm
内部排序得方法:
插入排序:直接插入排序、折半插入排序、希尔排序
交换排序:冒泡排序、快速排序
选择排序:简单选择排序、堆排序
归并排序,2-路归并排序
其它排序, 多关键字排序、基数排序
排序基本操作:
比较两个关键字大小
将记录从一个位置移动到另一个位置
排序算法的 稳定性,
考虑有多个数据元素具有相同关键字的情况。
稳定:具有相同关键字的数据元素的相对位置关系
在排序前后保持不变。
不稳定:具有相同关键字的数据元素的相对位置关
系在排序前后发生了改变。
数据结构
tjm
例, 49 38 65 97 76 13 27
i=2 38 (38 49) 65 97 76 13 27
i=3 65 (38 49 65) 97 76 13 27
i=4 97 (38 49 65 97) 76 13 27
i=5 76 (38 49 65 76 97) 13 27
i=6 13 (13 38 49 65 76 97) 27
i=1 ( )
i=7 (13 38 49 65 76 97) 2727
jj j jjj
977665493827
(13 27 38 49 65 76 97)排序结果:
10.2 插入排序
10.2.1 直接插入排序
排序过程:整个排序过程为 n-1趟插入,即先将序
列中第 1个记录看成是一个有序子序列,然后从第 2
个记录开始,逐个进行插入,直至整个序列有序 。
算法 参见 P265
数据结构
tjm
若待排序记录按关键字从小到大排列 (正序 ),则
关键字比较次数,11
2
???
?
nn
i
记录移动次数,)1(22
2
???
?
nn
i
若待排序记录按关键字从大到小排列 (逆序 ),则
关键字比较次数:
2
)1)(2(
2
????
?
nnin
i记录移动次数:
2
)1)(4()1(
2
?????
?
nnin
i若待排序记录是随机的,取平均值,则
关键字比较次数约:
4
2n
记录移动次数约:
4
2n
时间复杂度,T(n)=O(n2)
空间复杂度,S(n)=O(1)
直接插入排序是一种稳定的排序方法。
算法评价
数据结构
tjm
折半插入排序:用折半查找方法确定插入位置。
例,i=1 (30) 13 70 85 39 42 6 20
i=2 13 (13 30) 70 85 39 42 6 20
i=7 6 (6 13 30 39 42 70 85 ) 20
…
i=8 20 (6 13 30 39 42 70 85 ) 20
s jm
i=8 20 (6 13 30 39 42 70 85 ) 20
s jm
i=8 20 (6 13 30 39 42 70 85 ) 20
s jm
i=8 20 (6 13 30 39 42 70 85 ) 20
sj
i=8 20 (6 13 20 30 39 42 70 85 )
10.2.2 其它插入排序
算法 参见 P267
时间复杂度,T(n)=O(n2) 空间复杂度,S(n)=O(1)
数据结构
tjm
10.2.3 希尔排序
希尔排序( Shell Sort)又称为, 缩小增量排
序, 。 排序过程:先取一个正整数 d1<n,把所有
相隔 d1的记录放一组,组内进行直接插入排序;
然后取 d2<d1,重复上述分组和排序操作;直至
di=1,即所有记录放进一个组中排序为止 。
数据结构
tjm
取 d3=1
三趟分组,13 27 48 55 4 49 38 65 97 76
三趟排序,4 13 27 38 48 49 55 65 76 97
例:初始,49 38 65 97 76 13 27 48 55 4
一趟排序,13 27 48 55 4 49 38 65 97 76
二趟排序,13 4 48 38 27 49 55 65 97 76
取 d1=5
一趟分组,49 38 65 97 76 13 27 48 55 4
取 d2=3
二趟分组,13 27 48 55 4 49 38 65 97 76
数据结构
tjm
其中第一趟排序过程如下,
49 38 65 97 76 13 27 48 55 4
j i
4913 3827
第二趟,13 27 48 55 4 49 38 65 97 76
j ij i
274
j ij i
55
j i
38
j ij ij i
j ij i
6548
j i
9755
j i
764
算法 参见 P272
数据结构
tjm
希尔排序特点
子序列的构成不是简单的“逐段分割”,而是将相
隔某个增量的记录组成一个子序列。 关键字较小的
记录跳跃式前移,在进行最后一趟增量为 1的插入排
序时,序列已基本有序。
希尔排序的时间复杂度在 O( nlog2n)和 O( n2 )之
间,大致为 O( n 1.3)。
由于希尔排序对每个子序列单独比较,在比较时进
行元素移动,有可能改变相同排序码元素的原始顺
序,因此希尔排序是不稳定的。
增量序列取法,
无除 1以外的公因子。
最后一个增量值必须为 1。
数据结构
tjm
10.3 快速排序
冒泡排序
排序过程:将第一个记录的关键字与第二个记录的关
键字进行比较,若为逆序 r[1].key>r[2].key,则交换;
然后比较第二个记录与第三个记录;依次类推,直至
第 n-1个记录和第 n个记录比较为止 —— 第一趟冒泡排
序,结果关键字最大的记录被放在最后。
对前 n-1个记录进行第二趟冒泡排序,结果使关键字
次大的记录被放在第 n-1个位置。重复上述过程,直
到“在一趟排序过程中没有进行过交换记录的操作”
为止。
算法 参见 P16算法。
数据结构
tjm
例 38
49
65
76
13
27
30
97
第
一
趟
38
49
65
13
27
30
76
第
二
趟
38
49
13
27
30
65
第
三
趟
38
13
27
30
49
第
四
趟
13
27
30
38
第
五
趟
13
27
30
第
六
趟
49
38
65
97
76
13
27
30
初
始
关
键
字
n=8
38
49
76
9713
9727
9730
97
13
76
76
7627
30
13
6527
6530
65
13
13
49
4930
4927
3827
3830
38
13
27
第
七
趟
排序后序列为,13 27 30 38 49 65 76 97
数据结构
tjm
算法评价
最好情况(正序)时:
比较次数,n-1
移动次数,0
最坏情况(逆序)时:
比较次数:
)(21)( 2
1
1
nnin
n
i
????
?
?
移动次数:
)(23)(3 2
1
nnin
n
i
????
?
空间复杂度,S(n)=O(1)
时间复杂度,T(n)=O(n2)
数据结构
tjm
快速排序
首先从 j所指位置向前搜索第一个关键字小于 x的记
录,并和 rp交换。再从 i所指位置起向后搜索,找
到第一个关键字大于 x的记录,和 rp交换。重复上
述两步,直至 i=j为止。
基本思想:通过一趟排序,将待排序记录分割成独立
的两部分,其中一部分记录的关键字均比另一部分记
录的关键字小,则可分别对这两部分记录进行排序,
以达到整个序列有序。
排序过程:
对 r[s…… t]中记录进行一趟快速排序,附设两个
指针 i和 j,设枢轴记录 rp=r[s],x=rp.key。初始时
令 i=s,j=t。
再分别对两个子序列进行快速排序,直到每个子序
列只含有一个记录为止 。
数据结构
tjm
例,初始关键字,49 38 65 97 76 13 27 50
i jji
完成一趟排序,( 27 38 13) 49 (76 97 65 50)
分别进行快速排序,( 13) 27 (38) 49 (50 65) 76 (97)
快速排序结束,13 27 38 49 50 65 76 97
4927
i i ji
49 65
j
13 4949 97
i j
算法 参见 P2754,P275
x=49
数据结构
tjm
时间复杂度:
最好情况(每次总是选到中间值作枢轴):
T(n)=O(nlog2n)。
最坏情况(每次总是选到最小或最大元素作枢轴):
T(n)=O(n2)。
算法评价
数据结构
tjm
10.4 选择排序
10.4.1 简单选择排序
首先通过 n-1次关键字比较,从 n个记录中找出关键
字最小的记录,将它与第一个记录交换。
再通过 n-2次比较,从剩余的 n-1个记录中找出关键
字次小的记录,将它与第二个记录交换。
重复上述操作,共进行 n-1趟排序后,排序结束。
算法 参见 P277
排序过程:
例:
初始,[ 49 38 65 97 76 13 27 ]
k
j j j j j j
k k
i=1 13 49
数据结构
tjm
三趟,13 27 [65 97 76 49 38 ]
四趟,13 27 38 [97 76 49 65 ]
五趟,13 27 38 49 [76 97 65 ]
六趟,13 27 38 49 65 [97 76 ]
13 27 38 49 65 76 [97 ]
排序结束,13 27 38 49 65 76 97
二趟,13 [38 65 97 76 49 27 ]i=2
k k
j j j jj
27 38
数据结构
tjm
时间复杂度,T(n)=O(n2)
算法评价
)(21)( 2
1
1
nnin
n
i
????
?
?
比较次数:
记录移动次数
最好情况,0
最坏情况,3(n-1)
数据结构
tjm
或 ( i=1,2,…..,?n/2? )ki?k2i
ki?k2i+1
ki?k2i
ki?k2i+1
例:
( 96,83,27,38,11,9)
例:
( 13,38,27,50,76,65,49,97)
96
27
91138
83
13
2738
49657650
97
可将堆序列看成完全二叉树,则堆顶
元素(完全二叉树的根)必为序列中
n个元素的最小值或最大值
10.4.3 堆排序
堆的定义,n个元素的序列 (k1,k2,……k n),当且仅当
满足下列关系时,称之为堆。
数据结构
tjm
堆排序:将无序序列建成一个堆,得到关键字最小
(或最大)的记录;输出堆顶的最小(大)值后,使
剩余的 n-1个元素重又建成一个堆,则可得到 n个元素
的次小值;重复执行,得到一个有序序列。
堆排序需解决的两个问题:
如何由一个无序序列建成一个堆?
如何在输出堆顶元素之后,调整剩余元素,使之成为
一个新的堆?
第二个问题解决方法 —— 筛选。
方法:输出堆顶元素之后,以堆中最后一个元素替代
之;然后将根结点值与左、右子树的根结点值进行比
较,并与其中小者进行交换;重复上述操作,直至叶
子结点,将得到新的堆,称这个从堆顶至叶子的调整
过程为“筛选”。
算法 参见 P282
数据结构
tjm
例:
13
2738
49657650
97
97
2738
49657650
13
输出,13
27
4938
97657650
13
输出,13
97
4938
27657650
13
输出,13 27
38
4950
27657697
13
输出,13 27
65
4950
27387697
13
输出,13 27 38
数据结构
tjm
49
6550
27387697
13
输出,13 27 38
76
6550
27384997
13
输出,13 27 38 49
50
6576
27384997
13
输出,13 27 38 49
97
6576
27384950
13
输出,13 27 38 49 50
65
9776
27384950
13
输出,13 27 38 49 50
97
6576
27384950
13
输出,13 27 38 49 50 65
数据结构
tjm
76
6597
27384950
13
输出,13 27 38 49 50 65
97
6576
27384950
13
输出,13 27 38 49 50 65 76
97
6576
27384950
13
输出,13 27 38 49 50 65 76 97
数据结构
tjm
例,含 8个元素的无序序列( 49,38,65,97,76,13,
27,50)
49
6538
27137697
50
49
6538
27137650
97
49
1338
27657650
97
49
1338
27657650
97
13
2738
49657650
97
第一个问题的解决方法:从无序序列的第 ?n/2?个元素
(即此无序序列对应的完全二叉树的最后一个非终端结
点)起,至第一个元素止,进行反复筛选。
算法 参见 P282
数据结构
tjm
算法评价
堆排序的时间复杂度为,T(n)=O(nlog2n)。
堆排序是一种不稳定的排序方法 。
第十章 (上 )
数据结构
tjm
第十章 内部排序
10.1 概述
10.2 插入排序
10.2.1 直接插入排序
10.2.2 其它插入排序
10.2.3 希尔排序
10.3 快速排序
10.4 选择排序
10.4.1 简单选择排序
10.4.3 堆排序
10.5 归并排序
10.6 基数排序
10.6.1 多关键字的排序
10.6.2 链式基数排序
10.7 各种内部排序方法的比较讨论
数据结构
tjm
10.1 概述
排序:将一个数据元素(或记录)的任意序列,重新
排列成一个按关键字有序的序列。
有序表与无序表,一组记录按关键字的递增或递减次
序排列得到的结果被称之为有序表, 相应地, 把排序
前的状态称为无序表 。
内部排序和外部排序:
内部排序:待排序记录存放在内存
外部排序:排序过程中需对外存进行访问的排序
正序表与逆序表, 若有序表是按关键字升序排列的,
则称为升序表或正序表,否则称为降序表或逆序表。
不失普遍性,一般只讨论正序表。
数据结构
tjm
内部排序得方法:
插入排序:直接插入排序、折半插入排序、希尔排序
交换排序:冒泡排序、快速排序
选择排序:简单选择排序、堆排序
归并排序,2-路归并排序
其它排序, 多关键字排序、基数排序
排序基本操作:
比较两个关键字大小
将记录从一个位置移动到另一个位置
排序算法的 稳定性,
考虑有多个数据元素具有相同关键字的情况。
稳定:具有相同关键字的数据元素的相对位置关系
在排序前后保持不变。
不稳定:具有相同关键字的数据元素的相对位置关
系在排序前后发生了改变。
数据结构
tjm
例, 49 38 65 97 76 13 27
i=2 38 (38 49) 65 97 76 13 27
i=3 65 (38 49 65) 97 76 13 27
i=4 97 (38 49 65 97) 76 13 27
i=5 76 (38 49 65 76 97) 13 27
i=6 13 (13 38 49 65 76 97) 27
i=1 ( )
i=7 (13 38 49 65 76 97) 2727
jj j jjj
977665493827
(13 27 38 49 65 76 97)排序结果:
10.2 插入排序
10.2.1 直接插入排序
排序过程:整个排序过程为 n-1趟插入,即先将序
列中第 1个记录看成是一个有序子序列,然后从第 2
个记录开始,逐个进行插入,直至整个序列有序 。
算法 参见 P265
数据结构
tjm
若待排序记录按关键字从小到大排列 (正序 ),则
关键字比较次数,11
2
???
?
nn
i
记录移动次数,)1(22
2
???
?
nn
i
若待排序记录按关键字从大到小排列 (逆序 ),则
关键字比较次数:
2
)1)(2(
2
????
?
nnin
i记录移动次数:
2
)1)(4()1(
2
?????
?
nnin
i若待排序记录是随机的,取平均值,则
关键字比较次数约:
4
2n
记录移动次数约:
4
2n
时间复杂度,T(n)=O(n2)
空间复杂度,S(n)=O(1)
直接插入排序是一种稳定的排序方法。
算法评价
数据结构
tjm
折半插入排序:用折半查找方法确定插入位置。
例,i=1 (30) 13 70 85 39 42 6 20
i=2 13 (13 30) 70 85 39 42 6 20
i=7 6 (6 13 30 39 42 70 85 ) 20
…
i=8 20 (6 13 30 39 42 70 85 ) 20
s jm
i=8 20 (6 13 30 39 42 70 85 ) 20
s jm
i=8 20 (6 13 30 39 42 70 85 ) 20
s jm
i=8 20 (6 13 30 39 42 70 85 ) 20
sj
i=8 20 (6 13 20 30 39 42 70 85 )
10.2.2 其它插入排序
算法 参见 P267
时间复杂度,T(n)=O(n2) 空间复杂度,S(n)=O(1)
数据结构
tjm
10.2.3 希尔排序
希尔排序( Shell Sort)又称为, 缩小增量排
序, 。 排序过程:先取一个正整数 d1<n,把所有
相隔 d1的记录放一组,组内进行直接插入排序;
然后取 d2<d1,重复上述分组和排序操作;直至
di=1,即所有记录放进一个组中排序为止 。
数据结构
tjm
取 d3=1
三趟分组,13 27 48 55 4 49 38 65 97 76
三趟排序,4 13 27 38 48 49 55 65 76 97
例:初始,49 38 65 97 76 13 27 48 55 4
一趟排序,13 27 48 55 4 49 38 65 97 76
二趟排序,13 4 48 38 27 49 55 65 97 76
取 d1=5
一趟分组,49 38 65 97 76 13 27 48 55 4
取 d2=3
二趟分组,13 27 48 55 4 49 38 65 97 76
数据结构
tjm
其中第一趟排序过程如下,
49 38 65 97 76 13 27 48 55 4
j i
4913 3827
第二趟,13 27 48 55 4 49 38 65 97 76
j ij i
274
j ij i
55
j i
38
j ij ij i
j ij i
6548
j i
9755
j i
764
算法 参见 P272
数据结构
tjm
希尔排序特点
子序列的构成不是简单的“逐段分割”,而是将相
隔某个增量的记录组成一个子序列。 关键字较小的
记录跳跃式前移,在进行最后一趟增量为 1的插入排
序时,序列已基本有序。
希尔排序的时间复杂度在 O( nlog2n)和 O( n2 )之
间,大致为 O( n 1.3)。
由于希尔排序对每个子序列单独比较,在比较时进
行元素移动,有可能改变相同排序码元素的原始顺
序,因此希尔排序是不稳定的。
增量序列取法,
无除 1以外的公因子。
最后一个增量值必须为 1。
数据结构
tjm
10.3 快速排序
冒泡排序
排序过程:将第一个记录的关键字与第二个记录的关
键字进行比较,若为逆序 r[1].key>r[2].key,则交换;
然后比较第二个记录与第三个记录;依次类推,直至
第 n-1个记录和第 n个记录比较为止 —— 第一趟冒泡排
序,结果关键字最大的记录被放在最后。
对前 n-1个记录进行第二趟冒泡排序,结果使关键字
次大的记录被放在第 n-1个位置。重复上述过程,直
到“在一趟排序过程中没有进行过交换记录的操作”
为止。
算法 参见 P16算法。
数据结构
tjm
例 38
49
65
76
13
27
30
97
第
一
趟
38
49
65
13
27
30
76
第
二
趟
38
49
13
27
30
65
第
三
趟
38
13
27
30
49
第
四
趟
13
27
30
38
第
五
趟
13
27
30
第
六
趟
49
38
65
97
76
13
27
30
初
始
关
键
字
n=8
38
49
76
9713
9727
9730
97
13
76
76
7627
30
13
6527
6530
65
13
13
49
4930
4927
3827
3830
38
13
27
第
七
趟
排序后序列为,13 27 30 38 49 65 76 97
数据结构
tjm
算法评价
最好情况(正序)时:
比较次数,n-1
移动次数,0
最坏情况(逆序)时:
比较次数:
)(21)( 2
1
1
nnin
n
i
????
?
?
移动次数:
)(23)(3 2
1
nnin
n
i
????
?
空间复杂度,S(n)=O(1)
时间复杂度,T(n)=O(n2)
数据结构
tjm
快速排序
首先从 j所指位置向前搜索第一个关键字小于 x的记
录,并和 rp交换。再从 i所指位置起向后搜索,找
到第一个关键字大于 x的记录,和 rp交换。重复上
述两步,直至 i=j为止。
基本思想:通过一趟排序,将待排序记录分割成独立
的两部分,其中一部分记录的关键字均比另一部分记
录的关键字小,则可分别对这两部分记录进行排序,
以达到整个序列有序。
排序过程:
对 r[s…… t]中记录进行一趟快速排序,附设两个
指针 i和 j,设枢轴记录 rp=r[s],x=rp.key。初始时
令 i=s,j=t。
再分别对两个子序列进行快速排序,直到每个子序
列只含有一个记录为止 。
数据结构
tjm
例,初始关键字,49 38 65 97 76 13 27 50
i jji
完成一趟排序,( 27 38 13) 49 (76 97 65 50)
分别进行快速排序,( 13) 27 (38) 49 (50 65) 76 (97)
快速排序结束,13 27 38 49 50 65 76 97
4927
i i ji
49 65
j
13 4949 97
i j
算法 参见 P2754,P275
x=49
数据结构
tjm
时间复杂度:
最好情况(每次总是选到中间值作枢轴):
T(n)=O(nlog2n)。
最坏情况(每次总是选到最小或最大元素作枢轴):
T(n)=O(n2)。
算法评价
数据结构
tjm
10.4 选择排序
10.4.1 简单选择排序
首先通过 n-1次关键字比较,从 n个记录中找出关键
字最小的记录,将它与第一个记录交换。
再通过 n-2次比较,从剩余的 n-1个记录中找出关键
字次小的记录,将它与第二个记录交换。
重复上述操作,共进行 n-1趟排序后,排序结束。
算法 参见 P277
排序过程:
例:
初始,[ 49 38 65 97 76 13 27 ]
k
j j j j j j
k k
i=1 13 49
数据结构
tjm
三趟,13 27 [65 97 76 49 38 ]
四趟,13 27 38 [97 76 49 65 ]
五趟,13 27 38 49 [76 97 65 ]
六趟,13 27 38 49 65 [97 76 ]
13 27 38 49 65 76 [97 ]
排序结束,13 27 38 49 65 76 97
二趟,13 [38 65 97 76 49 27 ]i=2
k k
j j j jj
27 38
数据结构
tjm
时间复杂度,T(n)=O(n2)
算法评价
)(21)( 2
1
1
nnin
n
i
????
?
?
比较次数:
记录移动次数
最好情况,0
最坏情况,3(n-1)
数据结构
tjm
或 ( i=1,2,…..,?n/2? )ki?k2i
ki?k2i+1
ki?k2i
ki?k2i+1
例:
( 96,83,27,38,11,9)
例:
( 13,38,27,50,76,65,49,97)
96
27
91138
83
13
2738
49657650
97
可将堆序列看成完全二叉树,则堆顶
元素(完全二叉树的根)必为序列中
n个元素的最小值或最大值
10.4.3 堆排序
堆的定义,n个元素的序列 (k1,k2,……k n),当且仅当
满足下列关系时,称之为堆。
数据结构
tjm
堆排序:将无序序列建成一个堆,得到关键字最小
(或最大)的记录;输出堆顶的最小(大)值后,使
剩余的 n-1个元素重又建成一个堆,则可得到 n个元素
的次小值;重复执行,得到一个有序序列。
堆排序需解决的两个问题:
如何由一个无序序列建成一个堆?
如何在输出堆顶元素之后,调整剩余元素,使之成为
一个新的堆?
第二个问题解决方法 —— 筛选。
方法:输出堆顶元素之后,以堆中最后一个元素替代
之;然后将根结点值与左、右子树的根结点值进行比
较,并与其中小者进行交换;重复上述操作,直至叶
子结点,将得到新的堆,称这个从堆顶至叶子的调整
过程为“筛选”。
算法 参见 P282
数据结构
tjm
例:
13
2738
49657650
97
97
2738
49657650
13
输出,13
27
4938
97657650
13
输出,13
97
4938
27657650
13
输出,13 27
38
4950
27657697
13
输出,13 27
65
4950
27387697
13
输出,13 27 38
数据结构
tjm
49
6550
27387697
13
输出,13 27 38
76
6550
27384997
13
输出,13 27 38 49
50
6576
27384997
13
输出,13 27 38 49
97
6576
27384950
13
输出,13 27 38 49 50
65
9776
27384950
13
输出,13 27 38 49 50
97
6576
27384950
13
输出,13 27 38 49 50 65
数据结构
tjm
76
6597
27384950
13
输出,13 27 38 49 50 65
97
6576
27384950
13
输出,13 27 38 49 50 65 76
97
6576
27384950
13
输出,13 27 38 49 50 65 76 97
数据结构
tjm
例,含 8个元素的无序序列( 49,38,65,97,76,13,
27,50)
49
6538
27137697
50
49
6538
27137650
97
49
1338
27657650
97
49
1338
27657650
97
13
2738
49657650
97
第一个问题的解决方法:从无序序列的第 ?n/2?个元素
(即此无序序列对应的完全二叉树的最后一个非终端结
点)起,至第一个元素止,进行反复筛选。
算法 参见 P282
数据结构
tjm
算法评价
堆排序的时间复杂度为,T(n)=O(nlog2n)。
堆排序是一种不稳定的排序方法 。