zoukankan      html  css  js  c++  java
  • JAVA 排序

    简述稳定排序和非稳定排序的区别

    稳定排序:排序前后两个相等的数相对位置不变,则算法稳定 非稳定排序:排序前后两个相等的数相对位置发生了变化,则算法不稳定

    堆排序

    什么是最大堆和最小堆?

    最大(小)堆是指在树中,存在一个结点而且该结点有儿子结点,该结点的data域值都不小于(大于)其儿子结点的data域值,并且它是一个完全二叉树(不是满二叉树)

    堆排序

    import java.util.*;
    
    public class Main {
        // static int[] a = { 9, 5, 3, 2, 2, 2, 6, 1, 0 };
        static int[] a = { 3, 2, 6, 1, 0 };
    
        void downAdjust(int[] arr, int parentIndex, int length) {
            // temp保存父节点的值,用于最后赋值
            int temp = arr[parentIndex];
            int childrenIndex = 2 * parentIndex + 1;
            while (childrenIndex < length) {
                // 如果有右孩子,且右孩子大于左孩子的值,则定位到右孩子
                // 这里其实是比较左、右子树的大小,选择更大的
                if (childrenIndex + 1 < length && arr[childrenIndex + 1] > arr[childrenIndex]) {
                    childrenIndex++;
                }
                // 如果父节点大于任何一个孩子得值,则直接跳出
                if (temp >= arr[childrenIndex]) {
                    break;
                }
                // 当左、右子树比父节点更大,进行交换
                arr[parentIndex] = arr[childrenIndex];
                parentIndex = childrenIndex;
                childrenIndex = 2 * childrenIndex + 1;
            }
            arr[parentIndex] = temp;
        }
    
        void swap(int a, int b) {
            int tmp = a;
            a = b;
            b = tmp;
        }
    
        /**
         * 堆排序(升序)
         * 
         * @param {array} arr 待调整的堆
         */
        int[] heapSort(int[] arr) {
            // 把无序数组构建成最大堆, 这里-2,是因为从索引0开始、另外就是叶子节点【最后一层是不需要堆化的】
            for (int i = (arr.length - 2) / 2; i >= 0; i--) {// (arr.length-2)/2:最后一个父节点
                downAdjust(arr, i, arr.length);
            }
    
            // 循环删除堆顶元素,并且移到集合尾部,调整堆产生新的堆顶
            for (int i = arr.length - 1; i > 0; i--) {
                // 交换最后一个元素与第一个元素
                // swap(arr[0], arr[i]);
                int temp = arr[i];
                arr[i] = arr[0];
                arr[0] = temp;
                // swap(arr[0],arr[i])错误,无法交换
                // 下沉调整最大堆
                // downAdjust(arr, 0, i - 1);// 1 0 2 3 6 i-1的话 i==2时,无法重新更细为最大堆
                downAdjust(arr, 0, i);// 0 1 2 3 6
            }
            return arr;
        }
    
        public static void main(String agrs[]) {
            Main ma = new Main();
            ma.heapSort(a);
            for (int x : a) {
                System.out.print(x + " ");
            }
    
        }
    }

    输入整数数组 arr ,找出其中最小的 k 个数。例如,输入4、5、1、6、2、7、3、8这8个数字,则最小的4个数字是1、2、3、4。

    class Solution {
        public int[] getLeastNumbers(int[] arr, int k) {
            if(arr.length==0 ||k==0){
                   return new int[0];
            }
                 PriorityQueue<Integer>que  =new PriorityQueue<Integer>(new acomparator());//PriorityQueue默认最小堆,这里改为最大堆
                 for(int a:arr){
                     if(que.size()<k)  que.offer(a);
                     else if(a<que.peek()){
                         que.poll();
                         que.offer(a);
                     }
                 }
                 int n  =que.size();
                 int []b  =new int[n];
                //  for(int i=0;i<que.size();i++) {//这里不能用que.size(),因为que.size()在变化
                //      b[i]  =que.poll();
                //  }
                 for(int i=0;i<n;i++) {
                     b[i]  =que.poll();
                 }
                 return b;
        }
    }
    class acomparator implements Comparator<Integer>{
        public int compare(Integer a,Integer b){
            return b-a;
        }
    }

    最大的K个数,需要修改如下:

      PriorityQueue<Integer> que = new PriorityQueue<Integer>();
     else if (a > que.peek()) {
                    que.poll();
                    que.offer(a);
                }

    归并排序

    把两个有序的序列归并成一个序列
    当小组只有一个数据时,可以认为这个小组组内已经达到了有序,然后再合并相邻的二个小组就可以了
    import java.util.*;
    
    public class Main {
    
        int[] a = new int[5];
        int[] b = new int[5];
        int ans;
    
        void merge(int[] a, int l, int r) {
            if (l == r)
                return;
            int m = (l + r) >> 1;
            merge(a, l, m);
            merge(a, m + 1, r);
            int i = l, j = m + 1, k = l;
            while (i <= m && j <= r) {
                if (a[i] <= a[j])
                    b[k++] = a[i++];
                else {
                    b[k++] = a[j++];
                    ans += (m - i + 1);//逆序对数目
                }
            }
            while (i <= m)
                b[k++] = a[i++];
            while (j <= r)
                b[k++] = a[j++];
            for (int p = l; p <= r; p++)
                a[p] = b[p];
        }
    
        public static void main(String args[]) {
            Main ma = new Main();
            Scanner input = new Scanner(System.in);
            for (int i = 0; i < 5; i++) {
                ma.a[i] = input.nextInt();
            }
            ma.merge(ma.a, 0, 4);
            for (int i = 0; i < 5; i++) {
                System.out.print(ma.a[i] + " ");
            }
            System.out.println(" ");
            System.out.println(ma.ans);
    
        }
    }

     链表归并

    import java.util.*;
    
    import javax.swing.plaf.metal.MetalRadioButtonUI;
    
    public class Main {
        static class Node {
            int val;
            Node next;
    
            public Node(int val) {
                this.val = val;
            }
        }
    
        static Node head;
    
        public void addfirst(int val) {
            Node node = new Node(val);
            if (head == null) {
                head = node;
                return;
            }
            node.next = head;
            head = node;
    
        }
    
        public void addlast(int val) {
            Node px = head;
            Node node = new Node(val);
            if (head == null) {
                head = node;
                return;
            }
            while (px.next != null) {
                px = px.next;
            }
            px.next = node;
        }
    
        public void printl(Node p) {
            Node px = p;
            while (px != null) {
                System.out.print(px.val + " ");
                px = px.next;
            }
            System.out.println(" ");
        }
    
        public Node bingsort(Node head) {
            if (head == null || head.next == null)
                return head;
            Node mid = getmid(head);
            Node ri = mid.next;
            mid.next = null;
            return merge(bingsort(head), bingsort(ri));
        }
    
        public Node getmid(Node head) {
            if (head == null || head.next == null)
                return head;
            Node sl = head, fa = head;
            while (fa.next != null && fa.next.next != null) {
                sl = sl.next;
                fa = fa.next.next;
            }
            return sl;
        }
    
        public Node merge(Node head1, Node head2) {
            Node p1 = head1, p2 = head2, head;
            if (head1.val <= head2.val) {
                head = head1;
                p1 = p1.next;
            } else {
                head = head2;
                p2 = p2.next;
            }
            Node p = head;
            while (p1 != null && p2 != null) {
                if (p1.val <= p2.val) {
                    p.next = p1;
                    p1 = p1.next;
                    p = p.next;
                } else {
                    p.next = p2;
                    p2 = p2.next;
                    p = p.next;
                }
            }
            if (p1 != null)
                p.next = p1;
            if (p2 != null)
                p.next = p2;
            return head;
    
        }
    
        public static void main(String[] args) {
            Main ma = new Main();
            ma.addlast(1);
            ma.addlast(7);
            ma.addlast(10);
            ma.addlast(19);
            ma.addlast(1);
            ma.addlast(7);
            ma.addlast(100);
            ma.addlast(1999);
            ma.printl(head);
            ma.bingsort(head);
            ma.printl(head);
    
        }
    }

    快速排序

    import java.util.*;
    
    
    
    public class Main {
    
        private static void sort(int[] arr, int l, int r) {
            int i = l;
            int j = r;
            if (l < r) {
                while (l < r) {
                    while (l < r && arr[r] >= arr[l]) {
                        r--;
                    }
                    int tmp = arr[l];
                    arr[l] = arr[r];
                    arr[r] = tmp;
    
                    while (l < r && arr[l] <= arr[r]) {
                        l++;
                    }
                    tmp = arr[l];
                    arr[l] = arr[r];
                    arr[r] = tmp;
    
                }
                sort(arr, i, l - 1);// 递归左边,此时l=5
                sort(arr, l + 1, j);// 递归右边,此时l=5
            }
        }
    
        public static void main(String agrs[]) {
    
            int[] arr = { -5, 1, 1, 8, 7, 300, 7, 0, 0, 6 };
            sort(arr, 0, arr.length - 1);
            for (int i : arr) {
                System.out.print(i + " ");
            }
    
        }
    }

     

    链表快排  https://www.cnblogs.com/morethink/p/8452914.html

    /**
     * Definition for singly-linked list.
     * public class ListNode {
     *     int val;
     *     ListNode next;
     *     ListNode() {}
     *     ListNode(int val) { this.val = val; }
     *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
     * }
     */
    class Solution {
        public ListNode sortList(ListNode head) {
             quicksort(head,null);
             return head;
        }
        public void quicksort(ListNode head,ListNode end){
            if(head!=end){//注意边界
            ListNode node  =partion(head,end);
            quicksort(head,node);
            quicksort(node.next,end);
            }
            
        }
        public ListNode partion(ListNode head,ListNode end){//p1前面的都小于key,p1,p2之间的都大于key,p2=end时交换p1 head,p1就是partion
            ListNode p1  =head,p2 =head.next;
            while(p2!=end){
                if(p2.val<head.val){
                    p1 = p1.next;
                    int tmp  = p1.val;
                    p1.val  =p2.val;
                    p2.val  =tmp;
                }
                p2  =p2.next;
            }
            if(p1!=head){//已经有序不需要交换
                int tmp  = p1.val;
                p1.val  =head.val;
                head.val  =tmp;
            }
            return p1;
        }
    }

     

    剑指 Offer 40. 最小的k个数

    输入整数数组 arr ,找出其中最小的 k 个数。例如,输入4、5、1、6、2、7、3、8这8个数字,则最小的4个数字是1、2、3、4。

    class Solution {
        public int[] getLeastNumbers(int[] arr, int k) {
            if (k == 0 || arr.length == 0) {
                return new int[0];
            }
            // 最后一个参数表示我们要找的是下标为k-1的数
            return quickSearch(arr, 0, arr.length - 1, k - 1);
        }
        private int[] quickSearch(int[] nums, int lo, int hi, int k) {
            // 每快排切分1次,找到排序后下标为j的元素,如果j恰好等于k就返回j以及j左边所有的数
            int j = partition(nums, lo, hi);
            if (j == k) {
                return Arrays.copyOfRange(nums,0, j + 1);
            }
            // 否则根据下标j与k的大小关系来决定继续切分左段还是右段。
            return j > k? quickSearch(nums, lo, j - 1, k): quickSearch(nums, j + 1, hi, k);
        }
        private int partition(int[] arr, int l, int r) {
            int i = l;
            int j = r;
            if (l < r) {
                while (l < r) {
                    while (l < r && arr[r] >= arr[l]) {
                        r--;
                    }
                    int tmp = arr[l];
                    arr[l] = arr[r];
                    arr[r] = tmp;
                    while (l < r && arr[l] <= arr[r]) {
                        l++;
                    }
                    tmp = arr[l];
                    arr[l] = arr[r];
                    arr[r] = tmp;
                }  
            }
            return r; //arr[r]左边不大于他,右边不小于他
        }
    }

  • 相关阅读:
    13.Convert BST to Greater Tree(将树转为更大树)
    13.调用数组顺序使奇数位于偶数前面
    12.数值的整数次方
    11.二进制中1的个数
    12.Hamming Distance(汉明距离)
    11.Find All Numbers Disappeared in an Array(找出数组中缺失的数)
    10.Find All Anagrams in a String(在一个字符串中发现所有的目标串排列)
    垃圾收集器与内存分配策略---垃圾收集器
    线程之间的协作
    1287. Mars Canals(DP)
  • 原文地址:https://www.cnblogs.com/tingtin/p/15753810.html
Copyright © 2011-2022 走看看