JavaSwing的归并排序动画

一年前写的JavaSwing排序动画JavaSwing排序动画,当时由于自己对归并排序理解不深,一直认为归并排序需要额外的数组空间,那时候一直想写出归并排序动画,可惜一直没成功,后来放弃了。

就在昨天翻看算法导论时,看到了归并排序的伪代码,突然迸发出灵感,这个算法也许可以让以前排序动画里的归并排序跑起来。

归并排序算法如下:

private static void mergeSort(int[] data, int start,  int end){
		if(start < end){
			int mid = (start + end) / 2;
			mergeSort(data, start, mid);
			mergeSort(data, mid + 1, end);
			merge(data, start, mid, end);
		}
	}

	private static void merge(int[] data, int start, int mid, int end){
		int capacity1 = mid - start + 1;
		int capacity2 = end - mid;
		int dataRight[] = new int[capacity1 + 1];
		int dataLeft[] = new int[capacity2 + 1];
		int i, j = 0;
		
		for(i = 0; i < capacity1; i++){
			dataRight[i] = data[start + i];
		}
		dataRight[i] = 10000;   // 哨兵值,取一个比数据里面任何一个数都大的值
		
		for(j = 0; j < capacity2; j++){
			dataLeft[j] = data[mid + j + 1];
		}
		dataLeft[j] = 10000;   // 哨兵值,取一个比数据里面任何一个数都大的值
		
		int indexA = 0;
		int indexB = 0;
		
		// notice the ArrayIndexOutofBounds, first we must check the indexA and indexB
		try{
			for(int k = start; k < end + 1; k++){
				if(dataRight[indexA] <= dataLeft[indexB] ){
					data[k] = dataRight[indexA];
					mergeHistogram.showHistogram(data, k);
					Thread.sleep(20);
					indexA++;
				}
				else if(dataRight[indexA] > dataLeft[indexB]){
					data[k] = dataLeft[indexB];
					mergeHistogram.showHistogram(data, k);
					Thread.sleep(20);
					indexB++;
				}
			}
			mergeHistogram.showHistogram(data);
		}catch(InterruptedException ex){
			ex.printStackTrace();
		}
	}

为什么哨兵值要取一个比排序数据都大的数,为什么声明的dataRight,dataLeft数组长度要比capacity大1

一切都是为了下面的归并过程

for(int k = start; k < end + 1; k++){
				if(dataRight[indexA] <= dataLeft[indexB] ){
					data[k] = dataRight[indexA];
					mergeHistogram.showHistogram(data, k);
					Thread.sleep(20);
					indexA++;
				}
				else if(dataRight[indexA] > dataLeft[indexB]){
					data[k] = dataLeft[indexB];
					mergeHistogram.showHistogram(data, k);
					Thread.sleep(20);
					indexB++;
				}
			}

如果dataRight和dataLeft的长度是capacity的话,if(dataRight[indexA] <= dataLeft[indexB] )这句话总会越界一次而且只会越界一次,每次运行都会抛出异常,所以我们声明数组长度是capacity+1,尽管最后一个数据没用到,但是我们可以通过最后一个哨兵最大值比较,归并过程是把两个有序数组的元素按照从小到大的顺序归并成一个有序的数组,所以当for循环从start迭代到end + 1后,就停止迭代,此时的哨兵值也不会被归并进来,从而不影响排序结果,又能很容易地回避数组越界问题

运行效果如图:



源代码下载地址归并排序动画源代码

可运行jar下载地址归并排序可运行jar

视频地址归并排序动画视频

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值