台哥算法练习:数组排序的几种算法
2009年的9月份,每天啃一本厚厚的数据结构,把几乎所有的算法和数据结构都亲手实现了一遍。
归并排序和快速排序,理解了以后,别的排序就是小菜一碟了。。
package suanfa;
/**
* 常见的数组排序方法
* @author 台哥彩铃
*
* 针对int类型的数组arr,进行排序
*/
public class Paixu {
/**
* 交换排序 :比较次数和交换次数都很大
* @param arr :待排序的数组
*/
public void px_jiaohuan(int[] arr) {
for (int i = 0; i < arr.length - 1; i++) {
for (int j = i + 1; j < arr.length; j++) {
if (arr[j] < arr[i]) {
this.jiaohuan(arr, i, j);
}
}
}
}
/**
* 选择排序 :可以看做是改进后的交换排序,比较次数很大,交换次数很小。
*/
public void px_xuanze(int[] arr) {
int k;
for (int i = 0; i < arr.length - 1; i++) {
k = i;
for (int j = i + 1; j < arr.length; j++) {
if (arr[j] < arr[k]) {
k = j;
}
}
if (i != k) {
this.jiaohuan(arr, i, k);
}
}
}
/**
* 冒泡排序
*
* 比较次数很大,交换次数小于交换排序 。
* 适用于(2,1,4,3,6,5,8,7)这样数列的排序。
*/
public void px_maopao(int[] arr) {
for (int i = 0; i < arr.length - 1; i++) {
for (int j = 0; j < arr.length - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
this.jiaohuan(arr, j, j + 1);
}
}
}
}
/**
* 插入排序
* 最好的二次排序方法。
* 尤其适用于很多元素已排好顺序的情况。
*/
public void px_charu(int[] arr) {
for (int i = 1; i < arr.length; i++) {
int k = i;
for (int j = i - 1; j >= 0; j--) {
if (arr[k] < arr[j]) {
this.jiaohuan(arr, k, j);
k--;
} else {
break;
}
}
}
}
/**
* 归并排序
*/
public void px_guibing(int[] arr) {
int[] tempArr = arr.clone();
msort(arr, tempArr, 0, arr.length - 1);
}
private void msort(int[] arr, int[] tempArr, int first, int last) {
if (first < last) {
int midpt = (first + last) / 2;
msort(arr, tempArr, first, midpt);
msort(arr, tempArr, midpt + 1, last);
int a = first;
int b = midpt + 1;
for (int i = first; i <= last; i++) {
if (a > midpt) {
tempArr[i] = arr[b];
b++;
continue;
}
if (b > last) {
tempArr[i] = arr[a];
a++;
continue;
}
if (arr[a] <= arr[b]) {
tempArr[i] = arr[a];
a++;
} else {
tempArr[i] = arr[b];
b++;
}
}
for (int j = first; j <= last; j++) {
arr[j] = tempArr[j];
}
}
}
/**
* 快速排序
* @param arr
*/
public void px_kuaisu(int[] arr) {
this.ksort(arr, 0, arr.length - 1);
}
private void ksort(int[] arr, int first, int last) {
if (last > first) {
int midpt = (first + last) / 2;
this.jiaohuan(arr, first, midpt);
int a = first + 1, b = last;
while (a <= b) {
if (arr[a] < arr[first]) {
a++;
} else {
if (arr[b] < arr[first]) {
this.jiaohuan(arr, a, b);
a++;
}
b--;
}
}
this.jiaohuan(arr, first, b);
ksort(arr, first, b - 1);
ksort(arr, b + 1, last);
}
}
// 交换数组的两个元素
private void jiaohuan(int[] arr, int i, int j) {
int hi = arr[i];
arr[i] = arr[j];
arr[j] = hi;
}
// 顺序打印数组
public void print(int[] arr) {
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
System.out.println();
}
public static void main(String[] args) {
int[] arr = new int[] { 12, 144, 313, 23, 22, 66, 43, 6, 55, 18, 77, 29, 36, 2, 5};
Paixu tai = new Paixu();
System.out.println("排序前");
tai.print(arr);
long start = System.nanoTime();
System.out.println(start);
/***** 交换排序 ******/
// tai.px_jiaohuan(arr);
/***** 选择排序 ******/
// tai.px_xuanze(arr);
/***** 冒泡排序 ******/
// tai.px_maopao(arr);
/***** 插入排序 ******/
// tai.px_charu(arr);
/***** 归并排序 ******/
// tai.px_guibing(arr);
/***** 快速排序 ******/
// tai.px_kuaisu(arr);
long end = System.nanoTime();
System.out.println(end);
System.out.println("排序后");
tai.print(arr);
System.out.println("排序用时:" + (end - start) + "纳秒");
}
}
数组需要足够大的时候,归并排序和快速排序才能看出威力。。