zoukankan      html  css  js  c++  java
  • 常用排序算法

    import java.util.*;
    
    public class Sort {
        public static void main(String[] args) {
            Sort s = new Sort();
            int[] array = new int[]{1, 6, 2, 7, 3, 9, 10};
    //        int[] array=new int[]{6,3};
            s.countSort(array);
            for (int i : array)
                System.out.print(i + " ");
        }
    
        /**
         * 冒泡排序
         * 从头到尾,比较大小,大的向后放
         * 时间复杂度O(n^2)
         * 空间复杂度O(1)
         */
        public void bubbleSort(int[] array) {
            int temp;
            for (int i = 1; i < array.length; i++) {
                for (int j = 0; j < array.length - i; j++) {
                    if (array[j] > array[j + 1]) {
                        temp = array[j + 1];
                        array[j + 1] = array[j];
                        array[j] = temp;
                    }
                }
            }
        }
    
        /**
         * 选择排序
         * 每次从数组中找出最大值,将其与最后一个元素交换
         * 时间复杂度O(n^2)
         * 空间复杂度O(1)
         */
        int max, temp;
    
        public void selectSort(int[] array) {
            for (int i = array.length - 1; i > 0; i--) {
                //在剩余元素中寻找最大值
                max = 0;
                for (int j = 0; j <= i; j++) {
                    if (array[j] > array[max]) {
                        max = j;
                    }
                }
                //最大值放到最后
                temp = array[i];
                array[i] = array[max];
                array[max] = temp;
            }
        }
    
        /**
         * 插入排序
         * 从数组中取出一个元素,查找其在新数组中的位置,进行插入
         * 有序数组从后向前查
         * 时间复杂度O(n^2)
         * 空间复杂度O(1)
         */
        public void insertSort(int[] array) {
            int temp;
            for (int i = 1; i < array.length; i++) {
                //缓存当前待插入值
                temp = array[i];
                //从后向前
                int j = i - 1;
                for (; j >= 0; j--) {
                    //找到待插入位置
                    if (temp > array[j]) {
                        array[j + 1] = temp;
                        break;
                    }
                    //数组元素后移
                    array[j + 1] = array[j];
                }
                if(j==-1) {
                    array[0] = temp;
                }
            }
        }
    
        /**
         * 快速排序
         * 一趟排序将数组分为两部分,一部分的数据大于另一部分的数组,在递归进行快速排序
         */
        public void quickSort(int[] array) {
            quickSort(array, 0, array.length - 1);
        }
    
        public void quickSort(int[] array, int start, int end) {
            //确定一个分割点
            int mid = array[start];
            int left = start;
            int right = end;
            while (left < right) {
                //必须先右后左,若先左,则左永远不会+1
                //从右向左找一个小于mid的值
                while (array[right] > mid && left < right) right--;
                array[left] = array[right];
                //从左向右找一个大于mid的值
                while (array[left] < mid && left < right) left++;
                array[right] = array[left];
            }
            array[left] = mid;
            //递归,分别对两侧进行快速排序
            if (left - 1 > start) quickSort(array, start, left - 1);
            if (right + 1 < end) quickSort(array, right + 1, end);
        }
    
        /**
         * 堆排序
         * 构建大顶堆,将最后一个元素与堆顶交换,再构建大顶堆,以此类推,直到最后一个元素
         * 堆是完全二叉树,一个数组的下标为i,则他的父节点是(i-1)/2
         */
        public void heapSort(int[] array) {
            int temp;
            for (int i = array.length - 1; i > 0; i--) {
                buildBigHeap(array, 0, i);
                //将栈顶与最后一个元素交换
                temp = array[0];
                array[0] = array[i];
                array[i] = temp;
            }
        }
    
        public void buildBigHeap(int[] array, int start, int end) {
            int temp;
            for (int i = end; i > start; i--) {
                if (array[i] > array[(i - 1) / 2]) {
                    temp = array[i];
                    array[i] = array[(i - 1) / 2];
                    array[(i - 1) / 2] = temp;
                }
            }
        }
    
        /**
         * 归并排序(2路归并)
         * 将一个数组对半拆分,直到数据两两一组,之后合并排序,这样将两个有序数组合并为一个有序数组,直到最后一个结果
         */
        public void mergeSort(int[] array) {
            int[] result = new int[array.length];
            split(array, 0, array.length - 1);
        }
    
        public void split(int[] array, int start, int end) {
            if (start < end) {
                int mid = (end + start) / 2;
                split(array, start, mid);
                split(array, mid + 1, end);
                merge(array, start, mid, end);
            }
        }
    
        public void merge(int[] array, int start, int mid, int end) {
            int left = start;
            int right = mid + 1;
            int cur = 0;
            int[] result = new int[end - start + 1];
            while (left <= mid && right <= end) {
                if (array[left] < array[right]) {
                    result[cur++] = array[left++];
                } else {
                    result[cur++] = array[right++];
                }
            }
            while (left <= mid) {
                result[cur++] = array[left++];
            }
            while (right <= end) {
                result[cur++] = array[right++];
            }
            System.arraycopy(result, 0, array, start, end - start + 1);
        }
    
        /**
         * 基数排序
         * 所有数字按照个十百千,分别进行排序,最后一次排序的结果就是有序的
         * 1.找出最大值
         * 2.所有数字的位数与最大值补齐
         * 3.从个位开始排序
         */
        public void radixSort(int[] array) {
            int max = array[0];
            //找出最大值
            for (int i = 0; i < array.length; i++) {
                if (array[i] > max) {
                    max = array[i];
                }
            }
            //判断最大值有多少位
            int maxLength = 1;
            while (max >= 10) {
                maxLength *= 10;
                max = max / 10;
            }
            //每一位单独排序
            for (int i = 1; i <= maxLength; i *= 10) {
                radixSort(array, i);
            }
        }
    
        public void radixSort(int[] array, int place) {
            //因为一位数只有0-9共10种情况,因此创建一个数组,每个数组存储一个链表
            List<LinkedList> list = new ArrayList();
            for (int i = 0; i < 10; i++) {
                list.add(new LinkedList<Integer>());
            }
            //将节点插入相应位置
            for (int i = 0; i < array.length; i++) {
                list.get((array[i] / place) % 10).add(array[i]);
            }
            //将列表元素放进数组中
            Iterator iterator = list.iterator();
            LinkedList linkedList;
            int cur = 0;
            while (iterator.hasNext() && cur < array.length) {
                linkedList = (LinkedList) iterator.next();
                while (!linkedList.isEmpty()) {
                    array[cur++] = (int) linkedList.getFirst();
                    linkedList.remove();
                }
            }
        }
    
        /**
         * 希尔排序
         * 设置步长,相差步长的元素分为一组,进行快速排序
         * 缩小步长为原来的一半,重复上步
         * 当步长为1时,即全部数据有序
         */
        public void shellSort(int[] array) {
            //设置步长为 数组长度的一半,之后不断折半
            for (int step = (array.length+1)/ 2; step > 0; step = (step+1)/2) {
                for (int i = 0; i < step; i++) {
                    shellSort(array, i, step);
                }
                if(step==1)
                    break;
            }
        }
    
        public void shellSort(int[] array, int start, int step) {
            int temp;
            //第一个已经有序
            for (int i = start+step; i < array.length - 1; i += step) {
                temp = array[i];
                //从有序表中查找
                int j = i-step;
                for (; j >= start; j -= step) {
                    if (temp > array[j]) {
                        array[j+step]=temp;
                        break;
                    }
                    array[j+step]=array[j];
                }
                if(j==start-step){
                    array[start]=temp;
                }
            }
        }
    
    
        /**
         * 桶排序
         * 1.确定桶的数量,通过(max-min)/len+1
         * 2.用arraylist存储桶,桶内存储arraylist
         * 3.将数组元素分到桶内
         * 4.对每个桶分别排序
         * 5.遍历所有桶,输出结果
         */
        public void bucketSort(int[] array) {
            //找出最大最小值
            int min=array[0];
            int max=array[0];
            for(int i=1;i<array.length;i++){
                min=min<array[i]?min:array[i];
                max=max>array[i]?max:array[i];
            }
            //确定桶的数量,+1是避免max-min<len
            int bucket=(max-min)/array.length+1;
    
            //创建桶
            List<ArrayList<Integer>> list=new ArrayList<>(bucket);
            for(int i=0;i<bucket;i++){
                list.add(new ArrayList<Integer>());
            }
            //元素入桶
            for(int i=0;i<array.length;i++){
                list.get((array[i]-min)/array.length).add(array[i]);
            }
            //对桶排序
            for(int i=0;i<list.size();i++){
                Collections.sort(list.get(i));
            }
            //将桶中元素取出,放入数组
            int cur=0;
            Iterator<ArrayList<Integer>> iterator = list.iterator();
            while(iterator.hasNext()){
                Iterator<Integer> iterator1 = iterator.next().iterator();
                while(iterator1.hasNext()){
                    array[cur++]=iterator1.next();
                }
            }
        }
    
        /**
         * 计数排序
         * 将数组内数组映射到数组下标,数组元素大小代表出现的次数
         * 1.求出数组长度,max-min+1
         * 2.偏移量为min
         * 3.将元素对应的数组元素+1
         * 4.按照数组元素大小输出数组元素
         */
        public void countSort(int[] array) {
            int min=array[0];
            int max=array[0];
            for(int i=1;i<array.length;i++){
                min=min<array[i]?min:array[i];
                max=max<array[i]?array[i]:max;
            }
            int[] newArray=new int[max-min+1];
            //将数组元素映射到新数组上
            for(int i=0;i<array.length;i++){
                newArray[array[i]-min]++;
            }
            int cur=0;
            for(int i=0;i<newArray.length;i++){
                while(newArray[i]--!=0){
                    array[cur++]=i+min;
                }
            }
        }
    }
    
  • 相关阅读:
    datagridview中读取数据判断+考勤每月上班天数判断
    dateTimePicker日期比较+时间段内查询+员工查询薪资步骤+datagridview
    c#word 存取
    位图去空白
    过桥问题
    Dominos 2(DFS)(容器)
    poj 3421(三分)
    poj 3186(DP)
    安装Ubuntu
    poj 3273(二分)
  • 原文地址:https://www.cnblogs.com/mlr-wjy/p/12625802.html
Copyright © 2011-2022 走看看