数组排序学习

数组

二分查找

二分查找要求数组排列时有序的

在这里插入图片描述

八种常见的排序

1.冒泡排序

2.选择排序

3.插入排序

4.希尔排序

5.快速排序

6.归并排序

7.基数排序

8.堆排序

冒泡排序

排序原理:数组元素两两比较,交换位置,大元素往后放,那么经过一轮比较后,最大的元素就会出现在最大的索引处

在这里插入图片描述

public class ArrayDemo{
    public static void main(String[] args){
        int[] arr={24,69,80,57,13};
        for(int j=0;j<arr.length-1;j++){
            for(int i=0;i<arr.length-1-j;i++){
            if(arr[i]>arr[i+1]){
                int t=arr[i];
                arr[i]=arr[i+1];
                arr[i+1]=t;
            }
        }
        }
        System.out.println(Arrays.toString(arr));
    }
}

选择排序

排序原理:从0索引处开始,依次和后面的元素进行比较,小的元素往前放,经过一轮比较后,最小的元素就出现在最小的索引处

在这里插入图片描述

public class ArrayDemo{
    public static void main(String[] args){
        int[] arr={24,69,80,57,13};
        for(int index=0;index<arr.length-1;index++){
            for(int i=1+index;i<arr.length;i++){
             if(arr[index]>arr[i]){
                int t=arr[index];
                arr[index]=arr[i];
                arr[i]=t;
            }
          }
        }
        System.out.println(Arrays.toString(arr));
    }
}

插入排序

排序原理:直接插入排序是一种简单的排序方法,他的基本操作是将一个记录插入到长度为m的有序表中,使之还是保持有序

在这里插入图片描述

public class ArrayDemo{
    public static void main(String[] args){
        int[] arr={49,38,65,97,76,13,27};
        //外层循环定义轮次
        //方法一
       /* for(int i=0;i<arr.length;i++){
            int j=i;
            while(j>0&&arr[j]<arr[j-1]){
                int t=arr[j];
                arr[j]=arr[j-1];
                arr[j-1]=t;
                j--;
            }
        }*/
        //方法二
        for(int i=0;i<arr.length;i++){
            for(int j=i;j>0;j--){
                if(arr[j]<arr[j-1]){
                    int t=arr[j];
                    arr[j]=arr[j-1];
                    arr[j-1]=t;
                }
            }
        }
        System.out.println(Arrays.toString(arr));
    }
}

希尔排序

希尔排序是对直接插入排序的一种优化,大大提高插入排序的执行效率

希尔排序又称缩小增量排序

基本思想:先将原表按增量ht分组,每个子文件按照直接插入法排序。同样,用下一个增量ht/2将文件再分为子文件,再直接插入法排序。直到ht=1时,整个文件排序完成

关键:选择合适的增量

直接插入排序就是增量为一的希尔排序

public class ArrayDemo{
    public static void main(String[] args){
        int[] arr={46,55,13,42,17,94,5,70};
        shellSort(arr);
        System.out.println(Arrays.toString(arr));
    }
    public static void shellSort(int[] arr){
        //定义增量
        //第一次增量选取数组长度的一半,然后不断减半
           /*for(int h=arr.length/2;h>0;h--){
               for(int i=h;i<arr.length;i++){
               for(int j=i;j>h-1;j-=h){
                if(arr[j]<arr[j-h]){
                    int t=arr[j];
                    arr[j]=arr[j-h];
                    arr[j-h]=t;
                }
            }
         }
         }*/
        //有一种效率更高的序列叫克努特序列
        //根据克努特序列选取我们第一个增量
        int jiange=1;
        while(jiange<=arr.length/3){
            jiange=jiange*3+1;
        }
        for(int h=jiange;h>0;h=(h-1)/3){
               for(int i=h;i<arr.length;i++){
               for(int j=i;j>h-1;j-=h){
                if(arr[j]<arr[j-h]){
                    int t=arr[j];
                    arr[j]=arr[j-h];
                    arr[j-h]=t;
                }
            }
         }
         }
        
    }
}

快速排序

分治方法:比大小,再分区

1.从数组中取出一个数作为基准数

2.分区:将比这个数大或者等于的数全部放到他右边,小于他的数放到他左边

3.对左右区间重复第二步,直到个区间只有一个数

实现思路:

挖坑填数

1.将基准数挖出形成第一个坑

2.由后向前找比他小的数,找到后挖出此数填到前一个坑中

3.由前向后找比他大或者等于的数,找到后挖出此数填到前一个坑中

4.再重复执行2.3两步

public class ArryDemo{
    public static void main(String[] args){
        int[] arr={10,3,5,6,1,0,100,40,50,8};
        quickSort(arr,0,arr.length-1);
        System.out.println(Arrays.toString(arr));
    }
    public static void quickSort(int[] arr,int start,int end){
        if(start<end){
            int index=getIndex(arr,start,end);
            quickSort(arr,start,index-1);
            quickSort(arr,index+1,end);
        }
    }
    private static int getIndex(int[] arr,int start,int end){
        int i=start;
        int j=end;
        int x=arr[i];
        while(i<j){
            //由后向前找比他小的数,找到后挖出此数填到前一个坑中
            while(i<j&&arr[j]>=x){
                j--;
            }
            if(i<j){
                arr[i]=arr[j];
                i++;
            }
            //由前向后找比他大或者等于的数,找到后挖出此数填到前一个坑中
            while(i<j&&arr[i]<x){
                i++;
            }
            if(i<j){
                arr[j]=arr[i];
                j--;
            }
        }
        //将基准数挖出形成第一个坑
        arr[i]=x;
        return i;
    }
}

归并排序

在这里插入图片描述

实现思路:假设初始序列有n个记录,则可以看成是n个有序的子序列,每个子序列长度为1,然后两两归并,得到n/2个长度为2或1的有序子序列,再两两归并。。。如此重复,直到得到一个长度为n的有序序列为止,这种排序方法称为2路归并排序

public class ArryDemo{
    public static void main(String[] args){
        int[] arr={10,30,2,1,0,8,7,5,19,29};
        chaifen(arr,0,arr.length-1);
        System.out.println(Arrays.toString(arr));
    }
    public static void chaifen(int arr[],int startIndex,int endIndex){
        //计算中间索引
        int centerIndex=(startIndex+endIndex)/2;
        if(startIndex<endIndex){
            chaifen(arr,startIndex,centerIndex);
            chaifen(arr,centerIndex+1,endIndex);
            guiBing(arr,startIndex,centerIndex,endIndex);
        }
    }
    public static void guiBing(int[] arr,int startIndex,int centerIndex,int endIndex){
        //定义零时数组
        int[] tempArr=new int[endIndex-startIndex+1];
        //定义左边数组的起始索引
        int i=startIndex;
        //定义右边数组的起始索引
        int j=centerIndex+1;
        //定义零时数组的起始索引
        int index=0;
        //比较左右两边数组元素的大小,往临时数组中放
        while(i<=centerIndex&&j<=endIndex){
            if(arr[i]<=arr[j]){
                tempArr[index]=arr[i];
                i++;
            }else{
                tempArr[index]=arr[j];
                j++;
            }
            index++;
        }
        //处理剩余元素
        while(i<=centerIndex){
            tempArr[index]=arr[i];
            i++;
            index++;
        } 
        while(j<=endIndex){
            tempArr[index]=arr[j];
            j++;
            index++;
        }
        for(int k=0;k<tempArr.length;k++){
            arr[k+startIndex]=tempArr[k];
        }
    }
}

基数排序

由于略有区别,这里就先不过多介绍,下次再补!

堆排序

堆排序是利用堆这种数据结构设计出的一种排序算法,堆排序是一种选择排序

堆排序的基本思想:

1.将待排序序列构造成一个大顶堆,此时,整个序列最大值是堆顶的根节点。

2.将其与尾部元素交换,此时尾部就为最大值

3.然后将剩余n-1个元素重新构造为一个堆,这样就会得到n个元素的次小值

4.如此反复执行,便得到一个有序序列

升序排列使用大顶堆,降序排列使用小顶堆

我们用简单的公式来描述一下堆的定义就是:

​ 左节点 右节点

大顶堆:arr[i]>arr[2i+1]&&arr[i]>=arr[2i+2]

小顶堆:arr[i]<arr[2i+1]&&arr[i]<=arr[2i+2]

public class ArryDemo{
    public static void main(String[] args){
        int[] arr={1,0,6,7,2,3,4};
        //定义开始调整位置
        int startIndex=(arr.length-1)/2;
        //循环开始
        for(int i=startIndex;i>=0;i--){
            toMaxHeap(arr,arr.length,i);
        }
        System.out.println(Arrays.toString(arr));
        //经过上面操着,已经将数组变为一个大顶堆,把根元素和最后一个元素进行调换
        for(int i=arr.length-1;i>0;i--){
            int t=arr[0];
            arr[0]=arr[i];
            arr[i]=t;
            toMaxHeap(arr,i,0);
        }
        System.out.println(Arrays.toString(arr));
    }
    /**
    *@param arr 要排序的数组
    *@param size 调整元素的个数
    *@param index 从哪里开始调整
    **/
    private static void toMaxHeap(int[] arr,int size,int index){
        //获取左右结点的索引
        int leftNodeIndex=index*2+1;
        int rightNodeIndex=index*2+2;
        //查找最大结点对应的索引
        int maxIndex=index;
        if(leftNodeIndex<size&&arr[leftNodeIndex]>arr[maxIndex]){
            maxIndex=leftNodeIndex;
        }
        if(rightNodeIndex<size&&arr[rightNodeIndex]>arr[maxIndex]){
            maxIndex=rightNodeIndex;
        }
        //调换位置
        if(maxIndex!=index){
            int t=arr[maxIndex];
            arr[maxIndex]=arr[index];
            arr[index]=t;
            //调整完可能影响到下面的子树不是大顶堆,我们还需要继续再次调整
            toMaxHeap(arr,size,maxIndex);
        }
    }
}

觉得不错的话点个赞呗~~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值