Java common sorting algorithm

  In fact, small series is unlikely to want to write relevant articles on java, because this is really a programming language would use too many people, numerous online blog, not necessary to repeat create the wheel, but although the language would use java a lot of people, but will use, master, skilled, proficient and no joke, you want to reach the level of proficiency, Xiao Bian say, a formal development company can be reached through a handful of developers proficient in java, so Xiaobian here to skip about what java simple API, grammar, directly give you some relatively lift capacity and knowledge base is not so, maybe after the interview will be used, in particular, sort, really, I do not know why all like the sort of questions during the interview, the actual development of big data really sort of really small handwriting, I think, is each interviewer wants to see is whether each candidate can get to the sorting algorithm the essence of it.
  Well, each write blog have a bunch of nonsense, self-examination, but did not want to change, then create several small series introduces sorting algorithms and their java implementation.

1. Bubble Sort

  Principle: starting with the first element, and it compares adjacent, if one element is greater than the previous one element behind, put them switch places.
  Schematic:
Java common sorting algorithm
   code implementation:

public static void main(String[] args) {
        int arr[] = { 15, 16, 145, 91, 9, 5, 0 };
        int temp1=0;

        for(int i=0;i<arr.length-1;i++){  //控制循环次数:arr.length-1
            for(int j=0;j<arr.length-i-1;j++){  //控制比较次数:arr.length-i-1
                if(arr[j]>arr[j+1]){
                    temp1=arr[j];
                    arr[j]=arr[j+1];
                    arr[j+1]=temp1;
                }
            }
        }
}

   An enhanced version of bubble sort:

public static void main(String[] args) {
        int arr[] = { 1,0,2,3,4,5,6,7,8 };
        int temp1;
        for(int i=0;i<arr.length-1;i++){  //控制循环次数:arr.length-1
            boolean flag=true;  //判断内层循环是否执行
            for(int j=0;j<arr.length-i-1;j++){  //控制比较次数:arr.length-i-1
                if(arr[j]>arr[j+1]){
                    temp1=arr[j];
                    arr[j]=arr[j+1];
                    arr[j+1]=temp1;
                    flag=false;
                }
            }
            if(flag){  //如果内层循环的if一次都没有执行,说明已经排序结束
                break;
            }
        }

2. Select Sort

  Principle: starting from the first position, he will be compared to all elements of the back, the front is greater than if the latter, they swap places.
  Schematic:
Java common sorting algorithm
  code implementation:

public static void main(String[] args) {
    int arr[] = { 45,15,48,9,3,65,22 };
 for(int i=0;i<arr.length-1;i++){  //控制位置,从第一个位置开始,到倒数第二个位置
        for(int j=i+1;j<arr.length;j++){ //当前位置的下一个位置开始,与后面的所有比较
            if(arr[i]>arr[j]){
                int temp=arr[i];
                arr[i]=arr[j];
                arr[j]=temp;
            }
        }
    }

3. Insertion Sort

  Principle: starting from the second element position, he will compare his previous elements, if smaller than the previous element, it will be inserted into him in front of that element.
  Schematic:
Java common sorting algorithm
  code implementation:

public static void main(String[] args) {
int arr[] = { 45, 15, 48, 9, 3, 65, 22 };
// 插入排序
int temp1;
for (int i = 1; i < arr.length; i++) { //从第二个数开始,一直到最后一个数
    for (int j = 0; j < i; j++) { //i之前的所有数,全部比较
        if (arr[i] < arr[j]) {
            temp1 = arr[i];
            for (int k = i; k > j; k--) { //将前面的数据把后面的覆盖,从j开始,一直到i 
                arr[k] = arr[k - 1];
            }
            arr[j] = temp1;
        }
    }
}

4. Quick Sort

  原理:先选取一个基准点,作用:基准点左侧小于基准点的数据 基准点右侧放的数据都是大于基准点的数据。基准点:最常用的基准点选第一个,最终一个大数组不停的进行查分 拆分的最终结果每个数组只有一个元素。
  原理图:
Java common sorting algorithm
解释:大循环中有两个循环,一个是从右往左,找比基准点小的,一个是从左往右找比基准点大的(找到之后,与基准点交换位置)。最终大循环,在left>=right时结束。
(2) 快排拆分:
Java common sorting algorithm
解释:使用递归的方式,将数组左右两边一次次拆分,直到left>=right时,递归结束。
  代码实现:

public class QuickSort {
    public static void main(String[] args) {
        int arr[]= {2,7,1,2,8,1,3,9,415,189,123};
        sort(arr,0,arr.length-1);
        System.out.println(Arrays.toString(arr));
    }
    public static void sort(int [] arr,int left ,int right) {
        //递归的出口,当左侧==右侧
        if(left>=right) {
            return;
        }
        //获取基准点
        int point=getPoint(arr,left,right);
        //左边排序(递归)
        sort(arr,left,point-1);
        //右边排序(递归)
        sort(arr,point+1,right);
    }
    public static  int getPoint(int [] arr,int left ,int right) {
        int key=arr[left];
        while(left<right) {
            //从右向左循环,只要右边的比基准点大,就继续循序
            while(key<=arr[right]&&left<right) {
                //每循环一次,right的索引向左移一个
                right--;
            }
            //交换基准点的位置
            arr[left]=arr[right];
            //从左向右循环,只要左边的比基准点小,就继续循序
            while(arr[left]<=key&&left<right) {
                left++;
            }
            //交换基准点
            arr[right]=arr[left];
        }
        //最后给基准点赋值
        arr[left]=key;
        return left;
    }
}

注意:了解快速排序有助于了解MR的map-reduce过程,因为在MRmap阶段环形缓冲区满了之后,会将数据溢写到文件中,这个过程中就是使用了快速排序。

5. 计数排序

  原理:对一个已有数组进行排序,那么就新建一个数组,数组长度为数组中元素的最大值+1。并把已有数组中的元素,对应上新建数组的下标,放入里面,新建数组的元素为,已有数组中元素的出现次数。
  原理图:
Java common sorting algorithm
解释:新创建一个数组,长度为需要排序的数组的最大值+1,遍历数组,将数组中的值分别找到新数组的索引,将索引处的元素+1,最后,遍历输出新数组的下标(只输出相应的值>0的下标,并且值为多少就输出几次)。
  代码实现:

public class CountSort {
    public static void main(String[] args) {
        int arr[]= {2,7,1,2,8,1,3,9,415,189,123};
        sort(arr,415);
        System.out.println(Arrays.toString(arr));
    }
    public static void sort(int arr[],int max) {
        int index=0;
        int newarr[]=new int [max+1];
        for(int i=0;i<arr.length;i++) {
            newarr[arr[i]]++;
        }
        for(int i=0;i<newarr.length;i++) {
            if(newarr[i]!=0) {
                for(int j=0;j<newarr[i];j++) {
                    arr[index++]=i;
                }
            }
        }
    }
}

注意:了解计数排序,有助于了解hbase的布隆过滤器,布隆过滤器的特点就是,我说没有就没有,我说有不一定有(有一定的误判率)。

6. 归并排序(两路)

Principle: The sort order for multiple data sets. (Time complexity: n * logN)
merge sort has two stages:
a normalization is: to split the data set in each of the small data set only one element.
Achieve a normalized data set :

public static void chai(int arr[],int first,int last,int [] newarr) {
        if(first>=last) {
            return;
        }
        //找中间点
        int mid=(first+last)/2;
        //左边归
        chai(arr,first,mid,newarr);
        //右侧拆
        chai(arr,mid+1,last,newarr);
        //拆完之后并
        meger(arr,first,last,mid,newarr);
}

And a is: the two ordered sets of data, ordered merged into a large data set.
Achieve two data sets and ordered:

public int[] bing(int arr1[], int arr2[]) {
        //创建一个最终结果的数组:长度为arr1和arr2长度之和
        int newarr[] = new int[arr1.length+arr2.length];
        //新数组的元素标记
        int index=0;
        //记录arr1和arr2的下标
        int arr1_index=0;
        int arr2_index=0;
        //只要有一个数组,遍历结束,就停止循环
        while(arr1_index<arr1.length&&arr2_index<arr2.length) {
            //进行判断,将数据存储在新数组中
            if(arr1[arr1_index]<arr2[arr2_index]) {
                newarr[index++]=arr1[arr1_index++];
            }else {
                newarr[index++]=arr2[arr2_index++];
            }
        }
        //可能是arr1没有遍历完全
        while(arr1_index<arr1.length) {
            newarr[index++]=arr1[arr1_index++];
        }
        //可能是arr2没有遍历完全
        while(arr2_index<arr2.length) {
            newarr[index++]=arr2[arr2_index++];
        }
        return newarr;
    }

Achieve complete code:

public class bingSort {
    public static void main(String[] args) {
        int arr[]= {1,8,7,6,11,2,4};
        int newarr[]=new int[arr.length];
        System.out.println(Arrays.toString(arr));
        chai(arr,0,arr.length-1,newarr);
        System.out.println(Arrays.toString(newarr));
    }
    //归
    public static void chai(int arr[],int first,int last,int [] newarr) {
        if(first>=last) {
            return;
        }
        //找中间点
        int mid=(first+last)/2;
        //左边归
        chai(arr,first,mid,newarr);
        //右侧拆
        chai(arr,mid+1,last,newarr);
        //拆完之后并
        meger(arr,first,last,mid,newarr);
    }
    /**
     *  并
     * @param arr 原数组
     * @param first 开始位置
     * @param last 结束位置
     * @param mid 中间位置
     * @param newarr  存放最终结果的数组
     */
    public static void meger(int arr[],int first,int last,int mid,int [] newarr) {
        //第一个数据集的起始下标
        int arr1_start=first;
        //第一个数据集的终止下标
        int arr1_end=mid;
        //第二个数据集的起始下标
        int arr2_start=mid+1;
        //第二个数据集的终止下标
        int arr2_end=last;
        int index=0;
        while(arr1_start<=arr1_end&&arr2_start<=arr2_end) {
            if(arr[arr1_start]<arr[arr2_start]) {
                newarr[index++]=arr[arr1_start++];
            }else {
                newarr[index++]=arr[arr2_start++];
            }
        }
        while(arr1_start<=arr1_end) {
            newarr[index++]=arr[arr1_start++];
        }
        while(arr2_start<=arr2_end) {
            newarr[index++]=arr[arr2_start++];
        }
        /**
         * 因为归并排序,需要使用两个有序的数据集,而arr一开始时无需的,所有每一次归并的时候
         * 需要将归并好之后的那一段数据集,赋值到arr中,使之后的归并仍然有序
         */
        //赋值的循环的次数,是本次归并的元素的个数
        for(int i=0;i<index;i++) {
            //每次赋值的时候,是从first开始
             arr[first+i]=newarr[i];
        }
    }
}

Note: In the MR program in which there are two phases to use the merge, is a buffer overflow when writing small files, will finally merge multiple small files into one large file, the other is in the process reduce got me a map the local data is to generate a lot of small files, this time will do a merge.

7. a binary search data

  Principle: the foundation has been sorted on the array element binary search.
  Schematic:
Java common sorting algorithm

  Code:

public static void main(String[] args) {
        int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
        // 二分法查数据
        int num = new Scanner(System.in).nextInt(); //查找的数
        int start = 0;
        int end = arr.length - 1;
        int middle = (start + end) / 2;
        while (true) {
          //如果end<start说明全部找完也没有找到
            if (end < start) {
                System.out.println(num + "不在此数组中");
                break;
            }
            if (arr[middle] > num) {
                end = middle - 1;
            } else if (arr[middle] < num) {
                start = middle + 1;
            } else {
                System.out.println("这个数的索引下标为" + middle);
                break;
            }
            middle = (start + end) / 2;
        }

Guess you like

Origin blog.51cto.com/14048416/2426016