归并算法(非递归版)

归并算法(非递归版)

用二叉堆排序的概念,自底向上,分层排序。缺点是不直观,理解有困难,算法较复杂。

算法

def merge_sort_norecurse(array) :
    j = 1;
    while j < array.length :
        i = 1;
        // 最右侧节点的左子序列,其最后一个元素的下标应小于数组长度
        while i + j - 1 < n :
            合并两个有序列,下标分为,i,i+1,...i+j-1和i+j,i+j+1,...min(i+2j-1,n)  
            i += 2j; //横向以纵向步长的2倍进行跳跃
        end while
        j *= 2; //纵向以2的幂次方步长跳跃

合并算法

def merge_array(data, work, start, mid, end) :
    midStart = mid + 1;
    int memoryStart = start;
    index = 0;
    // 合并
    while start <= mid 且 midStart <= end :
        work[index++] = data[start] <= data[midStart] ?
                        data[start++]:data[midStart++]; 
    end while

    // 合并未进行排序的数据
    while start <= mid :
        work[index++] = data[start++];
    end while
    while midStart <= end :
        work[index++] = data[midStart++];
    end while

    index--;
    while index >= 0 :
        data[memoryStart + index] = work[index--];
    end while 

算法测试

import java.util.Arrays;

public class Test {

    public static void main(String[] args) {
        int[] a = { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
        merge_sort(a, new int[a.length]);
        System.out.println(Arrays.toString(a));

    }

    // 归并排序(非递归版)
    private static void merge_sort(int[] data, int work[]) {
        int n = data.length;

        int j = 1; // 二叉堆的纵向光标,从1开始
        int i = 0; // 二叉堆的横行光标,从0开始
        while (j < n) {
            i = 0;
            // 横向跳跃到最后左侧子序列,其值应小于数组的最大下标
            while (i + j < n) {
                // 二叉堆的同层子序列中,除最后一个子序列,其他子序列长度为j
                // 最后一个子序列长度为j或者j-1,因此merge_array()函数最后一个参数
                // 选用小值
                merge_array(data, work, i,  i + j - 1, Math.min(i + 2 * j - 1, n - 1));
                i += 2 * j; //横向起始位置以纵向步长的2倍跳动
            }
            j *= 2; // 纵向以2的幂次方的步长跳动
        }

    }

    // 合并两个有序列
    /**
     * 将数组data中待合并处理的数据,按序整理好放入work中, 在将work中数据放回data相应位置
     * 
     * @param data
     *            待进行合并处理的数组
     * @param work
     *            用于存储合并处理数据的数组
     * @param low
     *            data数组中,需要合并处理的左端起始下标
     * @param mid
     *            data数组中,需要合并处理的左端终点下标
     * @param high
     *            data数组中,需要合并处理的右端终点下标
     */
    private static void merge_array(int[] data, int[] work, int low, int mid, int high) {
        int index = 0;
        int lowRight = mid + 1; // 右端起始下标
        int i = 0;
        int memoryStart = low;

        // 排序
        while (low <= mid && lowRight <= high) {
            if (data[low] <= data[lowRight]) {
                work[index++] = data[low++];
            } else {
                work[index++] = data[lowRight++];
            }
        }

        // 未进行比较数据置入直接work中
        while (low <= mid) {
            work[index++] = data[low++];
        }
        while (lowRight <= high) {
            work[index++] = data[lowRight++];
        }

        // 处理好的数据返回给data
        index--;
        while (index >= 0) {
            data[memoryStart + index] = work[index--];
        }
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值