分治法之排序及二分查找
一、目的
- 了解分治法思想;
- 掌握递归算法的思想与程序编写;
- 熟练使用二分查找法实现代码编写。
- 熟练使用合并排序、快速排序实现代码编写
二、题目
-
n个数的全排列问题。
-
给定由 n 个整数(可能为负整数)组成的序列,求解其连续的最大字段和。当所有数都是负整数时,最大字段和是 0 . 如:a[] = {-2, 11, -4, 13, -5, -2}时, max = 11 + (-4) + 13 = 20.。
-
给定一个随机数数组,求取这个数组中的逆序对总个数。要求时间效率尽可能高。
-
设b[0:n-1]为数组,数组中含有n个数,参照课本2.7,试设计一个消去递归的合并排序算法。
三、解体思路及步骤
Q1:n个数全排列问题
public class test01 {
public static void main(String[] args) {
int n;
Scanner scanner = new Scanner(System.in);
n = scanner.nextInt();
int arr[] = new int[n+1];
for(int i=0;i<=n;i++)
arr[i] = i;
perm(arr, 1,n);
}
public static void perm(int arr[],int begin,int n) {
if(begin==arr.length) {
for(int i=1;i<=n;i++) {
System.out.print(arr[i]+" ");
}
System.out.println();
}
for(int i=begin;i<arr.length;i++) {
int t = arr[i];
arr[i] = arr[begin];
arr[begin] = t;
perm(arr, begin+1,n);
t = arr[i];
arr[i] = arr[begin];
arr[begin] = t;
}
}
}
运行结果
Q2:给定由 n 个整数(可能为负整数)组成的序列,求解其连续的最大字段和。当所有数都是负整数时,最大字段和是 0 . 如:a[] = {-2, 11, -4, 13, -5, -2}时, max = 11 + (-4) + 13 = 20.
public class test02 {
public static void main(String[] args) {
int [] a = {-2, 11, -4, 13, -5, -2};
int n = a.length;
int sum=maxSub(a,n) ;
System.out.println(sum);
}
public static int maxSub(int []arr,int n){
int maxEnd = arr[0];
int maxSum = arr[0];
for (int i = 0; i <n; i++) {
maxEnd = max(arr[i],maxEnd+arr[i]);
maxSum = max(maxSum,maxEnd);
}
return maxSum;
}
public static int max(int a,int b ){
if (a<b){
return b;
}else {return a;}
}
}
运行结果
Q3:给定一个随机数数组,求取这个数组中的逆序对总个数。要求时间效率尽可能高。
import java.util.Scanner;
public class test03 {
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
System.out.println("请输入您的数组");
String str = sc.next();
String [] s1 = str.split("");
int length =str.length();
int[] arr = new int[length];
for (int i = 0; i <length; i++) {
arr[i] = Integer.parseInt(s1[i]);
}
int a=findCouple(arr);
System.out.println("该数组中含有逆序对的个数总共为:"+a);
}
public static int findCouple(int[] arr){
if(arr==null||arr.length==0){return -1;}
int len=arr.length;
int sum=0;
int[] a = new int[len];
for(int i=0;i<len;i++){
int count=0;
for(int j=i+1;j<len;j++){
if(arr[i]>arr[j])
count++;
}
a[i]=count;
}
for(int k=0;k<len;k++){
sum+=a[k];
}
return sum;
}
}
Q4: 设b[0:n-1]为数组,数组中含有n个数,试设计一个消去递归的合并排序算法。
package day03;
import java.util.*;
public class test05{
public static void mergeSort(Comparable[] a) {
Comparable[] b = new Comparable[a.length];
int s = 1;
while (s < a.length) {
mergePass(a, b, s);
s += s;
mergePass(b, a, s);
s += s;
}
System.out.println(Arrays.toString(a));
}
public static void mergePass(Comparable[] x, Comparable[] y, int s) {
int i = 0;
while (i <= x.length - 2 * s) {
merge(x, y, i, i + s - 1, i + 2 * s - 1);
i = i + 2 * s;
}
if (i + s < x.length) {
merge(x, y, i, i + s - 1, x.length - 1);
} else {
for (int j = i; j < x.length; j++) {
y[j] = x[j];
}
}
}
public static void merge(Comparable[] a, Comparable[] b, int m, int n, int r) {
int i = m, j = n + 1, k = m;
while ((i <= n) && (j <= r)) {
while ((i <= n) && (j <= r)) {
if (a[i].compareTo(a[j]) <= 0) {
b[k++] = a[i++];
} else {
b[k++] = a[j++];
}
}
if (i > n) {
for (int q = j; q <= r; q++) {
b[k++] = a[q];
}
} else {
for (int q = i; q <= n; q++) {
b[k++] = a[q];
}
}
}
}
public static void main(String[] args) {
Comparable[] a = {8, 7, 2, 4, 5, 1, 9, 3};
System.out.print(Arrays.toString(a));
System.out.println();
mergeSort(a);
}
}
运行结果