插入排序、合并排序、堆排序和快速排序
http://www.cnblogs.com/yshb/archive/2012/07/23/2605026.html
package ch02;
import java.util.Random;
public class Test {
/**
* 插入排序 时间复杂度O(n2)
*
* @param array原地排序算法
*/
public void insertSort(int[] array) {
for (int i = 1; i < array.length; i++) {
int present = array[i];
int position = i;
while (position > 0 && array[position - 1] > present) {// 右移
array[position] = array[position - 1];
position--;
}
array[position] = present;
}
}
/**
* 合并排序 O(nlogn)
*
* @param array
* @param left
* 第一个索引
* @param right
* 最后一个索引
*/
public void mergeSort(int[] array, int left, int right) {
if (left < right) {
int middle = (left + right) / 2;
mergeSort(array, left, middle);
mergeSort(array, middle + 1, right);
merge(array, left, middle, right);
}
}
public void merge(int[] array, int left, int middle, int right) {
int[] array1 = new int[middle - left + 1];
int[] array2 = new int[right - middle];
for (int i = 0; i < array1.length; i++) {
array1[i] = array[left + i];
}
for (int i = 0; i < array2.length; i++) {
array2[i] = array[middle + i + 1];
}
int l = 0, r = 0, k = left;
for (; k <= right && l < array1.length && r < array2.length; k++) {
if (array1[l] > array2[r]) {
array[k] = array2[r];
r++;
} else {
array[k] = array1[l];
l++;
}
}
while (l < array1.length) {
array[k] = array1[l];
l++;
k++;
}
while (r < array2.length) {
array[k] = array2[r];
r++;
k++;
}
}
/**
* 堆排序 原地排序且O(nlogn)
*
* @param array
*/
public void heapSort(int[] array) {
buildHeap(array);
for (int i = array.length - 1; i > 0; i--) {
int k = array[0];
array[0] = array[i];
array[i] = k;
heapify(array, 0, i);
}
}
/**
* 构建最大堆
*
* @param array
*/
public void buildHeap(int[] array) {
for (int i = array.length / 2 - 1; i > -1; i--) {
heapify(array, i, array.length);
}
}
/**
*
* @param array
* 数组
* @param index
* 数组中的索引
* @param length
* 树中元素个数
*/
public void heapify(int[] array, int index, int length) {
int present = index;// 当前索引
int value = array[index];
int largest = array[index];
int largest_index = index;
while ((2 * present + 1) < length) {// 判断是否有儿子
if (array[2 * present + 1] > largest) {
largest = array[2 * present + 1];
largest_index = 2 * present + 1;
}
if ((2 * present + 2) < length && array[2 * present + 2] > largest) {
largest = array[2 * present + 2];
largest_index = 2 * present + 2;
}
if (largest_index != present) {
array[present] = largest;
present = largest_index;
largest = value;
} else {
break;
}
}
array[present] = value;
}
/**
* 最坏时间O(n2)----在数组已经排好序时发生 O(nlogn)
*
* @param array
* @param p
* @param r
*/
public void quickSort(int[] array, int p, int r) {
if (p < r) {
int q = partition(array, p, r);
quickSort(array, p, q - 1);
quickSort(array, q + 1, r);
}
}
public int partition(int[] array, int p, int r) {
Random random = new Random();
exchange(array, r, random.nextInt(r - p + 1) + p);// 随机取数
int x = array[r];
int i = p - 1;
for (int j = p; j < r; j++) {
if (array[j] <= x) {
i = i + 1;
exchange(array, i, j);
}
}
exchange(array, i + 1, r);
return i + 1;
}
public void exchange(int[] array, int p, int q) {
int k = array[p];
array[p] = array[q];
array[q] = k;
}
}
package ch02;
import java.util.Random;
/**
* 最大子序列和问题的几种算法
* @author Administrator
*
*/
public class MaxSequenceSumTest {
/**
* @param args
*/
public static void main(String[] args) {
int[] array = new int[10000000];
Random r = new Random(100);
for (int i = 0; i < array.length; i++) {
int k = r.nextInt(20);
if (k % 2 == 0)
array[i] = 0 - k;
else
array[i] = k;
// System.out.print(array[i]+" ");
}
// System.out.println();
// maxSum1(array);
// maxSum2(array);
// maxSum3(array);
long start = System.currentTimeMillis();
int sum = maxSum4(array, 0, array.length - 1);
long end = System.currentTimeMillis();
System.out.print("最大子序列的和为:" + sum + "--------花费时间:");
System.out.println((end - start) / 1000 + "秒" + (end - start) % 1000
+ "毫秒");
maxSum5(array);
}
/**
* f(n)=f(n-1)+f(n-2) f(n)=1 n<=1
*/
public static void f(int n) {
long[] array = new long[n + 1];
array[0] = 1;
array[1] = 1;
array[2] = 2;
for (int i = 3; i < n + 1; i++) {
array[i] = array[i - 1] + array[i - 2];
}
for (int i = 0; i < n + 1; i++) {
System.out.println("i=" + i + "---------- " + array[i]);
}
}
public static int maxSum1(int[] array) {
long start = System.currentTimeMillis();
int sum = 0;
for (int i = 0; i < array.length; i++) {
for (int j = i + 1; j < array.length; j++) {
int s = array[i];
for (int k = i + 1; k <= j; k++) {
s = s + array[k];
}
if (s > sum)
sum = s;
}
}
long end = System.currentTimeMillis();
System.out.print("最大子序列的和为:" + sum + "--------花费时间:");
System.out.println((end - start) / 1000 + "秒" + (end - start) % 1000
+ "毫秒");
return sum;
}
/**
* 时间减半而已
*
* @param array
* @return
*/
public static int maxSum2(int[] array) {
int sum = 0;
long start = System.currentTimeMillis();
for (int i = 0; i < array.length; i++) {
for (int j = i + 1; j < array.length; j++) {
if (array[i] < 0)
break;
int s = array[i];
for (int k = i + 1; k <= j; k++) {
s = s + array[k];
}
if (s > sum)
sum = s;
}
}
long end = System.currentTimeMillis();
System.out.print("最大子序列的和为:" + sum + "--------花费时间:");
System.out.println((end - start) / 1000 + "秒" + (end - start) % 1000
+ "毫秒");
return sum;
}
/**
* 少一重循环
*
* @param array
* @return
*/
public static int maxSum3(int[] array) {
long start = System.currentTimeMillis();
int sum = 0;
for (int i = 0; i < array.length; i++) {
int s = array[i];
for (int j = i + 1; j < array.length; j++) {
s = s + array[j];
if (s > sum)
sum = s;
}
}
long end = System.currentTimeMillis();
System.out.print("最大子序列的和为:" + sum + "--------花费时间:");
System.out.println((end - start) / 1000 + "秒" + (end - start) % 1000
+ "毫秒");
return sum;
}
/**
* O(NlogN)时间复杂度 分治策略: 分:把问题分成两个大致相等的子问题,然后递归地对他们求解
* 治:将两个子问题的解修补到一起并可能再做些少量的附加工作,最后得到整个问题的解
*
* @param array
* @param left
* @param right
* @return
*/
public static int maxSum4(int[] array, int left, int right) {
if (left == right)
if (array[left] > 0)
return array[left];
else
return 0;
int middle = (left + right) / 2;
int lMax = maxSum4(array, left, middle);
int rMax = maxSum4(array, middle + 1, right);
int a = 0;
int aMax = 0;
for (int i = middle; i >= left; i--) {
a = a + array[i];
if (a > aMax)
aMax = a;
}
int b = 0;
int bMax = 0;
for (int i = middle + 1; i < right; i++) {
b = b + array[i];
if (b > bMax)
bMax = b;
}
return Math.max(Math.max(lMax, rMax), aMax + bMax);
}
/**
* 如果a[i]小于零,那么它不可能代表最优序列的起点,因为任何包含a[i]的作为起点的子序列都可以通过
* 用a[i+1]作为起点而得到改进。同理,任何小于零的子序列不可能是最优子序列的前缀。
*
* @param array
* @return
*/
public static int maxSum5(int[] array) {
long start = System.currentTimeMillis();
int maxSum = 0, thisSum = 0;
for (int i = 0; i < array.length; i++) {
thisSum = thisSum + array[i];
if (thisSum > maxSum) {
maxSum = thisSum;
} else if (thisSum < 0) {
thisSum = 0;
}
}
long end = System.currentTimeMillis();
System.out.print("最大子序列的和为:" + maxSum + "--------花费时间:");
System.out.println((end - start) / 1000 + "秒" + (end - start) % 1000
+ "毫秒");
return maxSum;
}
}