排序算法练习

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


原文地址:https://www.cnblogs.com/thewindkee/p/12873207.html