插入排序和迭代归并排序以及复杂度分析

引言: 算法是计算机科学中的基础,程序=算法+数据结构,算法描述了我们将如何来处理数据的过程。本文将介绍两种算法的实现以及其中一种算法的复杂度分析过程。

1.  算法介绍

  归并排序是利用归并思想对数列进行排序,核心点是将数组进行分组拆分,拆分到最小单元之时,即为有序;然后进行分组数据的归并排序合并,从而达到排序的目的。

  插入排序是将元素插入到某个有序数组之中,并保持原有数据的有序性,以此类推来解决数据排序的问题。

2. 算法实现

   插入排序是在这里的实现是从有序数组的最后一个元素来进行比较和插入,当然这里也可以从第一个元素来进行比较和插入操作。

   归并元素是基于2分法来进行分拆、排序归并的。

  代码如下:

import java.util.Arrays;

public class SortWays {

	/**
	 * direction:  
	 * 
	 * @param data
	 * @param direction 0: ascendent, 1: descendent
	 * @return
	 */
	public static int[] insertSort(int[] data, int direction) {
		if (data == null || data.length == 0) return new int[]{};
		
		for (int j=1; j<data.length; j++) {
			int key = data[j];
			int i = j -1;
			
			while ((i>=0)) {
				if ((data[i] > key) && (direction == 0)) {
					   data[i+1] = data[i];
				     i--;  //auto decrease
				}
				else if ((data[i]<key) &&(direction == 1)) {
					data[i+1] = data[i];
					i--;  //auto decrease
				}
				else {
					break;
				}
			}
			data[i+1] = key;
		}
		
		return data;
	}
	
	public static void mergeSort(int[] data, int startIndex, int endIndex) {
		if (startIndex < endIndex) {
			int splitIndex = (int)Math.floor((startIndex+endIndex)/2);
			mergeSort(data, startIndex, splitIndex);
			mergeSort(data, splitIndex+1, endIndex);
			
			merge(data, startIndex, splitIndex, endIndex);
		}
	}
	
	/**
	 * merge method body.
	 * 
	 * @param data
	 * @param startIndex
	 * @param splitIndex
	 * @param endIndex
	 */
	private static void merge(int[] data, int startIndex, int splitIndex, int endIndex) {
		int[] tmp = new int[endIndex - startIndex+1]; //临时区域
		
		int i = startIndex; // first area index
		int j = splitIndex +1; //second area index
		int k = 0;    // temporary area index
		
		while (i<= splitIndex && j <= endIndex) {
			//System.out.println("splitIndex/i/endIndx/j:" + splitIndex + "/" + i + "/" + endIndex + "/" + j);
			
			if (data[i] > data[j]) 
				tmp[k++] = data[j++];
			else 
				tmp[k++] = data[i++];
		}
		
		while (i<=splitIndex) {
			tmp[k++] = data[i++];
		}
		
		while(j<=endIndex) {
			tmp[k++] = data[j++];
		}
		
		for (int c=0; c<k; c++) 
			data[startIndex+c] = tmp[c];
		
		tmp = null;
	}
	
	public static void main(String[] args) {
		int[] rawdata = new int[]{7,2, 3,  5, 1, 8, 4, 6};
		
		//int[] data = SortWays.insertSort(rawdata, 0);
		
		SortWays.mergeSort(rawdata, 0, rawdata.length-1);
		System.out.println("Array Data:" + Arrays.toString(rawdata));
	}

}
  在插入排序中, direction方向表示: 0为顺序排序,1: 降序排序。

  在归并排序中,注意mergeSort的输入参数中最后一个参数为最后一个元素的位置,而非数组长度;比如这里实际的位置为7, 而非长度8.

3.  迭代归并排序的复杂度分析

   关于插入排序的复杂度分析, 我们基于其伪代码实现来进行分析:

    

  其运行的总时间为:

   

其在最坏情况下的总时间为:

   

      总时间为 N*N的正相关关系, 故其消耗时间为:

       

       故这里的插入算法的复杂度为O(n*n),至于其他的n和常量都在复杂度的级别上进行忽略。

 对于合并排序的算法复杂度分析,递归算法的时间复杂度公式为:

     n<<c,c为某个常量值之时,则问题规模足够小,可以直接求出其解所需时间,为O(1). T(n) = O(1)

     其他情况下,

             T(n) = aT(n/b) + D(n)+C(n)

  其中,a为分解的问题个数,T(n/b)为单个被分级的问题规模所需时间,二分法情况下为 a=b=2;但是大部分情况下,a并不等于b

         D(n):将问题分解为子问题所需时间

        C(n): 将子问题的解合并为原问题的解所需要的时间

   对于归并排序的算法而言:

              n = 1 ==> T(n) = O(1)= c [c为常量,固定时间]

              n>1 => T(n)=2T(n/2) + O(n) = 2T(n/2) + cn  

                  [c为常数, n为元素数量正相关的元素]

     我们将递归算法分解为以下图中所示的层次关系:

         

  

   

从上图可知,整个递归树的层次为lgn+1层,每层的时间消耗为cn,故整体的时间消耗为: cnlgn + cn = cn(lgn+1)  ~~~ O(nlgn)

   故迭代归并的时间复杂度为 O(nlgn)

4.总结

  对于各个算法的复杂度分析一般会分为最坏情况,最好情况和平均情况,在这里只是使用了最坏情况下的分析,这些数据方便我们了解各个算法在不同情况下的资源和时间消耗,这里并未涉及空间复杂度的讨论,主要是由于资源空间消耗不大,故没有讨论。

5. 参考资料

  •   归并排序  http://www.cnblogs.com/skywang12345/p/3602369.html
  •   插入排序  http://blog.csdn.net/cjf_iceking/article/details/7916194
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
算法赏析》课程介绍 “软件 = 算法 + 数据结构”,算法是软件的灵魂。在信息时代,计算思维是分析复杂工程问题的重要思维方式,计算机则是求解问题的重要工具。本课程以计算机经典问题求解为导向,通用算法思维和自动编程流程图培养为目标,引入经典算法,精心安排课程的理论教学和编程实践。本课程学习将有助于学员提高计算思维能力及算法思维的能力。 本课程主要讲授计算机问题求解的经典算法设计方法和算法复杂度分析方法,主要内容包括计算机概述、计算机系统的组成、信息化及指标体系、操作系统、程序设计语言、算法简介、数的表示及存储、数据结构简介及顺序结构和选择结构、循环结构、循环的嵌套、算法复杂度分析,枚举算法,递归与分治策略,递归与迭代的思想、求最大值最小值、线性查找、二分查找与冒泡排序以及选择与交换排序、插入和希尔排序。本课程除了强调经典的算法理论和模型,亦兼顾编程实践能力。力图使得学员面对复杂问题时,既能“想到”还能“做到”。 授课目标 培养算法思维,掌握枚举算法、分治策略、递归与迭代、选择与交换排序等经典算法模型; 培养实践能力,掌握在存储空间和时间开销受限情况下的程序设计方法; 培养理论思维,掌握复杂问题的算法设计与分析方法。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值