您的位置:首页 > 其它

插入排序、合并排序、堆排序和快速排序

2014-12-14 18:08 295 查看
插入排序、合并排序、堆排序和快速排序
http://www.cnblogs.com/yshb/archive/2012/07/23/2605026.html[code]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;
}

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