zoukankan      html  css  js  c++  java
  • 递归应用之归并排序

    算法分析
            归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。
    基本思路:
            先递归的把数组划分为两个子数组,一直递归到数组中只有一个元素,然后再调用函数把两个子数组排好序,因为该函数在递归划分数组时会被压入栈,所以这个函数真正的作用是对两个有序的子数组进行排序;
    基本步骤:
            1、判断参数的有效性,也就是递归的出口;
            2、首先什么都不管,直接把数组平分成两个子数组;
            3、递归调用划分数组函数,最后划分到数组中只有一个元素,这也意味着数组是有序的了;
            4、然后调用排序函数,把两个有序的数组合并成一个有序的数组;

            5、排序函数的步骤,让两个数组的元素进行比较,把大的/小的元素存放到临时数组中,如果有一个数组的元素被取光了,那就直接把另一数组的元素放到临时数组中,然后把临时数组中的元素都复制到实际的数组中;

    示例代码:

    public class GuibingSort {
    	//first数组初始索引值,mid数组分界点索引,last数组结束索引,temp[]临时数组
    	//以mid为界限,将a分为两个数组,对其进行归并排序
    	//将二个有序数列合并。这个非常简单,只要从比较二个数列的第一个数,
    	//谁小就先取谁,取了后就在对应数列中取下一个数。然后再进行比较,
    	//如果有数列遍历完毕,那直接将另一个数列的数据依次取出即可。
    	void mergearray(int a[], int first, int mid, int last, int temp[])
    	{//两个有序数组的归并
    		int i = first,m = mid;//第一个数组的范围
    		int j = mid + 1,n = last;//第二个数组的范围
    		int k = 0;//temp的初始下标
    		
    		while (i <= m && j <= n)//分别从两个数组中取值
    		{
    			if (a[i] <= a[j])//取较小的数放到temp数组中
    				temp[k++] = a[i++];//先进行赋值运算,然后k,i自加1
    			//注意,这里j并没有变化,下一次比较仍然是上一次的j值,直到else发生
    			else
    				temp[k++] = a[j++];//j变化,i不变化
    		}
    		
    		while (i <= m)//如果数组中仍有元素,直接复制到temp后面即可
    			temp[k++] = a[i++];
    		
    		while (j <= n)
    			temp[k++] = a[j++];
    		
    		for (i = 0; i < k; i++)//将排好序的数组重新赋给a
    			a[first + i] = temp[i];
    	}
    	void mergesort(int a[], int first, int last, int temp[])
    	//a[]是需要排序的数组,first, last是索引范围
    	{
    		if (first < last)//当数组中只有一个元素时,first==last,递归结束
    		{
    			int mid = (first + last) / 2;
    			mergesort(a, first, mid, temp);    //左边递归,直到只剩一个元素
    			mergesort(a, mid + 1, last, temp); //右边递归,直到只剩一个元素
    			mergearray(a, first, mid, last, temp); //再将二个有序数列合并
    		}
    	}
    	public void sort(int[] a) {
    		int n=a.length;
    		int[] b=new int[n];
    		mergesort(a, 0, n-1, b);
    	}
    public static void main(String[] args) {
    	int[] a= {10,9,8,7,6,5,4,3};
    	GuibingSort guibingSort=new GuibingSort();
    	guibingSort.sort(a);
    	for (int i : a) {
    		System.out.println(i);
    	}
    }
    }
    运行过程解释:

    第一次归并10和9,排序结果9,10

    第二次归并8和7,排序结果7,8

    第三次归并9,10和7,8,,排序结果7,8,9,10

    对于6,5,4,3排序过程与上述类似,排序结果为3,4,5,6

    最后归并两大部分,得到最终结果。

  • 相关阅读:
    INTERVAL YEAR TO MONTH数据类型
    Oracle 中DATE类型的计算
    Oracle中特殊的变量类型
    Webview窗口设置遮罩层
    mui.init方法配置
    mui.fire()触发自定义事件
    管理员启动程序的命令
    收藏网址
    html标签
    Event对象和触发
  • 原文地址:https://www.cnblogs.com/kangsir/p/6653283.html
Copyright © 2011-2022 走看看