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

来源:互联网 发布:fgo淘宝石头号注意事项 编辑:程序博客网 时间:2024/06/07 04:00

一、 二分搜索

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 stubint 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 aint[] * @param leftint * @param rightint */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 aint[] */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 aint[] * @param bint[] * @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);elsefor (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 qint[] * @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 qint[] * @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 qint[] * @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 stubint 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
原创粉丝点击