数据结构和算法2:高级排序

本文深入解析了希尔排序、归并排序和快速排序在处理大量数据时的原理和区别,包括希尔排序的Knuth序列优化,归并排序的分治策略与合并操作,以及快速排序的分界值选择和递归过程。讨论了它们在不同场景下的优势和互补性。
摘要由CSDN通过智能技术生成

1 高级排序

排序方法简述
希尔排序间隔分组插入排序
归并排序两个子数组分别有序,依次比较放入新数组
快速排序通过分界值将数组分成左右两部分独立排序
  • 希尔排序和归并排序在处理大批量数据时差别不是很大
  • 快速排序和归并排序是互补的:
    – ① 归并排序将数组分成两个子数组分别排序,并将有序的子数组归并从而将整个数组排序;而快速排序的方式则是当两个数组都有序时,整个数组自然就有序了。
    – ② 在归并排序中,一个数组被等分为两半,归并调用发生在处理整个数组之前;在快速排序中,切分数组的位置取决于数组的内容,递归调用发生在处理整个数组之后。

1.1 希尔排序

public class ShellSort{
	//测试
	public static void main(String[] args){
		int[] arr={9,6,11,3,5,12,8,7,10,15,14,4,1,13,2};
		sort(arr);
		for(int i=0;i<arr.length;i++){
			System.out.print(arr[i]+" ");
		}
	}
	//希尔排序算法
	public static void sort(int[] arr){
		int h=1;
		//Knuth序列,效率比arr.length/2高
		while(h<=arr.length/3){
			h=h*3+1;
		}
		for(int gap=h;gap>0;gap=(gap-1)/3){ 
			for(int i=gap;i<arr.length;i++){
				for(int j=i;j>gap-1;j-=gap){
					if(arr[j]<arr[j-gap]){
						swap(arr,j,j-gap);
					}
				}
			}
		}
	}
	//数组元素i和j交换位置
	public void swap(int[] arr,int i,int j){
		int temp=arr[i];
		arr[i]=arr[j];
		arr[j]=temp;
	}
}

1.2 归并排序

public class MergeSort{
	//测试
	public static void main(String[] args){
		int[] arr={1,4,7,8,3,6,9};
		sort(arr,0,6);
		for(int i=0;i<arr.length;i++){
			System.out.print(arr[i]+" ");
		}
	}
	public static void sort(int[] arr,int left,int right){
		//left最左边,right最右边
		if(left==right) return;
		//分成两半
		int mid=left+(right-left)/2;
		//左边排序
		sort(arr,left,mid);
		//右边排序
		sort(arr,mid+1,right);
		//左右归并
		merge(arr,left,mid+1,right);
	}
	//归并,左右两个子数组已经有序
	static void merge(int[] arr,int leftPtr,int rightPtr,int rightBound){
		int mid=rightPtr-1;
		int[] temp=new int[rightBound-leftPtr+1];

		int i=leftPtr;
		int j=rightPtr;
		int k=0;
		
		while(i<=mid && j<=rightBound){
			if(arr[i]<=arr[j]){
				temp[k++]=arr[i++];
			}else{
				temp[k++]=arr[j++];
			}
		}

		while(i<=mid)
			temp[k++]=arr[i++];
		while(j<=rightBound)
			temp[k++]=arr[j++];

		for(int m=0;m<temp.length;m++)
			arr[leftPtr+m]=temp[m];
	}
	//数组元素i和j交换位置
	static void swap(int[] arr,int i,int j){
		int temp=arr[i];
		arr[i]=arr[j];
		arr[j]=temp;
	}
}

补充:JAVA对象排序

TimSort

  • 混合、稳定高效的排序算法,源自二分插入排序和归并排序
  • 已经排好序的数据块称为“run”,也就是一个个分区,TimSort迭代数据元素,将其放到不同的run里面,同时针对这些run,按规则进行合并至只剩一个,则这个仅剩的 run 即为排好序的结果
  • 简要步骤:根据数列大小产生minrun(划分run的一个条件值)—>依次寻找待排序序列中的run—>合并run

1.3 快速排序

public class Quick{
	//测试
	public static void main(String[] args){
		int[] arr={6, 1, 2, 7, 9, 3, 4, 5, 8};
		sort(arr,0,arr.length-1);
		for(int i=0;i<arr.length;i++){
			System.out.print(arr[i]+" ");
		}
	}
	//快速排序算法
	//对数组内的元素进行排序
	public static void sort(int[] arr,int leftBound,int rightBound){
		if(leftBound>=rightBound) return;
		//对arr数组中,从leftBound到rightBound的元素进行切分
		int mid=partition(arr,leftBound,rightBound);
		//对左边分组中的元素进行排序
		sort(arr,leftBound,mid-1);
		//对右边分组中的元素进行排序
		sort(arr,mid+1,rightBound);
	}
	static int partition(int[] arr,int leftBound,int rightBound){
		int pivot=arr[rightBound];
		int left=leftBound;
		int right=rightBound-1;
		
		while(left<=right){
			while(arr[left]<=pivot)
				left++;
			while(arr[right]>pivot)
				right--;
			if(left<right)
				swap(arr,left,right);
		}
		swap(arr,left,rightBound);
	}
	//数组元素i和j交换位置
	static void swap(int[] arr,int i,int j){
		int temp=arr[i];
		arr[i]=arr[j];
		arr[j]=temp;
	}
}

p.s.
快排改进—>双轴快排(找两个数,三段式less、mid、more)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值