《数据结构》希尔排序算法

希尔排序(Shell Sort)是一种改进的插入排序算法,能够提高插入排序的效率。它通过将数组分成若干个子序列,对每个子序列进行插入排序,从而使得数据更加有序。希尔排序的核心思想是通过逐步减少间隔来使得数据元素逐渐接近最终排序状态。

增量设置方案:

                          增量呈递减方式,直至增量为1,一般增\sqrt{}n至1之间。

过程图表:

存储数组:

00

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

84

92

78

67

21

79

23

57

86

32

46

19

22

90

15

69

42

13

47

38

55

34

18

43

26

94

72

62

                      从数组下标0开始,依次增加9 

                      增量 H=9

184 32 47 62 32 47 62 84
292 46 3838 46 92
378 19 55  19 55 78
467 22 3422 34 67
521 90 1818 21 90
679 15 4315 43 79
723 69 2623 26 69
857 42 9442 57 94
986 13 72

13 72 86

                  

00

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

84

92

78

67

21

79

23

57

86

32

46

19

22

90

15

69

42

13

47

38

55

34

18

43

26

94

72

62

H=9

32

38

19

22

18

15

23

42

13

47

46

55

34

21

43

26

57

72

62

92

78

67

90

79

69

94

86

84

                     从数组下标0开始,依次增加5

                     增量 H=5

1

32 15 46 26 78 94

15 26 32 46 78 94

2

38 23 55 57 67 86

23 38 55 57 67 86

3

19 42 34 72 90 84

19 34 42 72 84 90

4

22 13 21 62 79

13 21 22 62 79

5

18 47 43 92 69

18 43 47 69 92

00

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

84

92

78

67

21

79

23

57

86

32

46

19

22

90

15

69

42

13

47

38

55

34

18

43

26

94

72

62

H=9

32

38

19

22

18

15

23

42

13

47

46

55

34

21

43

26

57

72

62

92

78

67

90

79

69

94

86

84

H=5

15

23

19

13

18

26

38

34

21

43

32

55

42

22

47

46

57

72

62

69

78

67

84

79

92

94

86

90

                      从数组下标0开始,依次增加3

                      增量 H=3

115 13 38 43 42 46 62 67 92 90

13 15 38 42 43 46 62 67 90 92

2 23 18 34 32 22 57 69 84 94

18 22 23 32 34 57 69 84 94

3

19 26 21 55 47 72 78 79 86

19 21 26 47 55 72 78 79 86

00

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

84

92

78

67

21

79

23

57

86

32

46

19

22

90

15

69

42

13

47

38

55

34

18

43

26

94

72

62

H=9

32

38

19

22

18

15

23

42

13

47

46

55

34

21

43

26

57

72

62

92

78

67

90

79

69

94

86

84

H=5

15

23

19

13

18

26

38

34

21

43

32

55

42

22

47

46

57

72

62

69

78

67

84

79

92

94

86

90

H=3

13

18

19

15

22

21

38

23

26

42

32

47

43

34

55

46

57

72

62

69

78

67

84

79

90

94

86

92

                      从数组下标0开始,依次增加1

                      增量 H=1

00

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

84

92

78

67

21

79

23

57

86

32

46

19

22

90

15

69

42

13

47

38

55

34

18

43

26

94

72

62

H=9

32

38

19

22

18

15

23

42

13

47

46

55

34

21

43

26

57

72

62

92

78

67

90

79

69

94

86

84

H=5

15

23

19

13

18

26

38

34

21

43

32

55

42

22

47

46

57

72

62

69

78

67

84

79

92

94

86

90

H=3

13

18

19

15

22

21

38

23

26

42

32

47

43

34

55

46

57

72

62

69

78

67

84

79

90

94

86

92

H=1

13

15

18

19

21

22

23

26

32

34

38

42

43

46

47

55

57

62

67

69

72

78

79

84

86

90

92

94

注意:无论增量怎样设置,最后都必须有增量1。

希尔排序代码与直接插入排序代码即为相似。

简易代码描述:

void Shell_sort(int a[],int d[],int n,int t)
{
	int i,j,h,k,x;
	for(h=0;h<t;h++)
	{
		k=d[h];
		for(i=k;i<n;i++)
		{
			x=a[i];
			for(j=i-k;j>=0&&x<a[j];j-=k)
			{
				a[j+k]=a[j];
			}
			a[j+k]=x;
		}
	}
}

代码分析:

  1. 参数说明

    • a[]:待排序数组。
    • d[]:间隔序列。
    • n:数组的长度。
    • t:间隔序列的长度。
  2. 间隔序列的处理

    • 外层循环 for(h=0; h<t; h++) 遍历间隔序列 d[]
    • k = d[h] 获取当前间隔值。
  3. 排序过程

    • 对于每个间隔值 k,从 k 开始,使用插入排序算法对相应的子数组进行排序。
    • x = a[i] 保存当前元素的值。
    • 内层循环 for(j=i-k; j>=0 && x<a[j]; j-=k) 用于查找插入位置并移动元素。
    • a[j+k] = x 将 x 插入到正确的位置。

时间复杂度:

  • 希尔排序的时间复杂度与间隔序列的选择密切相关。最坏情况下,时间复杂度可以达到 (O(n^2)),而最好的情况通常在 (O(n \log n)) 左右。不同的间隔序列能显著影响排序的效率。通过使用希尔排序,可以显著减少插入排序的平均时间复杂度,尤其是对大规模数据集来说。

 

  • 7
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

data_structure_wr

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值