import java.util.Random;
/**
* 排序算法大全
* @use
* @author tanyouhao
* @date 2013-3-14 上午9:49:42
* @version 1.0
*
*/
public class test {
static int m=0;
public static void main(String args[]) {
bubbleSort(new test().createArray(), "asec");
System.out.println("冒泡排序一共比较多少次:"+m);
selectSort(new test().createArray());
insertSort(new test().createArray());
reverse(new test().createArray());
int[] a = new test().createArray();
fastSort(a, 0, a.length - 1);
System.out.println("快速:");
printArray(a);
System.out.println("二分查找前:");
printArray(a);
int positon = binarySearch(a, a[3], 0, a.length - 1);
System.out.println(a[3] + "的位置在:" + positon);
}
// 创建一个原始序列
public int[] createArray() {
Random random = new Random();
int[] array = new int[10];
for (int i = 0; i < 10; i++) {
array[i] = random.nextInt(100) - random.nextInt(100);// 生成两个随机数相剑
}
System.out.println("=======原始数组======");
printArray(array);
return array;
}
// 打印数组
public static void printArray(int[] data) {
for (int i : data) {
System.out.print(i + " ");
}
System.out.println();
}
// 交换数组中两个元素的位置
public static void swap(int[] data, int x, int y) {
int temp = data[x];
data[x] = data[y];
data[y] = temp;
}
/**
* 冒泡排序
*
* @param data
* 序列
* @param sortType
* asec dsec 升序或者降序 时间复杂度是:n^2
*/
public static void bubbleSort(int[] data, String sortType) {// 是两个两个比较
if (sortType.equals("asec")) {// 升序
for (int i = 1; i < data.length; i++) {
for (int j = 0; j < data.length - i; j++) {
m++;
if (data[j] < data[j + 1]) {
swap(data, j, j + 1);
}
}
}
} else if (sortType.equals("desc")) {// 降序
} else {
System.out.println("排序类型不对");
}
System.out.println("冒泡排序后的数组");
printArray(data);// 打印输出
}
/**
* 直接选择排序
*
* 直接选择排序的基本思想 n个记录的文件的直接选择排序可经过n-1趟直接选择排序得到有序结果: ①初始状态:无序区为R[1..n],有序区为空。
* ②第1趟排序 在无序区R[1..n]中选出关键字最小的记录R[k],将它与无序区的第1个记录R[1]交换,
* 使R[1..1]和R[2..n]分别变为记录个数增加1个的新有序区和记录个数减少1个的新无序区。 …… ③第i趟排序
* 第i趟排序开始时,当前有序区和无序区分别为R[1..i-1]和R[i..n](1≤i≤n-1)
* 。该趟排序从当前无序区中选出关键字最小的记录R[k],将它与无序区的第1个记录R[i]交换
* ,使R[1..i]和R[i+1..n]分别变为记录个数增加1个的新有序区和记录个数减少1个的新无序区。
* 这样,n个记录的文件的直接选择排序可经过n-1趟直接选择排序得到有序结果。
*
*
*
* @param data
* 序列 默认从小到大排序
*/
public static void selectSort(int[] data) {// 每一次选取最小的进行交换
for (int i = 0; i < data.length; i++) {
for (int j = i; j < data.length; j++) {
if (data[i] > data[j]) {
swap(data, i, j);
}
}
}
System.out.println("直接选择排序");
printArray(data);
}
/**
* 直接插入排序 假设待排序的记录存放在数组R[1..n]中。初始时,R[1]自成1个有序区,无序区为R[2..n]。
* 从i=2起直至i=n为止,依次将R[i]插入当前的有序区R[1..i-1]中,生成含n个记录的有序区。
*
*
* @param data
* 默认为升序排列
*/
public static void insertSort(int[] data) {// 每次选取一个数值和原来已经有顺序的进行比较
for (int i = 0; i < data.length; i++) {
for (int j = 0; j < i; j++) {
if (data[i] < data[j]) {
swap(data, i, j);
}
}
}
System.out.println("直接插入");
printArray(data);
}
/**
* 翻转数组
*
* @param data
*/
public static void reverse(int[] data) {
int length = data.length;
int temp = 0;// 临时变量
for (int i = 0; i < length / 2; i++) {
temp = data[i];
data[i] = data[length - 1 - i];
data[length - 1 - i] = temp;
}
System.out.println("反转数组后");
printArray(data);
}
/**
* 快速排序 时间复杂度是o(Nlogn)
*
* 快速排序(Quicksort)是对冒泡排序的一种改进。由C. A. R. Hoare在1962年提出。
* 它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分, 其中一部分的所有数据都比另外一部分的所有数据都要小,
* 然后再按此方法对这两部分数据分别进行快速排序, 整个排序过程可以递归进行,以此达到整个数据变成有序序列。
*
*
* @param data
*
*/
public static void fastSort(int[] data, int low, int high) {
int i, j, x;
if (low < high) {
i = low;
j = high;
x = data[i];
while (i < j) {
while (i < j && data[j] > x) {
j--;
}
if (i < j) {
data[i] = data[j];
i++;
}
while (i < j && data[i] < x) {
i++;
}
if (i < j) {
data[j] = data[i];
j--;
}
}
data[i] = x;
fastSort(data, low, j - 1);
fastSort(data, i + 1, high);
}
}
/**
* 二分查找 基数的时候 a[length%2] 偶数的时候 有两个中间a[length%2] 和a[length%2-1]
*
* @param data
* @return
*/
public static int binarySearch(int[] data, int date, int begin, int end) {
int mid = (begin + end) / 2;
if (data[mid] > date) {
return binarySearch(data, date, begin, mid - 1);
} else if (data[mid] < date) {
return binarySearch(data, date, mid + 1, end);
} else {
return mid;
}
}
/**
* 希尔排序
*
* 属于插入类排序,是将整个无序列分割成若干小的子序列分别进行插入排序
* 排序过程:先取一个正整数d1<n,把所有序号相隔d1的数组元素放一组,组内进行直接插入排序
* ;然后取d2<d1,重复上述分组和排序操作;直至di=1,即所有记录放进一个组中排序为止 初始:d=5 49 38 65 97 76 13
* 27 49 55 04 49 13 |-------------------| 38 27
* |-------------------| 65 49* |-------------------| 97 55
* |-------------------| 76 04 |-------------------|
* 一趟结果 13 27
* 49* 55 04 49 38 65 97 76
* d=3 13 27 49* 55 04 49 38 65 97 76 13 55
* 38 76 |------------|------------|------------| 27 04 65
* |------------|------------| 49* 49 97 |------------|------------|
*
* 二趟结果 13 04 49* 38 27 49 55 65 97 76
* d=1 13 04 49* 38 27 49 55 65
* 97 76 |----|----|----|----|----|----|----|----|----|
*
* 三趟结果 04 13 27
* 38 49 49 55 65 76 97
*/
public static void ShellSort(int[] a, int n) {
int temp, i, j, d;
for (d = n / 2; d > 0; d /= 2)
for (i = d; i < n; i++) {
temp = a[i];
j = i;
while (j >= d && temp < a[j - d]) {
a[j] = a[j - d];
j -= d;
}
a[j] = temp;
}
test.printArray(a);
}
}
执行结果:
=======原始数组======
32 28 15 -52 -51 9 19 -26 -50 45
冒泡排序后的数组
45 32 28 19 15 9 -26 -50 -51 -52
冒泡排序一共比较多少次:45
=======原始数组======
50 62 12 67 93 -62 -38 -24 20 -6
直接选择排序
-62 -38 -24 -6 12 20 50 62 67 93
=======原始数组======
-39 -18 1 1 -51 28 -19 42 27 10
直接插入
-51 -39 -19 -18 1 1 10 27 28 42
=======原始数组======
-15 -2 -18 -1 61 15 -61 -10 19 33
反转数组后
33 19 -10 -61 15 61 -1 -18 -2 -15
=======原始数组======
-52 -30 -5 15 3 -48 20 18 -17 -45
快速:
-52 -48 -45 -30 -17 -5 3 15 18 20
二分查找前:
-52 -48 -45 -30 -17 -5 3 15 18 20
-30的位置在:3