【算法导论——java实例代码】第2章

归并排序算法
public class MergeSort {
    static int[] s = {2, 1, 10, 20, 3 ,2, 44, 23, 7, 6, 84, 100};
    static int mergeCalledCounter;
    private static void merge(int[] a, int p, int q, int r) {        
        if (p < 0 || r > a.length-1) {
            System.out.println("wrong parameters");
            return;
        }
        int n1 = q-p+1;
        int n2 = r-q;
        int i = 0, j = 0;
        int[] left = new int[n1+1];
        int[] right = new int[n2+1];
        for (; i<n1; i++) {
            left[i] = a[p+i];
        }
        for (; j<n2; j++) {
            right[j] = a[q+j+1];
        }
        // 这里使用了哨兵,可以换另一种不用哨兵的方式,如当left或right有一方
        // 已经遍历到尽头时,直接将另一方剩余的数组元素直接复制到a对应的位置。
        left[i] = Integer.MAX_VALUE;
        right[j] = Integer.MAX_VALUE;
        i = j = 0;        
        for (int k = p; k < r+1; k++) {
            if (left[i] < right[j]) {
                a[k] = left[i];
                i++;
            } else {
                a[k] = right[j];
                j++;
            }
        }        
        System.out.println("merge counter: " + (++mergeCalledCounter));
        printArray(s);
    }
    static void mergeSort(int[] a, int p, int r) {
        if (p < r) {
            int q;
            if ((p+r)%2 != 0) {
                q = (p+r-1)/2;
            } else {
                q = (p+r)/2;
            }
            mergeSort(a, p, q);
            mergeSort(a, (q+1), r);
            merge(a, p, q, r);
        }
    }   
    private static void printArray(int[] array) {
        for (int i = 0; i < array.length; i++) {
            System.out.print(array[i] + " ");
        }    
        System.out.println();
    }   
    public static void main(String[] args) {
        printArray(s);
        mergeSort(s, 0, s.length-1);
    }   
}

运行结果:

2 1 10 20 3 2 44 23 7 6 84 100

merge counter: 1

1 2 10 20 3 2 44 23 7 6 84 100
merge counter: 2
1 2 10 20 3 2 44 23 7 6 84 100
merge counter: 3
1 2 10 3 20 2 44 23 7 6 84 100
merge counter: 4
1 2 10 2 3 20 44 23 7 6 84 100
merge counter: 5
1 2 2 3 10 20 44 23 7 6 84 100
merge counter: 6
1 2 2 3 10 20 23 44 7 6 84 100
merge counter: 7
1 2 2 3 10 20 7 23 44 6 84 100
merge counter: 8
1 2 2 3 10 20 7 23 44 6 84 100
merge counter: 9
1 2 2 3 10 20 7 23 44 6 84 100
merge counter: 10
1 2 2 3 10 20 6 7 23 44 84 100
merge counter: 11
1 2 2 3 6 7 10 20 23 44 84 100

课后习题2.3-7

描述一个运行时间为Θ(nlgn)的算法,给定n个整数的集合S和另一个整数x,该算法能确定S中是否存在两个其和刚好为x的元素。

伪代码

1: 先用归并排序算法将集合S排好序,其运行时间 Θ(n lg(n))
2: i = 1
3: j = n
4: while i < j do
5:     if A[i] + A[j] = x then
6:         return true
7:     end if
8:     else if A[i] + A[j] < x then
9:         i = i + 1
10:   end else if
11:   else A[i] + A[j] > x then
12:        j = j - 1
13:   end else
14: end while
15: return false

第2-15步的运行时间为O(n) ,相对于Θ(n lg(n)),O(n)可被忽略,所以整个算法的运行时间为Θ(n lg(n))

java代码
public class Test_2_3_7 {
        public static void main(String[] args) {
        int[] s = {10,3,4,2,5,9,4,7,6,8};
        final int bingo = 15;
        int i = 0;
        int j = s.length - 1;
        int tmpSum;
        s = MergeSort.mergeSort(s, i, j); // 运用归并排序算法将数组s中的元素从小到大排序
        while (i < j) {
            tmpSum = s[i] + s[j];
            if (tmpSum == bingo) {
                System.out.println("i:" + i + " | j:" + j);
                System.out.println("s[i]:"+s[i] + " | " + "s[j]:"+s[j]);
                return;
            } else if (tmpSum < bingo) {
                i++;
            } else {
                j--;
            }
        }
        System.out.println("can't find i and j");
    }
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值