算法小白总结(四)-----分治法之排序问题

一、 二分搜索

1、 问题描述:

在一排序好n个元素中寻找特定元素x例:在排序好的int型数组a中查询元素5是否存在。

2、基本思想:

n个元素分成个数大致相同的两半,并不断分治,最终找到结果。


3、java实现: 

public class BinarySearch {
	/**
	 * 在已排序数组a中查找元素x;
	 * @param a	数组
	 * @param x	特定元素
	 * @return x存在则返回其索引,否则返回-1
	 */
	public static int binarySearch(int []a, int x){
		int n = a.length;
		int left = 0,right = n-1;
		while(left <= right){
			int middle=(left+right)/2;
			if(x==a[middle]) return middle;
			if(x>a[middle]) left = middle+1;
			else right = middle -1;
		}
		return -1;
	}
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int a[] = {1,2,3,4,5,6,7,8};
		int f = binarySearch(a, 5);
		if(f == -1)
			System.out.println("该元素不存在");
		else 
			System.out.println("该元素索引为"+ f +"值为:"+a[f]);
	}
}


二、合并排序

1、问题描述:

n个无序元素进行排序。

2、基本思想:

将待排序的元素大致分为数量相等的两个子集合,分别对两个子集合进行排序,最终将排序好的子集合并。

3、java实现:

public class MergeSort {
	private static int[] b;
	
	/**
	 * 递归合并排序数组a从a[left]:a[right]
	 * @param a	int[]
	 * @param left	int
	 * @param right	int
	 */
	public static void mergeSort(int[] a, int left, int right){
		if(left >= right) return ;
		int mid = (left+right)/2;
		mergeSort(a, left, mid);
		mergeSort(a, mid+1, right);
		merge(a, b, left, mid, right);
		copy(a, b, left, right);
	}
	
	/**
	 * 非递归合并排序数组a
	 * @param a	int[]
	 */
	public static void mergeSort(int[] a){
		int[] b = new int[a.length];
		int s=1;
		while(s<a.length){
			mergePass(a,b,s);
			s += s;
			mergePass(b,a,s);
			s += s;
		}
	}
	
	/**
	 * 通过数组b,合并排序数组a中相邻大小为s的数组即a[0:s-1]:a[s:2*s-1]合并排序
	 * @param a	int[]
	 * @param b	int[]
	 * @param s int
	 */
	public static void mergePass(int[] a, int[] b, int s){
		int i=0;
		while(i<=a.length-2*s){
			merge(a,b,i,i+s-1,i+2*s-1);
			i = i+2*s;
		}
		if(i+s<a.length)
			merge(a, b, i, i+s-1, a.length-1);
		else
			for (int j = 1; j < a.length; j++) {
				b[j] = a[j];
			}
	}
	
	/**
	 * 将a[left:mid],c[mid+1:right]合并到b[left:right]
	 * @param a
	 * @param b
	 * @param left
	 * @param mid
	 * @param right
	 */
	public static void merge(int[] a, int[] b,int left, int mid, int right){
		int i=left, j=mid+1, k=left;
		while(i<=mid && j<=right)
			if(a[i] <= a[j])
				b[k++] = a[i++];
			else 
				b[k++] = a[j++];
		if(i>mid)
			for(int q=j; q<=right; q++)
				b[k++] = a[q];
		else 
			for(int q=i; q<=mid; q++)
				b[k++] = a[q];			
	}
	
	/**
	 * 将b[left:right]复制到a[left:right]
	 * @param a
	 * @param b
	 * @param left
	 * @param right
	 */
	public static void copy(int[] a,int[] b, int left, int right){
		for(int i=left; i<=right; i++)
			a[i] = b[i];
	}
	
	public static void main(String[] args) {			
		int a[] = {1,15,14,12,9,8,13,11};
		int a1[] = a;
		System.out.print("     初始状态:     ");
		for(int i=0; i<a.length; i++)
			System.out.print(a[i]+" ");
		System.out.println();
		
		System.out.print("  递归排序结果: ");
		MergeSort.b = new int[a.length];
		MergeSort.mergeSort(a, 0, a.length-1);
		for(int i=0; i<a.length; i++)
			System.out.print(a[i]+" ");
		System.out.println();
		
		MergeSort.mergeSort(a1);
		System.out.print("非递归排序结果:");
		MergeSort.b = new int[a.length];
		MergeSort.mergeSort(a1, 0, a1.length-1);
		for(int i=0; i<a1.length; i++)
			System.out.print(a1[i]+" ");
		System.out.println();
	}
}

4、结果



三、快速排序

1、问题描述:

n个元素进行排序。

2、基本思想:

首先,找出中间点x;然后,把小于x的元素放在x左边,大于x的元素放在x右边;最后,分别对左半段、右半段快速排序。

3、java实现:

<span style="font-weight: normal;">public class QuiteSort {
	/**
	 * 快速排序数组q[left:right]
	 * @param q	int[]
	 * @param left int
	 * @param right int 
	 */
	public static void quiteSort(int[]q, int left, int right){
		if(left<right){
			int mid = quite(q,left,right);
			quiteSort(q, left, mid-1);
			quiteSort(q, mid+1, right);
		}
	}
	
	/**
	 * 将数组q中小于中位数mid的元素放在左半段,大于mid的放在右半段。
	 * @param q	int[]
	 * @param left int
	 * @param right int
	 * @return 中位数min的索引
	 */
	public static int quite(int[] q, int left, int right){
		int mid = q[left];
		int l=left,r=right+1;
		while(true){
			while(q[++l]<mid && l<right);
			while(q[--r]>mid);
			if(l>=r) break;
			swap(q, l, r);			
		}
		q[left] = q[r];
		q[r] = mid;	
		return r;
	}
	
	/**
	 * 交换数组q中q[i],q[j]
	 * @param q	int[]
	 * @param i int
	 * @param j int
	 */
	public static void swap(int[] q,int i,int j){
		int mid = q[i];
		q[i] = q[j];
		q[j] = mid;
	}
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int a[] = {1,15,14,12,9,8,13,11};
		QuiteSort.quiteSort(a, 0, 7);
		System.out.print("快速排序结果:");
		for(int i=0; i<a.length; i++)
			System.out.print(a[i]+" ");
	}
}</span>


4、结果:



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值