Java数组排序(递归版&非递归)

归并排序(递归)

public class Test {
    public void mergeSort(int[] nums, int low, int high)
    {
        if (low >= high)    return;
        int mid = low + ((high - low) >> 1);
        mergeSort(nums, low, mid);
        mergeSort(nums, mid + 1, high);
        merge(nums, low, mid, high);
    }
    private void merge(int[] nums, int low, int mid, int high)
    {
        int[] temp = Arrays.copyOfRange(nums, low, high + 1);
        int n1 = low, n2 = mid + 1, index = low;
        while (n1 <= mid && n2 <= high)
        {
            if (temp[n1 - low] <= temp[n2 - low])
            {
                nums[index] = temp[n1 - low];
                n1++;
            }
            else
            {
                nums[index] = temp[n2 - low];
                n2++;
            }
            index++;
        }

        while (n1 <= mid)
        {
            nums[index] = temp[n1 - low];
            index++;
            n1++;
        }
        /*while (n2 <= high)
        {
            nums[index] = temp[n2 - low];
            index++;
            n2++;
        }这里可以去掉,因为第二段数组内容已经提前拷贝过去了*/
    }

	public static void main(String[] args){
        int[] nums = new int[]{1,3,1,3,2,4,5,8,9,4,5,6,1,4,1,9,8,4,8,6,1,1,6,1,2,5,6,1,4,5,8,4,1};
        new Test().mergeSort(nums, 0, nums.length - 1);
        for (int num : nums)
        {
            System.out.printf("%d ", num);
        }
	}
}

关键点在于merge的时候要开一个辅助数组用于存储归并结果,也可以直接拷贝原始数组的那一段,参照拷贝后的数组对原始数组进行归并。

归并排序(非递归)

public class Test {
    private int[] nums;
    private int[] buffer;
	public static void main(String[] args){
        int[] test = new int[]{15,6,1,5,6,8,1,4,5,6,13,2,4,7,8,1,46,5,1,3,249,86,136,4,613,24,9,84,16,5,15,6,132};
        new Test(test).mergeSort();
        for (int num : test)
        {
            System.out.print(num + " ");
        }
    }

    public Test(int[] nums)
    {
        this.nums = nums;
        this.buffer = new int[nums.length];
    }

    private void mergeSort()
    {
        int size = 1;
        while (size <= nums.length)
        {
            for (int i = 0;i + size <= nums.length;i += (size << 1))
            {   //保证至少划分一块
                int low = i, mid = i + size - 1;
                int high = Math.min(i + (size << 1) - 1, nums.length - 1);
                //保证第二块的下标正确
                merge(low, mid, high);
            }
            size <<= 1;
        }
    }

    private void merge(int low, int mid, int high)
    {
        System.arraycopy(nums, low, buffer, low, high - low + 1);
        int index1 = low, index2 = mid + 1;
        int index = low;
        while (index1 <= mid && index2 <= high)
        {
            if (buffer[index1] <= buffer[index2])
            {
                nums[index] = buffer[index1];
                index1++;
            }
            else
            {
                nums[index] = buffer[index2];
                index2++;
            }
            index++;
        }

        while (index1 <= mid)
        {
            nums[index] = buffer[index1];
            index1++;
            index++;
        }
    }
}

堆排序(非优先队列)

public class Test {
    private final int[] nums;
	public static void main(String[] args){
        int[] test = new int[]{15,6,1,5,6,8,1,4,5,6,13,2,4,7,8,1,46,5,1,3,249,86,136,4,613,24,9,84,16,5,15,6,132};
        new Test(test).heapSort();
        for (int num : test)
        {
            System.out.print(num + " ");
        }
    }

    public Test(int[] nums)
    {
        this.nums = nums;
    }

    private void heapSort()
    {
        for (int i = ((nums.length >> 1) - 1);i >= 0;i--)
        {
            adjustHeap(i, nums.length - 1);
        }//从第一个非叶节点开始

        for (int i = nums.length - 1;i > 0;i--)
        {
            swap(0, i);
            adjustHeap(0, i - 1);
            //规模减小1个节点
        }
    }

    private void swap(int indexA, int indexB)
    {
        int temp = nums[indexA];
        nums[indexA] = nums[indexB];
        nums[indexB] = temp;
    }

    private void adjustHeap(int low, int high)
    {
        int temp = nums[low];//保存父亲节点以备交换
        for (int i = ((low << 1) + 1);i <= high;i = ((i << 1) + 1))
        {
            if (i + 1 <= high && nums[i] < nums[i + 1]) i++;
            //比较左右子节点
            if (temp > nums[i]) break;
            //如果后续节点已经合法,则不再调整
            nums[low] = nums[i];
            //直接赋值
            low = i;
            //接着调整后续子节点
        }
        nums[low] = temp;
        //最后完成交换
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值