阿布学排序之希尔排序

package com.abuge;
/**
 * 希尔排序:
 * 实质:分组插入排序,又称为缩小增量排序
 * 思想:
 * 先将整个待排元素序列分割成若干个子序列(由相隔某个"增量"的元素组成的)分别进行直接插入排序,待整个序列中的元素基本有序(增量足够小)时,再对全体元素进行直接插入排序。
 * 因为直接插入排序是在基本有序的情况下(接近最好情况)效率是很高的。
 * 第一种方法(把一组元素从开始比较到最后)
 * 步骤:
 * 1、设定分组增量初值,即为gap = n/2(n为元素个数),则每次以gap = gap / 2循环
 * 2、按组排序即0-> gap-> gap + gap->...
 * 			 1-> 1 + gap->...
 * 			 .
 * 			 .
 * 			 .
 * 			gap-1 -> gap + gap - 1->...
 * 3、如果后面的比前面的小,则交换顺序(升序排列)
 * 4、循环交换到0位置或者比要比较元素小的元素时,将元素放在其后
 * 
 * 
 * 第二种方法(从第gap个元素开始,每个元素与自己组内的元素进行比较,交替进行)
 * 步骤:
 * 1、设定分组增量初值,即为gap = n/2(n为元素个数),则每次以gap = gap / 2循环
 * 2、从gap开始,进行组内比较,如果与同组元素的前一个无须交换,则比较下一组,从而实现了交替比较
 * 3、比较过程中如果后面的比前面的小,则交换顺序(升序排列)
 * 4、循环交换到0位置或者比要比较元素小的元素时,将元素放在其后
 * 
 * 
 * 第三种方法(从第gap个元素开始,每个元素与自己组内前面的元素进行比较,交替进行)
 * 步骤:
 * 1、设定分组增量初值,即为gap = n/2(n为元素个数),则每次以gap = gap / 2循环
 * 2、从gap开始,进行组内比较,如果与同组元素的前一个无须交换,则比较下一组,从而实现了交替比较
 * 3、交换符合条件的元素
 * @author AbuGe
 *
 */
public class ShellSort
{
	//第一种方法
	public static void shellSort_1(int[] a, int n)
	{
		//设定循环变量,和步进增量
		int i;
		int j;
		int gap;
		for(gap = n / 2; gap > 0; gap = gap / 2)//设定步进增量
		{
			for(i = 0; i < gap; i++)//按组排序
			{
				for(j = i + gap; j < n; j = j + gap)
				{
					if(a[j] < a[j - gap])
					{
						int tmp = a[j];
						int k = j - gap;
						//循环比较
						while(k >= 0 && a[k] > tmp)
						{
							a[k + gap] = a[k];
							k -= gap;
						}
						a[k + gap] = tmp;
					}
				}
			}
		}
	}
	
	//第二种方法
	public static void shellSort_2(int[] a, int n)
	{
		//设定循环变量,和步进增量
		int i;
		int gap;
		for(gap = n / 2; gap > 0; gap = gap / 2)//设定步进增量
		{
			for(i = gap; i < n; i++)//循环增量为1,而第一个循环增量为gap
			{
				if(a[i] < a[i - gap])
				{
					int tmp = a[i];
					int k = i - gap;
					while(k >= 0 && a[k] > tmp)
					{
						a[k + gap] = a[k];
						k -= gap;
					}
					a[k + gap] = tmp;
				}
			}
		}
	}
	//第三种方法
	public static void shellSort_3(int[] a, int n)
	{
		//设定循环变量,和步进增量
		int i;
		int j;
		int gap;
		for(gap = n / 2; gap > 0; gap = gap / 2)//设定步进增量
		{
			for(i = gap; i < n; i++)//循环增量为1,而第一个循环增量为gap
			{
				for(j = i - gap; j >= 0 && a[j] > a[j + gap]; j-= gap)
				{
					swap(a, j, j + gap);
				}
			}
		}
	}
	public static void swap(int[]a , int x, int y)
	{
		int tmp = a[x];
		a[x] = a[y];
		a[y] = tmp;
	}
	public static void main(String[] args)
	{
		int[] a = {1, 13 , 11, 10, 6, 5,  8, 7};
		int n = a.length;
		System.out.print("排序前:");
		for(int i : a)
		{
			System.out.print(i + " ");
		}
		System.out.println();
		//shellSort_1(a, n);
		//shellSort_2(a, n);
		shellSort_3(a, n);
		
		System.out.print("排序后:");
		for(int i : a)
		{
			System.out.print(i + " ");
		}
	}
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值