首页 > 编程语言 > 详细

排序算法

时间:2021-01-09 23:17:02      阅读:31      评论:0      收藏:0      [点我收藏+]

排序

常见排序列表

技术分享图片

背的技巧

技术分享图片


选择排序

最简单但是也是最没用的一种算法。(时间复杂度N方,还不稳定)。

时间复杂度:N方

空间复杂度:1

基本思想是:第一次从 arr[0]~arr[n-1]中选取最小值,与 arr[0]交换;第二次从 arr[1]~arr[n-1]中选取最小值,与 arr[1]交换;第 n-1 次从 arr[n-2]~arr[n-1]中选取最小值,与 arr[n-2]交换,总共通过 n-1 次,得到一个按排序码从小到大排列的有序序列。

代码实现

public class 选择排序 {
    public static void main(String[] args) {
    int arr[] = {1,3,2,4,5};
     //返回数组的字符串形式
     System.out.println("排序前:"+Arrays.toString(arr));
     Arrays.toString(arr)
     System.out.println("排序后:"+Arrays.toString(arr)); 
        }
    
    //选择排序算法 
    public static void SelectSort(int [] arr){
         for(int i = 0;i < arr.length-1;i++){
            int minPos = i;
            for(int j = i+1;j < arr.length;j++){
                if(arr[minPos] > arr[j]){
                    minPos = j;
                }
                //交换两个数
                swap(arr,minPos,i);
            }    
            System.out.println(Arrays.toString(arr));
        }
        
        //交换两个数
         public static void swap(int [] arr){
              	int temp=arr[i];
        		arr[i]=arr[j];
        		arr[j]=temp;
         }
        
    }

算法验证—对数器

class DataChecker{

    public static int []  Random(){
        Random r = new  Random();
        int [] arr = new int[10000];
        for(int i=0;i<arr.length;i++){
            arr[i]=r.nextInt(10000);
        }
        return arr;
    }

    public static void Check(){
        int arr [] = Random();
        int arr2 [] = new int [arr.length];
        System.arraycopy(arr,0,arr2,0,arr.length);

        Arrays.sort(arr);
        SelectSort(arr2);

        boolean flag=true;
        for(int i =0;i<arr.length;i++){
            if(arr[i]!=arr2[i]){
                flag=false;
                break;
            }
        }
        if(flag){
            System.out.println("正确");
        }
        else{
            System.out.println("错误");
        }
    }
        //选择排序算法 
    public static void SelectSort(int [] arr){
         for(int i = 0;i < arr.length-1;i++){
            int minPos = i;
            for(int j = i+1;j < arr.length;j++){
                if(arr[minPos] > arr[j]){
                    minPos = j;
                }
                //交换两个数
                swap(arr,minPos,i);
            }    
            System.out.println(Arrays.toString(arr));
        }
        
        //交换两个数
         public static void swap(int [] arr){
              	int temp=arr[i];
        		arr[i]=arr[j];
        		arr[j]=temp;
         }
        
    }
    
}

学习知识点:

选择排序

对数器

在第二个循环中,不能直接交换两个数,会改变数组中的元素,定义一个mindex代替循环变量j。

    if(arr[minPos]>arr[j]){//前面的并不是最小值,交换两个值
                    minPos=j;
                }
				//交换两个数
                swap(arr,minPos,i);

冒泡排序

冒泡排序:从前向后遍历,依次比较相邻元素的值,若发现相邻元素则交换,这样遍历完一次可以让最大元素放在最后。

优化:在排序的过程中,各元素的位置不断的靠近自己的位置,如果在一趟比较下来没有发生果交换,就说明序列已经排好序。

代码实现

package 排序算法;

import java.util.Arrays;

public class 冒泡排序 {
    public static void main(String[] args) {
        int arr[]={3,9,-1,10,20};
        String s = Arrays.toString(arr);//返回数组的字符串形式。
        System.out.println(s);
        bubblesort(arr);
        String ss = Arrays.toString(arr);
        System.out.println(ss);

    }

    public static void bubblesort(int[] arr){
        int temp=0;//临时变量
        boolean flag=false;//标识变量,表示是否发生过交换
        for(int i=0;i<arr.length-1;i++){//表示要进行N-1趟
            for(int j=0;j<arr.length-1-i;j++){//每一次遍历要将大的数放在后面
               /*
                //如果是逆序,则交换两个元素
                temp=arr[j];
                arr[j]=arr[j+1];
                arr[j+1]=temp;
                */
               if(arr[j]>arr[j+1]){
                   flag=true;
                   arr[j]=arr[j]^arr[j+1];
                   arr[j+1]=arr[j]^arr[j+1];
                   arr[j]=arr[j]^arr[j+1];
               }
            }
            //优化
            if(!flag){//在一趟中没有发生交换
                break;
            }
            else{
                flag=false;//重置flag,进行下次判断
            }
        }
    }
}

学习知识点:

冒泡排序算法

Arrarys类

String s = Arrays.toString(arr);//返回数组的字符串形式。

插入排序

开始时有序表中只包含一个元素,无序表中包含有 n-1 个元素,排序过程中每次从无序表中取出第一个元素,把它的排序码依次与有序表元素的排序码进行比较,将它插入到有序表中的适当位置,使之成为新的有序表。

代码实现

    //插入排序
    public static void insertsort(int[] arr){
        //从下标为1的元素开始选择合适的位置插入,因为下标为0的只有一个元素,默认是有序的
        for(int i=1;i<arr.length;i++){
            // 记录要插入的数据
            int temp=arr[i];
            // 从已经排序的序列最右边的开始比较,找到比其小的数
            int j=i;
            while (j>0&&temp<arr[j-1]){
                arr[j]=arr[j-1];//用于查找前面是否有更小的值
                j--;
            }
            // 存在比其小的数,插入
            if(j!=i){
                arr[j]=temp;
            }
        }
    }

学习知识点:

插入排序

注意在前面的有序列表中找到要插入的位置。


希尔排序

简单排序存在的问题:当我们插入的数较小时,后移的次数明显增多,对效率有很大影响。

希尔排序示意图

技术分享图片

代码实现

    //希尔排序
    public static void shellSort(int[] arr) {
        int length = arr.length;
        int temp;
        for (int step = length / 2; step >= 1; step /= 2) {
            for (int i = step; i < length; i++) {
                temp = arr[i];
                int j = i - step;
                while (j >= 0 && arr[j] > temp) {
                    arr[j + step] = arr[j];
                    j -= step;
                }
                arr[j + step] = temp;
            }
        }
    }

快速排序

在排序的数列中,我们首先找一个数为基准,所有大于基准的数放在右边,小于基准的数全部放在左边,最后将基准数归位。

算法示意图

技术分享图片

代码实现

    //快速排序
    public static void quickSort(int [] arr,int left,int right){

        if(left>right){
            return;
        }
        int i=left;
        int j=right;
        int t;//做临时变量,用来交换
        int temp=arr[left];
        while(i!=j){
            while(arr[j]>=temp&&i<j){
                j--;
            }
            while(arr[i]<=temp&&i<j){
                i++;
            }
            if(i<j){//表示哨兵还没有相遇,交换两个数
                t=arr[i];
                arr[i]=arr[j];
                arr[j]=t;
            }
        }
            arr[left]=arr[i];
            arr[i]=temp;

        quickSort(arr,left,i-1);//向左递归                 
        quickSort(arr,i+1,right);//向右递归
        return;
    }

归并排序

时间复杂度:NlgN

空间复杂度:O(N)

附加知识点:归并排序是稳定的,在java中经常使用。在Java中,对于Java对象的排序一般要求都是稳定的。在java中,使用TimMeragr(改进的归并排序) 对一个数组分多个组进行排序,最后两两进行归并排序。在小组内部使用二分插入排序。

算法示意图

技术分享图片

两个有序的数组合并为一个有序数组

技术分享图片

需要定义三个指针,一个临时数组temp;指向左边数组的指针i;指向右边数组的指针j;指向临时数组的指针k。

比较左右两边的数值,数值小的赋值给temp,然后自身向后++。当一边结束后,将另一边剩下的值全部赋值给temp即可。

//归并排序
    public static void mergeSort(int [] arr,int left,int right){
        //只有一个元素
        if(left==right){
            return;
        }
        //将数组分成两半
        int mid=left+(right-left)/2;
        //左边排序
        mergeSort(arr,left,mid);
        //右边排序
        mergeSort(arr,mid+1,right);
        //归并两个有序数组
        merge(arr,left,mid+1,right);
    }
    public static void merge(int [] arr,int leftPtr,int rightPtr,int rightBound){
        //将需要的数组一分为二
        int mid=rightPtr-1;
        int i=leftPtr;
        int j=rightPtr;
        int k=0;
        int [] temp=new int[rightBound-leftPtr+1];
        //循环将数组有序添加到临时数组
        while(i <= mid  && j <= rightBound){//可以用三元运算符写
            temp[k++] = arr[i] <= arr[j] ? arr[i++] : arr[j++];
           /*
            if(arr[i] <= arr[j]){
                temp[k] = arr[i];
                i++;
                k++;
            }
            else{
                temp[k] = arr[j];
                j++;
                k++;
            }
            */

        }
        //判断那边的数组没有遍历完
        while(i <= mid) temp[k++] = arr[i++];
        while(j <= rightBound) temp[k++] = arr[j++];
        //将临时数组的值复制到arr数组
        for(int m=0;m<temp.length;m++) arr[leftPtr+m]=temp[m];
    }

排序算法

原文:https://www.cnblogs.com/nj123/p/14256789.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!