排序(四):堆排序,归并排序

一:堆排序:

有一说一,这个堆排序看了别人的思路看了有一会儿才懂,不搞清楚顺序这个是真的麻烦。

了解完代码后,给我最直接的感觉就是从局部到整体,整个堆排序的核心无疑就是在heapSortPart里面了。这里贴上别人给的解释:堆排序——Java实现 - Lvan灬 - 博客园 (cnblogs.com)

假如有5个节点,此时最后一个非叶子节点即为5/2-1=1,从这个节点使用heapSortPart,这一小部分就排好了(堆的顺序),之后的进展都建立在前面堆已经排好的情况下。

 //tempChild那里用了++,因为要比较父母节点的左右子节点谁更大,更大的在之后的操作中变成堆顶。
	 public void heapSortPart(int startIndex,int Length) {//对堆进行部分调整。startIndex是开始索引,Length是待排序列尾元素索引(你就简单想成总长度)
		 DataArrayNode tempNode = data[startIndex];//存储初始节点,最后会使用到这个tempNode。
		 int parentIndex = startIndex;
		 int Lchild,Rchild;
		 int tempKey = data[startIndex].key;
		 for(Lchild = parentIndex*2+1;Lchild<Length;Lchild = Lchild*2+1) {
			 Rchild = Lchild + 1;
			 if(Rchild < Length&&data[Rchild].key>data[Lchild].key) {//Rchild在Length范围内,且key值大于Lchild处key值。
				 Lchild++;
			 }
			 
			 //这里起初是data[parentIndex].key,但是因为parentIndex可能会一变,可能不再是原来的key,所以改为tempKey即正确。
			 if(tempKey >= data[Lchild].key) {//如果父节点大于子节点的值
				 break;//中断循环。
			 }else {
				 data[parentIndex] = data[Lchild];
				 parentIndex = Lchild;//将Lchild作为全新的parentIndex继续进行。
			 }
		 }//从下到上,从右往左。在当前的地方进行排序的话,它的左右肯定已经排好了序,此时比较这个parent和左右孩子,再使用这里的for循环就可以不断实现顺序排列。
		 data[parentIndex] = tempNode;
	 }//key是key,位置是位置。。。
	 
	 public void heapSort() {
		 DataArrayNode tempNode;
		 for(int i =data.length/2-1;i>=0;i--) {//从最后一个非叶子节点开始循环。
			 heapSortPart(i,data.length);//
		 }//初始化堆
		 
		 for(int i = data.length-1;i>0;i--) {
			 tempNode = data[i];
			 data[i] = data[0];
			 data[0] = tempNode;//因为最后一个最后会被舍弃掉,所以后面的依旧满足堆的定义,是堆有序的。
			 heapSortPart(0,i);//调整堆状态。
		 }
	 }
	 
	 

二:归并排序:

先拆分最后归并,按照顺序就比如先左后右,依次递归

Java实现归并排序 - 心中的山水 - 博客园 (cnblogs.com)

 public void merge(int a[],int left,int mid,int right) {//将分开的分别有序的数组合并
		 int[] temp =new int[right-left+1];
		 int tempLeft = left;
		 int tempMid = mid+1;
		 int k = 0;
		 while(tempLeft<=mid&&tempMid<=right) {
			 if(a[tempLeft]<=a[tempMid]) {
				 temp[k++] = a[tempLeft++];
			 }
			 else {
				 temp[k++] = a[tempMid++];
			 }
		 }//这样之后,最后只会剩下大的那一边
		 while(tempLeft<=mid) {
			 temp[k++] = a[tempLeft++];
		 }
		 while(tempMid<=right) {
			 temp[k++] = a[tempMid++];
		 }
		 for(int i = 0;i<temp.length;i++) {
			 a[i+left] = temp[i];
		 }
	 }
	 
	 public void mergeSort(int a[],int left,int right) {
		 if(left>=right) return;
		 else {
			 int mid = (left+right)/2;
			 mergeSort(a,left,mid);
			 mergeSort(a,mid+1,right);
			 merge(a,left,mid,right);
		 }
		 
	 }
	 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值