排序算法练习
package util;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
public class SortUtil {
public static void main(String[] args) {
Integer[] array = new Integer[]{2, 3,0, 5, 8, 9, 7, 5,11,14, 1, 6, 8, 7, 12};
selectSort(array, false);
printAllEle(array);
}
public static <T> void printAllEle(T [] array){
System.out.println(Arrays.toString(array));
}
public static <T extends List> void printAllEle(T list){
if(list!=null&&list.size()>0){
StringBuilder b = new StringBuilder();
b.append('[');
int iMax=list.size()-1;
for (int i = 0; ; i++) {
b.append(list.get(i));
if(i==iMax){
b.append(']');
break;
}
b.append(',');
}
System.out.println(b.toString());
}else{
System.out.println("[]");
}
}
private static void swap(Object[] x, int a, int b) {
Object t = x[a];
x[a] = x[b];
x[b] = t;
}
/**
* 冒泡排序
*
* @param array
* @param asc
* true为升序,false为降序
*/
public static void bubbleSort(Integer[] array, boolean asc) {
if (asc) {
for (int i = 0; i < array.length - 1; i++) {
for (int j = 0; j < array.length - 1; j++) {
if (array[j + 1] < array[j]) {
swap(array, j + 1, j);
}
}
}
} else {
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array.length - 1; j++) {
if (array[j + 1] > array[j]) {
swap(array, j + 1, j);
}
}
}
}
}
/**
* 选择排序
* @param array
* @param asc true为升序,false为降序
*/
public static void selectSort(Integer[] array,boolean asc){
if (asc) {
for (int i = 0; i < array.length - 1; i++) {
for (int j = i + 1; j < array.length; j++) {
if (array[j] < array[i]) {
swap(array, i, j);
}
}
}
} else {
for (int i = 0; i < array.length; i++) {
for (int j = i + 1; j < array.length; j++) {
if (array[j] > array[i]) {
swap(array, i, j);
}
}
}
}
}
/**
* 插入排序
*选出后一个与之前的一个来比较,直到首端或找到正序元素(如升序时,2,3为正序,3,2为逆序)默认之前的都是排好序的,因此最少只比较一次就可以确定位置.
* 内循环发现逆序不交换,采用整体右移,直到没有逆序的时候把元素放在该位置
* @param array
* @param asc true为升序,false为降序
*/
public static void insertSort(Integer[] array,boolean asc){
int temp = 0;
int j = 1;
for (int i = 1; i < array.length; i++) {
temp = array[i];// 需要比较的单独拿出来
j = i;
if (asc) {
while (j > 0 && temp < array[j - 1]) {// 比较,若升序,后者小于前者,向前找到一个数比temp小的数,放在该数之后
array[j] = array[j - 1];// 大则挨个放后,为temp空出位置
j--;
}
} else {
while (j > 0 && temp > array[j - 1]) {
array[j] = array[j - 1];// 为temp空出位置
j--;
}
}
array[j] = temp;
}
}
/**
* 插入排序
*选出后一个与之前的一个来比较,直到首端或找到正序元素(如升序时,2,3为正序,3,2为逆序)默认之前的都是排好序的,因此最少只比较一次就可以确定位置.
* 内循环发现逆序不交换,采用整体右移,直到没有逆序的时候把元素放在该位置
* @param <T>
* @param array
* @param asc true为升序,false为降序
*/
public static void insertSort(List<Integer> list,boolean asc){
int temp=0;
int size=list.size();
int targetIndex=1;//最终应被插入的下标
int comparedIndex=1;//本次被比较的下标
for (int i = 0; i < size; i++) {
temp=list.get(i);
targetIndex=i;
comparedIndex=i;
if(asc){
while(targetIndex>0&&temp<list.get(targetIndex-1)){
list.set(targetIndex, list.get(targetIndex-1));
targetIndex--;
}
}else{
while(targetIndex>0&&temp>list.get(targetIndex-1)){
list.set(targetIndex, list.get(targetIndex-1));
targetIndex--;
}
}
if(comparedIndex!=targetIndex){//位置有改变
list.set(targetIndex, temp);
}
}
}
/**
* 希尔排序
* 插入排序的改进
* [1]将数组按间距分组
* [2]组内进行插入排序。
* [3]一次排序过后,缩小间距,继续[1],[2]的操作
* @param array
* @param asc true为升序
*/
public static void shellSort(Integer[] array,boolean asc) {
int n = array.length;
int gap = n / 2;// 步长、间距
int temp = 0;
if (asc) {// 减少判断次数
do {
// 一次组内的插入排序
for (int i = gap; i < n; i++) {// 插入排序
int j = 0;
temp = array[i];// 待插入正确位置的元素temp
for (j = i - gap; j >= 0 && temp < array[j]; j -= gap) {// 为temp元素找到不再逆序的位置
array[j + gap] = array[j];// temp<array[j] ,
// 上一个逆序,当前元素后移
}
// 退出时,若因j<0退出,则j+gap>=0,j+gap为最终位置;若temp<array[j]退出,则j+gap为最终位置
if (j + gap != i) {// 最终位置有变化
array[j + gap] = temp;// 插入到该位置
}
}
} while ((gap /= 2) >= 1);
} else {
do {
// 一次组内的插入排序
for (int i = gap; i < n; i++) {// 插入排序
int j = 0;
temp = array[i];// 待插入正确位置的元素temp
for (j = i - gap; j >= 0 && temp > array[j]; j -= gap) {// 为temp元素找到不再逆序的位置
array[j + gap] = array[j];// temp>array[j] ,
// 上一个逆序,当前元素后移
}
// 退出时,若因j<0退出,则j+gap>=0,j+gap为最终位置;若temp<array[j]退出,则j+gap为最终位置
if (j + gap != i) {// 最终位置有变化
array[j + gap] = temp;// 插入到该位置
}
}
} while ((gap /= 2) >= 1);
}
// int n = array.length;
// int gap = n/2;//步长、间距
// int temp=0;
// do {
// //一次组内的插入排序
// for (int i = gap; i < n; i++) {//插入排序
// int j=0;
// temp=array[i];//待插入正确位置的元素temp
// if(asc){
// for (j = i-gap; j >= 0&&temp<array[j] ; j -= gap) {//为temp元素找到不再逆序的位置
// array[j+gap] = array[j];// temp<array[j] , 上一个逆序,当前元素后移
// }
// }else{
// for (j = i-gap; j >= 0&&temp>array[j] ; j -= gap) {//为temp元素找到不再逆序的位置
// array[j+gap] = array[j];// temp>array[j] , 上一个逆序,当前元素后移
// }
// }
// //退出时,若因j<0退出,则j+gap>=0,j+gap为最终位置;若temp<array[j]退出,则j+gap为最终位置
// if(j+gap!=i){//最终位置有变化
// array[j+gap]= temp;//插入到该位置
// }
// }
// } while ((gap/=2)>=1);
}
public static void shellSort(List<Integer> list,boolean asc) {
int n = list.size();
int gap = n / 2;// 步长、间距
int temp = 0;
if (asc) {
do {
// 一次组内的插入排序
for (int i = gap; i < n; i++) {// 插入排序
int j = 0;
temp = list.get(i);// 待插入正确位置的元素temp
for (j = i - gap; j >= 0 && temp < list.get(j); j -= gap) {// 为temp元素找到不再逆序的位置
list.set(j + gap, list.get(j));// temp<array[j] ,
// 上一个逆序,当前元素后移
}
// 退出时,若因j<0退出,则j+gap>=0,j+gap为最终位置;若temp<array[j]退出,则j+gap为最终位置
if (j + gap != i) {// 最终位置有变化
list.set(j + gap, temp);// 插入到该位置
}
}
} while ((gap /= 2) >= 1);
} else {
do {
// 一次组内的插入排序
for (int i = gap; i < n; i++) {// 插入排序
int j = 0;
temp = list.get(i);// 待插入正确位置的元素temp
for (j = i - gap; j >= 0 && temp > list.get(j); j -= gap) {// 为temp元素找到不再逆序的位置
list.set(j + gap, list.get(j));// temp<array[j] ,
// 上一个逆序,当前元素后移
}
// 退出时,若因j<0退出,则j+gap>=0,j+gap为最终位置;若temp<array[j]退出,则j+gap为最终位置
if (j + gap != i) {// 最终位置有变化
list.set(j + gap, temp);// 插入到该位置
}
}
} while ((gap /= 2) >= 1);
}
}
// int n = list.size();
// int gap = n/2;//步长、间距
// int temp=0;
// do {
// //一次组内的插入排序
// for (int i = gap; i < n; i++) {//插入排序
// int j=0;
// temp=list.get(i);//待插入正确位置的元素temp
// if(asc){
// for (j = i-gap; j >= 0&&temp<list.get(j) ; j -= gap) {//为temp元素找到不再逆序的位置
// list.set(j+gap, list.get(j));// temp<array[j] , 上一个逆序,当前元素后移
// }
// }else{
// for (j = i-gap; j >= 0&&temp>list.get(j) ; j -= gap) {//为temp元素找到不再逆序的位置
// list.set(j+gap, list.get(j));// temp>array[j] , 上一个逆序,当前元素后移
// }
// }
// //退出时,若因j<0退出,则j+gap>=0,j+gap为最终位置;若temp<array[j]退出,则j+gap为最终位置
// if(j+gap!=i){//最终位置有变化
// list.set(j+gap,temp);//插入到该位置
// }
// }
// } while ((gap/=2)>=1);
// }
}
package shellsort;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;
import util.SortUtil;
public class Test{
public static void main(String[] args) {
// int[] array = new int[]{2, 3,0, 5, 8, 9, 7, 5,11,14, 1, 6, 8, 7, 15};
List<Integer> list=new ArrayList<>();
Random r=new Random();
for (int i = 0; i < 10000; i++) {
list.add(r.nextInt(10000));
}
Integer [] array=(Integer [] )list.toArray(new Integer[list.size()]);
Integer[] array2=array.clone();
Integer[] array3=array.clone();
Integer[] array4=array.clone();
SortUtil.printAllEle(array2);
long start2=System.currentTimeMillis();
SortUtil.shellSort(array2,false);
System.out.println("shellSort time consume "+(System.currentTimeMillis()-start2));
SortUtil.printAllEle(array2);
System.out.println("----------");
long start=System.currentTimeMillis();
SortUtil.insertSort(array,false);
// SortUtil.printAllEle(array);
System.out.println("insertSort time consume "+(System.currentTimeMillis()-start));
System.out.println("----------");
long start3=System.currentTimeMillis();
SortUtil.bubbleSort(array3,false);
System.out.println("bubbleSort time consume "+(System.currentTimeMillis()-start3));
// SortUtil.printAllEle(array3);
System.out.println("----------");
long start4=System.currentTimeMillis();
SortUtil.selectSort(array4,false);
System.out.println("selectSort time consume "+(System.currentTimeMillis()-start4));
long start5=System.currentTimeMillis();
Collections.sort(list);
System.out.println("Collections.sort time consume "+(System.currentTimeMillis()-start5));
}
}
个人练习,欢迎指正。
参考:
http://www.cnblogs.com/jingmoxukong/p/4329079.html
http://blog.csdn.net/guanhang89/article/details/51902378