排序算法第五讲 --- 希尔排序(Python、C++、C)

排序算法系列目录

  排序算法第一讲 — 冒泡排序(Python、C++、C)
  排序算法第二讲 — 选择排序(Python、C++、C)
  排序算法第三讲 — 插入排序(Python、C++、C)
  排序算法第四讲 — 快速排序(Python、C++、C)
  排序算法第五讲 — 希尔排序(Python、C++、C)
  排序算法第六讲 — 归并排序(Python、C++、C)


题目描述:

给你一个整数数组 nums,请你将该数组采用希尔排序方式进行升序排列。

希尔排序,也称递减增量排序算法,是插入排序的一种更高效的改进版本。但希尔排序是非稳定排序算法。先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序.


解题思路:

让我们先来回顾一下插入排序:

  插入排序顾名思义,就是在排序的过程中,把数组的每一个元素按照大小关系,插入到前面有序区的对应位置。

怎样可以对插入排序算法做出优化呢?从以下两个方面入手:

  1. 在大多数元素已经有序的情况下,插入排序的工作量较小
  2. 在元素数量较少的情况下,插入排序的工作量较小

对原始数组进行预处理,使得大部分元素变得有序。

在这里插入图片描述
  所谓分组,就是让元素两两一组,同组两个元素之间的跨度,都是数组总长度的一半,也就是跨度为4。

在这里插入图片描述
  接下来,我们让每组元素进行独立排序,排序方式用直接插入排序即可。由于每一组的元素数量很少,只有两个,所以插入排序的工作量很少。每组排序完成后的数组如下:

在这里插入图片描述
  这样一来,仅仅经过几次简单的交换,数组整体的有序程度得到了显著提高,使得后续再进行直接插入排序的工作量大大减少。

在这里插入图片描述


代码:

Python写法:

class Solution(object):
    def solution(self,  nums):
        size = len(nums)
        jump = size // 2     # jump 代表每次的间隔
        while jump > 0:
            for i in range(jump, size):
                temp = nums[i]
                j = i - jump # j定位比较的元素
                while nums[j] > temp and j >= 0:
                    nums[j + jump] = nums[j]
                    nums[j] = temp
                    j = j - jump
            jump = jump // 2
        return nums

s = Solution()
nums = [5, 4, 38, 1]
s.solution(nums)
print(s.solution(nums))

C++写法:

#include<iostream>
using namespace std;

int main() {
	int nums[100],size,i,j,jump,temp;
	cin >> size;
	jump = size / 2;

	for(i = 0; i < size; i++){
		cin >> nums[i];
	}

	while (jump > 0){
		for(i = jump; i < size; i++){
			temp = nums[i];
			j = i - jump ;
			while (nums[j] > temp && j >= 0){
				nums[j + jump] = nums[j];
				nums[j] = temp;
				j = j - jump;
			}
		}
		jump = jump / 2;
	}

    for(i = 0; i < size; i++)  //输出排序后的结果
    	cout << nums[i] <<" ";

    cout << "\n";

    return 0;
}

C语言:

#include <stdio.h>

int main() {
	int nums[100],size,i,j,jump,temp;
	scanf("%d\n", &size);
	jump = size / 2;

	for(i = 0; i < size; i++){
		scanf("%d", &nums[i]);
	}

	while (jump > 0){
		for(i = jump; i < size; i++){
			temp = nums[i];
			j = i - jump ;
			while (nums[j] > temp && j >= 0){
				nums[j + jump] = nums[j];
				nums[j] = temp;
				j = j - jump;
			}
		}
		jump = jump / 2;
	}

	for (i = 0; i < size; i++){
		printf("%d ", nums[i]);
	}
	printf("\n");
	return 0;
}

题目来源:

本篇博客所用图片来源于:漫画:什么是希尔排序?


题目来源:

http://lab.youkuaiyun.com/#/question/38?tagId=16

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值