乐趣区

关于java:Java编程基于快速排序的三个算法题实例代码

疾速排序原理简介

疾速排序是咱们之前学习的冒泡排序的降级,他们都属于替换类排序,都是采纳一直的比拟和挪动来实现排序的。疾速排序是一种十分高效的排序算法,它的实现,增大了记录的比拟和挪动的间隔,将关键字较大的记录从后面间接挪动到前面,关键字较小的记录从前面间接挪动到后面,从而缩小了总的比拟次数和挪动次数。同时采纳“分而治之”的思维,把大的拆分为小的,小的拆分为更小的,其原理如下:对于给定的一组记录,抉择一个基准元素, 通常抉择第一个元素或者最初一个元素, 通过一趟扫描,将待排序列分成两局部, 一部分比基准元素小, 一部分大于等于基准元素, 此时基准元素在其排好序后的正确地位, 而后再用同样的办法递归地排序划分的两局部,直到序列中的所有记录均有序为止。

一,最小的 k 个数

输出 n 个数,找出其中最小的 k 个数,例如输出 4,5,1,6,2,7,3,8, 个数字,则最小的数字是 1,2,3,4

基于 O(n) 的算法,能够用基于 Partion 函数解决这个问题,如果基于数组的第 k 个数字来调整,使得比第 k 个数字小的所有数字都位于数组的右边,比第 k 个数组大的所有数字都位于数组的左边,这样调整之后数组右边的 k 个数字就是最小的 k 个数字,不肯定有序

import java.util.Scanner;
public class Main {public static void main(String[] args) {Scanner in=new Scanner(System.in);
        int n=in.nextint();
        int k=in.nextint();
        int[] num=new int[n];
        int[] out=new int[k];
        for (int i=0;i<n;i++){num[i]=in.nextint();}
        Boolean b=GetMinK(n,num,k,out);
        if(b){for (int i=0;i<k;i++){System.out.print(out[i]+" ");
            }
        }
    }
    public static Boolean GetMinK(int uiInputNum, int[] pInputArray, int uiK, int[] pOutputArray){if(pInputArray==null||pOutputArray==null||uiK>uiInputNum||uiInputNum<=0||uiK<=0){return false;}
        int start=0;
        int end=uiInputNum-1;
        int index=partition(pInputArray,start,end);
        while(index!=uiK-1){if(index>uiK-1){
                //index 在 k - 1 的左边
                end=index-1;
                index=partition(pInputArray,start,end);
            } else{
                start=index+1;
                index=partition(pInputArray,start,end);
            }
        }
        for (int i=0;i<uiK;i++){pOutputArray[i]=pInputArray[i];
        }
        return true;
    }
    //partion 分区函数,返回数组 a 的首元素快排的索引值 index
    public static int partition(int[] a,int start,int end){int privot=a[start];
        int i=start;
        int j=end;
        while(i<j){while(i<j&&privot<=a[j]){j--;}
            swap(a,i,j);
            while(i<j&&privot>=a[i]){i++;}
            swap(a,i,j);
        }
        return i;
    }
    public static void swap(int[] a,int i,int j){int t=a[i];
        a[i]=a[j];
        a[j]=t;
    }
}

二,数组中呈现次数超过一半的数字

数组中有一个数字呈现次数超过数组长度的一半,请找出这个数字。例如 1,2,3,2,2,2,5,4,2,数字 2 在数组中呈现了 5 次,超过数组长度的一半,输入 2

受疾速排序的启发,在疾速排序中,当初数组中抉择一个数字,而后调整数组中的数字的程序,使得比选中数字小的数字都排在它的右边,比选中数字大的数字都排在它的左边。

如果选中的数字的下标刚好是 n /2,那么这个数字就是数组中的中位数

import java.util.Scanner;
public class Main {public static void main(String[] args) {Scanner in=new Scanner(System.in);
        int n=in.nextint();
        int[] num=new int[n];
        for (int i=0;i<n;i++){num[i]=in.nextint();}
        int b=GetHalfNum(n,num);
        if(b!=-1){System.out.println(b);
        }
    }
    public static int GetHalfNum(int uiInputNum, int[] pInputArray){if(pInputArray==null||uiInputNum<=0){return -1;}
        int middle=uiInputNum>>1;
        // 长度的一半
        int start=0;
        int end=uiInputNum-1;
        int index=partition(pInputArray,start,end);
        while(index!=middle){
            // 如果不等于长度的一半阐明就没有找到这个中位数
            if(index>middle){
                end=index-1;
                index=partition(pInputArray,start,end);
            } else{
                start=index+1;
                index=partition(pInputArray,start,end);
            }
        }
        return pInputArray[index];
        //index=middle
    }
    public static int partition(int[] a,int start,int end){int privot=a[start];
        int i=start;
        int j=end;
        while(i<j){while(i<j&&privot<=a[j]){j--;}
            swap(a,i,j);
            while(i<j&&privot>=a[i]){i++;}
            swap(a,i,j);
        }
        return i;
    }
    public static void swap(int[] a,int i,int j){int t=a[i];
        a[i]=a[j];
        a[j]=t;
    }
}

三,找出数组中第 k 个最小的数

例如给定数组 1,5,2,6,8,0,6 中,第 4 小的数字是 5

import java.util.Scanner;
public class Main {public static void main(String[] args) {Scanner in=new Scanner(System.in);
        int n=in.nextint();
        int k=in.nextint();
        int[] num=new int[n];
        //int[] out=new int[k];
        for (int i=0;i<n;i++){num[i]=in.nextint();}
        int b=GetMinK(n,num,k);
        if(b!=-1){System.out.println(b);
        }
    }
    public static int GetMinK(int uiInputNum, int[] pInputArray, int uiK){if(pInputArray==null||uiK>uiInputNum||uiInputNum<=0||uiK<=0){return -1;}
        int start=0;
        int end=uiInputNum-1;
        int index=partition(pInputArray,start,end);
        while(index!=uiK-1){
            // 如果 index 不是 k - 1 的地位
            if(index>uiK-1){
                end=index-1;
                index=partition(pInputArray,start,end);
            } else{
                start=index+1;
                index=partition(pInputArray,start,end);
            }
        }
        return pInputArray[index];
        // 返回的这个地位的数值
    }
    public static int partition(int[] a,int start,int end){int privot=a[start];
        int i=start;
        int j=end;
        while(i<j){while(i<j&&privot<=a[j]){j--;}
            swap(a,i,j);
            while(i<j&&privot>=a[i]){i++;}
            swap(a,i,j);
        }
        return i;
    }
    public static void swap(int[] a,int i,int j){int t=a[i];
        a[i]=a[j];
        a[j]=t;
    }
}

总结

以上就是本文对于 Java 编程基于疾速排序的三个算法题实例代码的全部内容,心愿对大家有所帮忙

退出移动版