Shell、归并排序、递归的java实现

Shell、归并排序、递归的java实现

 

        摘要:上篇笔记记述了四个排序:插入排序、快速排序、冒泡排序、选择排序、本篇主要记录两个:shell排序——对插入排序的改进、归并排序。同样是从思想、算法实现和java代码的实现来研究、顺道补充了点递归的东西。


一:Shell排序


        1、基本思想:

 

              Shell排序(希尔排序)是对插入排序的一种改进、也称“缩小增量排序”。他是按照一个选取的缩小增量值n将要排序的数组中元素下标相差n和n的倍数的所有元素分成n组、分别对n组元素进行插入排序、完成后按上述规则再细分n1组、n1<n、再排序、直到nx = 1、直接对这一组进行插入排序、实现Shell排序、从上边的步骤也可以看出Shell排序是对插入排序的一种改进。

       

         2、算法原理:


              a) 取数组长度的一半step=a.length/2 作为缩小增量、

              b) 将数组分成 step组、

              c)分别对每组进行插入排序。

              d) 将step组中每组再以缩小增量step = step/2分组、重复步骤c。

              e) 重复步骤c、d直到step=1、对这一组元素进行插入排序。over!


        3、java实现:

 

package com.chy.arithmetic;

import java.util.Arrays;

public class ShellSort {
	private static int ia[] = { 1, 54, 6, 3, 78, 34, 12, 45, 56, 3 };

	private static int[] shellSort(int[] a) {
		//the increment;
		int step = a.length / 2;
		
		// The result has mostly sorted at the previous step of step=1;
		//Just change the condition step> = 1 to step > 1 if you want to observe it ;
		while (step >= 1) {
			
			for (int i = step; i < a.length; i++) {
				int temp = a[i];
				int j;
				
				// use insert sort to sort the part of a;
				for (j = i - step; j >= 0 && a[j] > temp; j -= step) {
					a[j + step] = a[j];
				}
				a[j + step] = temp;
			}
			//narrow the increment.
			step = step / 2;
		}
		return a;
	}


	public static void main(String[] args) {
		System.out.println(Arrays.toString(shellSort(ia)));
	}
}

 

二:归并排序

 

        1、基本思想:

 

                归并(Merge排序是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个有序的子序列(一般分解到原子级),再把有序的子序列合并为整体有序序列。

 

       2、算法原理:

 

            分解操作:

 

                a)  申请两个空间、分别存放原来序列的一半(不是严格意义上的一半、如果元素个数是奇数、则有一方会多一个元素)。

                b)  使用中间变量 center= a.length/2划分序列

                c)  分别填充第一步申请的两个空间

                d)  递归的形式细分填充上一步划分的两个空间、直到所有空间只放一个元素。

                e)  进行归并操作

                f)  重复上述步骤、直到所有空间合并成一个有序序列。

 

              归并操作:

 

                a)申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列

                b)设定两个指针,最初位置分别为两个已经排序序列的起始位置

                c)比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指

                d)针到下一位置

                e)重复步骤3直到某一指针达到序列尾

                f)将另一序列剩下的所有元素直接复制到合并序列尾

 

3、java实现:

 

package com.chy.arithmetic;

import java.util.Arrays;

public class MergeSort {

	public static void main(String[] args) {
		int[] array = { 3, 2, 1, 8, 5, 7, 9, 4, 6 };
		System.out.println(Arrays.toString(mergeSort(array)));
	}

	private static int[] mergeSort(int[] a) {
		if (a.length == 1) {
			return a;
		}

		int[] aL = new int[a.length / 2];
		int[] aR = new int[a.length - a.length / 2];
		int center = a.length / 2;
		for (int i = 0; i < center; i++) {
			aL[i] = a[i];
		}
		for (int i = center, j = 0; i < a.length; i++, j++) {
			aR[j] = a[i];
		}
		int[] sortedAL = mergeSort(aL);
		int[] sortedAR = mergeSort(aR);
		int[] as = mergeTwoArray(sortedAL, sortedAR);
		return as;
	}

	private static int[] mergeTwoArray(int[] aL, int[] aR) {
		int i = 0;
		int j = 0;
		int[] a = new int[aL.length + aR.length];
		int foot = 0;
		while (i < aL.length && j < aR.length) {
			if (aL[i] < aR[j]) {
				a[foot++] = aL[i++];
			} else {
				a[foot++] = aR[j++];
			}
		}

		if (i == aL.length) {
			while (j < aR.length) {
				a[foot++] = aR[j++];
			}
		} else {
			while (i < aL.length) {
				a[foot++] = aL[i++];
			}
		}
		return a;
	}
}

三:递归

 

      1、基本思想:

              递归在开发中是非常常见的一种算法、比如罗列某个指定文件夹下所有的文件名、因为有可能有层层文件、所以我们可以使用递归来实现。

思想:对于一个复杂的问题,把原问题分解为若干个相对简单类同的子问题,继续下去直到子问题简单到能够直接求解,也就是说到了递推的出口,这样原问题就有递推得解。 

              最能说明递归思想的是:Febonacci数列——看代码。

              递归最重要的是1、范围要越来越小。2、是要找到出口、也就是结束条件。

 

      2、java实现:


package com.chy.arithmetic;

import java.io.File;

public class RecursiveAlgorithm {
	
	public static void main(String[] args) {
		System.out.println(getFibonacciValue(10));
		getAllFiles("D:\\upload");
	}

	/**
	 * to obtain the specified index of a Fibonacci's value
	 */
	private static long getFibonacciValue(int index) {
		if (index == 1 || index == 2) {
			return 1;
		} else {
			return getFibonacciValue(index - 1) + getFibonacciValue(index - 2);
		}

	}
	
	/**
	 * to obtain all files in a specified directory
	 */
	private static void getAllFiles(String filePath){
		File file = new File(filePath);
		if(!file.isDirectory()){
			System.out.println(file.getAbsolutePath());
		}else{
			File[] fileList = file.listFiles();
			for(File fileDetail : fileList){
				if(!fileDetail.isDirectory()){
					System.out.println(fileDetail.getAbsolutePath());
				}else{
					getAllFiles(fileDetail.getAbsolutePath());
				}
			}
		}
	}
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值