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

    排序分为两大类:

    第一类:基于比较的排序

    1  冒泡排序

    public class BubbleSort {
    
        public static void main(String[] args) {
            int [] arr = new int[] {2,5,12,8,23,90,34};
            sort(arr);
            Arrays.stream(arr).forEach(x->System.out.print(x+ " "));
        }
        
        public static void sort(int [] arr) {
            for(int j = arr.length-1 ; j>0;j--) {
                for(int i = 0 ; i<j; i++) {
                    if(arr[i] > arr[i+1]) {
                        swap(arr, i, i+1);
                    }
                }
            }
        }
        
        
        public static void swap(int [] arr , int i , int j) {
            int temp =  arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
        }
    }

    2 选择排序

    public class SelectionSort {
    
        public static void main(String[] args) {
            int [] arr = new int[] {2,5,12,8,23,90,34};
            sort(arr);
            Arrays.stream(arr).forEach(x->System.out.print(x+ " "));
            
        }
        
        
        public static void sort(int [] arr ) {
            for(int i=0 ; i<arr.length; i++) {
                int min = i;
                for(int j=i+1;j<arr.length;j++) {
                    min = arr[j]<arr[min]?j:min;
                }
                swap(arr, min, i);
            }
        }
        
        
        public static void swap(int [] arr , int i , int j) {
            int temp =  arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
        }
        
    }

    3  插入排序

    public class InsertSort {
    
        public static void main(String[] args) {
            int [] arr = new int[] {2,5,12,8,23,90,34};
            sort(arr);
            Arrays.stream(arr).forEach(x->System.out.print(x+ " "));
        }
        
        public static void sort(int [] arr ) {
            for(int i=1;i<arr.length;i++) {
                int j=i;
                while(j>0 ) {
                    if( arr[j] < arr[j-1]) {
                        swap(arr,j,j-1);
                    }
                    j--;
                }
            }
            
        }
        
        
        public static void swap(int [] arr , int i , int j) {
            int temp =  arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
        }
    }

    4 归并排序

    public class MergeSort {
    
        public static void main(String[] args) {
            int [] arr = new int[] {2,5,12,8,23,90,34};
            sort(arr, 0 , arr.length-1);
            Arrays.stream(arr).forEach(x->System.out.print(x+ " "));
        }
        
        public static void sort(int[] arr , int L , int R) {
            if(L == R) {
                return ;
            }
            int mid = L+((R-L)>>1);
            sort(arr,L,mid);
            sort(arr,mid+1,R);
            merge(arr,L,mid,R);
        }
    
        private static void merge(int [] arr, int L, int mid, int R) {
            int [] help = new int[R-L+1];
            int i = 0;
            int p1 = L;
            int p2 = mid+1;
            while(p1<=mid && p2<= R) {
                help[i++] =  arr[p1] < arr[p2]  ? arr[p1++]:arr[p2++];
            }
            while(p1<=mid) {
                help[i++] = arr[p1++];
            }
            while(p2<=R) {
                help[i++] = arr[p2++];
            }
            for(i= 0 ; i<help.length; i++ ) {
                arr[L+i] = help[i];
            }
        }
    
    }

     5 随机快速

    /**
     * 经典快排:每次取都是最后一个数做参考
     * 随机快排:每次随机取一个数和最后一个数交换后,再排序
     * 经典快排思路:每次取数组的最后一个数num为参照,将指定区域排序为,前半部分小于num,中间部分等于num,右半部分大于num,递归调用
     */
    public class QuickSort {
    
        public static void main(String[] args) {
    
            int[] arr = new int[] { 2, 5, 12, 8, 6, 90, 34, 10, 10 };
            sort(arr, 0, arr.length - 1);
            Arrays.stream(arr).forEach(x -> System.out.print(x + " "));
    
        }
    
        public static void sort(int[] arr, int L, int R) {
            if (L < R) {
                //随机选择一个数和最后一个数交换
                swap(arr, L + (int)(Math.random()*(R-L+1)), R);
                int[] p = partion(arr, L, R);
                sort(arr, L, p[0] - 1);
                sort(arr, p[1] + 1, R);
            }
        }
    
        public static int[] partion(int[] arr, int L, int R) {
            int less = L - 1;
            int more = R;
            int cur = L;
            while (cur < more) {
                if (arr[cur] < arr[R]) {
                    swap(arr, cur++, ++less);
                } else if (arr[cur] == arr[R]) {
                    cur++;
                } else {
                    // 假如arr[R]是10,这里交换后,more位置要比10大
                    swap(arr, cur, --more);
                }
            }
            // 交换后,more位置一定是等于区域的最后一个
            swap(arr, R, more);
            return new int[] { less + 1, more };
        }
    
        public static void swap(int[] arr, int i, int j) {
            int temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
        }
    }

     6 堆排序

    /**
     * 
     * 堆排序的思路是:首先将数组组成一个大根堆,然后将数组的第一个和最后一个交换位置,在剩余的长度上进行堆调整,直到长度等于1
     *
     */
    public class HeapSort {
    
        public static void main(String[] args) {
            
            int[] arr = new int[] { 2, 5, 12, 8, 6, 90, 34, 10, 10 };
            for(int i = 0 ;i<arr.length ; i++) {
                heapInsert(arr,i);
            }
            int size = arr.length;
            while (size > 0) {
                //将数组中最后的一个值和第一个交换
                swap(arr, 0, --size);
                //假如数组长度为10,第一次调整表示将数组最后一位除开,在堆长度9上进行调整
                heapify(arr, 0, size);
            }
            Arrays.stream(arr).forEach(x -> System.out.print(x + " "));
            
        }
        
        //当index位置的值变小了,重新调整堆结构,size为需要保留的堆的长度
        public static void heapify(int[] arr ,  int index, int size) {
            int left = index * 2 + 1;
            while (left < size) {
                //获取左右节点的较大值,假如右节点不存在,就取左节点的值
                int largest = left + 1 < size && arr[left + 1] > arr[left] ? left + 1 : left;
                largest = arr[largest] > arr[index] ? largest : index;
                if (largest == index) {
                    break;
                }
                //假如左右子节点的较大值比父节点值大,就交换
                swap(arr, largest, index);
                index = largest;
                left = index * 2 + 1;
            }
        }
        
        
        //组成一个大根堆的过程
        public static void heapInsert(int[] arr, int index) {
            while (arr[index] > arr[(index - 1) / 2]) {
                swap(arr, index, (index - 1) / 2);
                index = (index - 1) / 2;
            }
        }
        
        public static void swap(int[] arr, int i, int j) {
            int temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
        }
    }

    第二类:非基于比较的排序

     1 计数排序思路:

     先获取数组arr最大值max,最小值min,初始化一个数组bucket,长度为max-min+1,
     遍历arr中元素时候,将元素值减去min,当成bucket的下标,bucket的值表示该下标出现的次数,
     然后依次遍历bucket,重新填充arr数组,得到新的数组就是排序后数组

    public class CountSort {
    
        
        public static void main(String[] args) {
            int[] arr = new int[] { 2, 5, 12, 8, 6, 90, 34, 10, 10 };
            sort(arr);
            Arrays.stream(arr).forEach(x -> System.out.print(x + " "));
        }
        
        public static void sort(int [] arr ) {
            //获取最大值和最小值
            int min = arr[0];
            int max = arr[0];
            for ( int i = 0; i < arr.length; i++) {
                if(arr[i] < min) {
                    min = arr[i];
                }
                if(arr[i] > max) {
                    max = arr[i];
                }
            }
            //初始化一个桶,并向桶里装数据
            int [] bucket = new int[max-min+1];
            for(int j=0 ; j<arr.length; j++) {
                bucket[arr[j]-min]++;
            }
            //从桶里取数据,将原数组排序
            int index = 0;
            for(int i =0 ;i <bucket.length;i++) {
                while(bucket[i]-- > 0) {
                    arr[index++] = i+min;
                }
            }
        }
        
    }
  • 相关阅读:
    最大子数组求和并进行条件组合覆盖测试
    Ubuntu 16.04 c++ Google框架单元测试
    The directory '/home/stone/.cache/pip/http' or its parent directory is not owned by the current user and the cache has been disabled. Please check the permissions and owner of that directory. If execu
    Problem executing scripts APT::Update::Post-Invoke-Success 'if /usr/bin/test -w /var/cache/app-info -a -e /usr/bin/appstreamcli; then appstreamcli refresh > /dev/null; fi'
    个人博客作业三:微软小娜APP的案例分析
    补交 作业一
    补交 作业二:个人博客作业内容:需求分析
    嵌入式软件设计第12次实验报告
    嵌入式软件设计第11次实验报告
    嵌入式软件设计第10次实验报告
  • 原文地址:https://www.cnblogs.com/moris5013/p/11525158.html
Copyright © 2011-2022 走看看