java语言实现数据结构之排序

  • 基于插入方式的排序
  • 二分排序
  • 希尔排序
  • 冒泡排序
  • 快速排序
  • 简单选择排序
  • 堆排序
  • 主函数


基于插入方式的排序

/**
     * 直接插入排序
     * 1.遍历目标数组
     * 2.取出第i个元素
     * 3.将source[i]与前面已经有序的sorted[0]~sorted[i-1]依次进行比较
     * 4.若在上述比较过程中,存在sorted[k] > source[i],则sorted[i-1]依次后移一位
     * 5.sorted[k] = source[i]
     * 6.继续遍历
     */
    public static void insertSort(int[] source){
        System.out.println("origin:"+Arrays.toString(source));
        //1.第一个元素有序,开始从第二个值开始依次向后遍历
        for (int i = 1; i < source.length; i++){
            //2.如果当前值比前一个值小
            if (source[i] < source[i-1]){
                //3.摘出当前值
                int temp = source[i],j;
                //4.与前面的i-1个值依次进行比较,source[i]依次与sorted[0]~sorted[i-1]比较
                // 只要索引大于等于0且当前元素大于temp.由于当前i为目标元素,故应对i-1依次开始向前比较,一直比较直0索引处(从后往前比较)
                for (j = i-1; j >= 0 && temp < source[j] ; j--){
                    //5.如果目标元素小于当前元素,也即当前元素大,则当前元素后移(其实j+1处即为目标元素i位置)
                    source[j+1] = source[j];
                }
                //5.因为这个是时候指针j已经减了一位,所以这个地方要+1,最后放目标元素
                source[j+1] = temp;
            }
        }
        System.out.println("sorted:"+Arrays.toString(source));
    }

二分排序

public static void binarySort(int[] source){
        System.out.println("origin:"+Arrays.toString(source));
        int mid,low,high;
        for (int i = 1; i < source.length; i++){
            //折半查找应该插入的位置
            low = 0; high = i-1;
            while(low <= high){
                mid = (low + high) / 2;
                if (source[mid] > source[i]){
                    high = mid - 1;
                }else {
                    low = mid + 1;
                }
            }
            //统一移动元素,然后将这个元素插入到正确的位置
            int temp = source[i];
            for (int j = i; j > high+1; j--){
                source[j] = source[j-1];
            }
            source[high+1] = temp;
        }
        System.out.println("sorted:"+Arrays.toString(source));
    }

希尔排序

public static void shellSort(int[] source){
        System.out.println("origin:"+Arrays.toString(source));
        int len = source.length;
        //按照缩小增量依次按照dk/2进行切割序列,直至增量为1
        for (int dk = len/2; dk >= 1; dk = dk/2){
            int temp;
            //循环遍历本次增量划分的区间子序列
            for (int i = dk; i < len; i++){
                if (source[i] < source[i-dk]){
                    temp = source[i];
                    int j;
                    //对本次划分的序列进行排序--直接出入排序算法
                    for (j = i-dk; j >= 0 && temp < source[j]; j-=dk){
                        source[j+dk] = source[j];
                    }
                    source[j+dk] = temp;
                }
            }
        }
        System.out.println("sorted:"+Arrays.toString(source));
    }

冒泡排序

public static void bubbleSort(int[] source){
        System.out.println("origin:"+Arrays.toString(source));
        //冒泡排序趟数
        for (int i = 0; i < source.length; i++){
            boolean flag = false; /*本趟排序是否发生交换的标志*/
            int temp;
            for (int j = source.length-1; j > i; j--){
                if (source[j] < source[j-1]){
                    temp = source[j];
                    source[j] = source[j-1];
                    source[j-1] = temp;
                    flag = true;
                }
            }
            if (!flag){
                System.out.println("sorted:"+Arrays.toString(source));
                return;
            }
        }
    }

快速排序

public static void quickSort(int[] source,int low,int high){
        if (low < high){
            int p = partition(source, low, high);
            quickSort(source,low,p-1);
            quickSort(source,p+1,high);
        }
    }

    /**
     * 快排的分治策略
     */
    private static int partition(int[] source,int low,int high){
        int pivot = source[low]; //base value
        while(low < high){
            while (low < high && source[high] >= pivot) high--;
            source[low] = source[high];
            while (low < high && source[low] <= pivot) low++;
            source[high] = source[low];
        }
        source[low] = pivot;
        System.out.println("sorted:"+Arrays.toString(source));
        return low;
    }

简单选择排序

public static void selectSort(int[] source){
        System.out.println("origin:"+Arrays.toString(source));
        for (int i = 0; i < source.length; i++){
            int min = i;   //min存放最小元素的下标
            //每轮遍历找出本轮遍历的最小值
            for (int j = i+1; j < source.length; j++){
                if (source[j] < source[min]){
                    min = j;
                }
            }
            //最小下标不是i,则j与第i个位置交换
            int swap;
            if (min != i){
                swap = source[i];
                source[i] = source[min];
                source[min] = swap;
            }
        }
        System.out.println("sorted:"+Arrays.toString(source));
    }

堆排序

public static void heapSort(int[] source){
        System.out.println("origin:"+Arrays.toString(source));
        int len = source.length-1;
        for (int i = len/2; i > 0; i--){
            adjustDown(source,i,len);
        }

    }

    /**
     * adjust down to heap
     */
    public static void adjustDown(int[] source, int index, int len){
        //step1.暂存当前元素节点
        int temp = source[index];
        //step2.沿当前节点向下遍历自己的子节点,i为动态指针
        for (int i = index*2; i <= len; i *= 2){
            //比较子节点左右节点关键子字的大小,如果右孩子关键字大于左孩子关键字,指针指向其大孩子的索引处
            if (i<len && (source[i] < source[i+1])){
                i++;//指针移动到右孩子的位置处
            }
            //比较父节点关键字与子节点关键字大小,如果父节点比子节点较大元素还大,则结束当次比较
            if (temp > source[i]){
                break;//删选结束
            //比较父节点关键字与子节点关键字大小,如果父节点比子节点较大元素小,则交换父节点关键字与其位置,修改节点索引,沿该节点继续向下找
            }else {
                temp = source[i];
                index = i;
            }
        }
        //step3.把最大的元素给当前父节点
        source[index] = temp;
    }

主函数

public static void main(String[] args) {
        int[] target = {20,9,6,8,5,3,1,7,4,0,9,8};
//        insertSort(target);
//        binarySort(target);
//        shellSort(target);
//        bubbleSort(target);
//        quickSort(target,0,target.length-1);
//        selectSort(target);
        heapSort(target);

   }