• 排序算法练习


    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


  • 相关阅读:
    字符串常量
    二维数组中的查找
    Codeforces 156B Suspects——————【逻辑判断】
    Codeforces 156 A——Message——————【思维题】
    Codeforces 639B——Bear and Forgotten Tree 3——————【构造、树】
    Codeforces 671 A——Recycling Bottles——————【思维题】
    Codeforces 550D —— Regular Bridge——————【构造】
    Codeforces 550C —— Divisibility by Eight——————【枚举 || dp】
    codeforces 638B—— Making Genome in Berland——————【类似拓扑排序】
    codeforces 675 C ——Money Transfers——————【思维题】
  • 原文地址:https://www.cnblogs.com/thewindkee/p/12873207.html
Copyright © 2020-2023  润新知