您的位置:首页 > 其它

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

2015-06-28 16:39 429 查看

一、 二分搜索

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、结果:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息