八大常见排序算法总结(JAVA实现)

目录

1.选择排序

2、冒泡排序

 3、快速排序

4、归并排序

5、基数排序

6、插入排序

7、希尔排序 

8、堆排序

 

学习总结:

        排序算法中,选择排序和冒泡排序比较简单,两次循环就可以求解;

  1.选择排序

public class SelectSort {
    public static void main(String[] args) {
        int[] array = new int[]{4, 2, 6, 7, 3, 10, 4, 1, 9, 8};
        selectSort(array);
        System.out.println("选择排序:"+Arrays.toString(array));
    }
    //遍历所有的数,将当前遍历的数与后面的所有数进行比较,选择最小的数放在前面
    public static void selectSort(int[] array){
        for (int i = 0; i < array.length; i++){
            int minIndex = i;
            for(int j = i+1; j < array.length; j++){
                if(array[minIndex] > array[j]){
                    minIndex = j;
                }
            }
            if(minIndex != i){
                int temp = array[i];
                array[i] = array[minIndex];
                array[minIndex] = temp;
            }
        }
    }
}

2、冒泡排序

public class BubbleSort {
    public static void main(String[] args) {
        int[] array = new int[]{4,2,6,7,3,10,4,1,9,8};
        bubbleSort(array);
        System.out.println("冒泡排序:"+ Arrays.toString(array));
    }

    public static void bubbleSort(int[] array) {
        for (int i = 0; i < array.length-1;i++){
            for(int j = 0;j < array.length-1-i; j++){
                if(array[j] > array[j+1]){
                    int temp = array[j];
                    array[j] = array[j+1];
                    array[j+1] = temp;
                }
            }
        }

    }
}

 3、快速排序

        快速排序选择一个标准比较值,分别从左边和右边与标准值进行比较,第一次比较完之后,以比较值为分界线,左边比比较值小,右边比比较值大,根据这个结果,可以继续这种算法,即进行递归,再将两部分的数组继续分别拆分成两部分数组。
       

public class QuickSort {
    public static void main(String[] args) {
        int[] array = new int[]{4,2,6,7,3,10,4,1,9,8};
        quickSort(array,0,array.length-1);
        System.out.println("快速排序:"+Arrays.toString(array));
    }
    public static void quickSort(int[] array, int start, int end) {
        if(start < end){//在方法中的左边的指针小于右边的指针时,才执行
            int low = start;
            int high = end;
            int comp = array[low];

            while (low < high) {//保证右边的指针不会跑到左边
                while (low < high && array[high] >= comp) {
                    //在右边的元素比标准大时,指针左移,但是需要保证不会移到比左边指针更小的位置
                    high--;
                }
                array[low] = array[high];//在右边的元素比标准小时,值赋给左边的元素
                //同理
                while (low < high && array[low] <= comp) {
                    low++;
                }
                array[high] = array[low];
            }
            //low = high时,将标准值赋给此位置的元素
            array[low] = comp;
            //处理排序后的左半部分元素
            quickSort(array, start, low - 1);
            //处理排序后的右半部分元素
            quickSort(array, low + 1, end);
        }
    }
}

4、归并排序

        归并排序是对于两个有序的数组来说,可以以此比较两个数组中的值,选取较小的值填入结果数组,为了得到两个有序的数组,首先需要进行递归,将数组拆分为更小的数组,使他们有序。

        

        快速排序:先排再递归

        归并排序:先递归再排

public class MergeSort {
    public static void main(String[] args) {
        int[] array = new int[]{4,2,6,7,3,10,4,1,9,8};
        mergeSort(array,0,array.length-1);
        System.out.println("归并排序:"+Arrays.toString(array));
    }
    
    public static void mergeSort(int[] array,int start,int end){
        if(start < end){
            int[] temp = new int[end - start + 1];//创建一个数组,用于存放排序后的结构
            int mid = (start + end)/2;//以mid为界限将数组分开
            int left = start;//左边数组的其实位置
            int right = mid+1;//右边数组的起始位置
            int index = 0;//temp数组中的下标
            //先递归,将数组分为两部分有序的数组,对其进行归并排序
            //左半部分,继续划分
            mergeSort(array,start,mid);
            //右半部分划分
            mergeSort(array,mid+1,end);
            //比较两部分数组中的值,选取小的值
            while (left <= mid && right <= end){
                if(array[left] <= array[right]){
                    temp[index++] = array[left++];
                }else {
                    temp[index++] = array[right++];
                }
            }
            //将数组中多余的元素取出,放入temp
            while (left <= mid){
                temp[index++] = array[left++];
            }
            while (right <= end){
                temp[index++] = array[right++];
            }
            //将排序后的数组赋给原数组
            for(int i = 0;i < temp.length;i++){
               array[i+start] = temp[i];
            }
        }
    }
}

5、基数排序

        将数组中所有的元素,从个位数开始,放入对应的桶中,然后从桶中按顺序取出,会得到对于小于2位数的元素来说有序的数组,然后再放入十位数字,取出后同样会得到对于小于3位数的元素来说的有序的数组。因此,放入数组中最大元素的所有位置的数字后,再取出,数组就变成有序的数组了。

public class RadixSort {
    public static void main(String[] args) {
        int[] array = new int[]{4,2,6,7,3,10,4,1,9,8};
        radixSort(array);
        System.out.println("基数排序:"+Arrays.toString(array));
    }

    public static void radixSort(int[] array){
        //先求出数组中最大值有几位数,以确定外层循环的次数
        int max = array[0];
        for(int i = 1;i < array.length;i++){
            if(array[i] > max){
                max = array[i];
            }
        }
        int maxLength = (max + "").length();//最大值的位数
        int[][] temp = new int[10][array.length];//用来存放数组中放入到桶中的元素,每位数有10种取值情况
        int[] count = new int[10];//计数,计算每位数的元素数量
        //确定比较次数,依次取元素的个位、十位、百位数......
        for(int i = 0,n = 1; i < maxLength;i++,n*=10){
            //遍历元素取余,并放入temp中相应的位置
            for (int j = 0;j < array.length; j++){
                int num = array[j]/n%10;//取余数
                temp[num][count[num]] = array[j];
                count[num]++;//余数为num的数量计数加1
            }
            //将temp中的元素取出,赋给原数组
            int index = 0;
            for(int k = 0; k < count.length;k++){
                if(count[k] != 0){
                    for(int l = 0;l < count[k]; l++) {
                        array[index] = temp[k][l];
                        index++;
                    }
                    count[k] = 0;
                }
            }
        }
    }
}

6、插入排序

        插入排序原理是从第2个元素开始,拿出这个元素与前面的所有元素比较,找到比它小的位置插入,其他的位置全部向右移一位。

public class InsertSort {
    public static void main(String[] args) {
        int[] array = new int[]{4,2,6,7,3,10,4,1,9,8};
        insertSort(array);
        System.out.println("插入排序:"+Arrays.toString(array));
    }

    public static void insertSort(int[] array){
        //原理是,遍历元素,将每个元素提出来,插入到正确的位置
        for(int i = 1; i < array.length;i++){//从第1位开始遍历,认为第0位是有序的
            int temp = array[i]; //记下需要比较的值
            int j;
            //遍历需要比较的值(temp)左边的所有元素
            //用temp与左边的值进行比较,如果小于,即将数组的元素右移,直到找到第一个比temp小的元素
            //将temp值赋给这个元素
            for(j = i ; j > 0 && temp <= array[j-1]; j--){
                array[j] = array[j-1];
            }
            array[j] = temp;
//            for(j = i-1 ; j >= 0 && temp <= array[j]; j--){
//                array[j+1] = array[j];
//            }
//            array[j+1] = temp;
        }
    }
}

7、希尔排序 

        希尔排序与插入排序类似,不过间隔不再是1,而是变换的间隔,一般第一次取数组长度的二分之一,之后继续除以2,知道间隔小于0,遍历所有的间隔值,其他的步骤与插入排序一样。希尔排序比插入排序更优的原因是,希尔排序会使数组相比数组来说更有序,遍历的次数比插入排序少。


public class ShellSort {
    public static void main(String[] args) {
        int[] array = new int[]{4,2,6,7,3,10,4,1,9,8};
        shellSort(array);
        System.out.println("希尔排序:"+Arrays.toString(array));
    }

    public static void shellSort(int[] array){
        //与插入排序类似,不过间隔不是1,而是gap

        //首先遍历gap的取值
        for(int gap = array.length/2; gap > 0; gap /= 2){
            //遍历元素,用插入排序的方法,注意是每隔gap取一个值
            for(int i = gap; i < array.length; i++){
                int j;
                int temp = array[i];
                for(j = i; j >= gap && temp < array[j-gap]; j -= gap){
                    array[j] = array[j-gap];
                }
                array[j] = temp;
            }
        }
    }
}

8、堆排序

        堆排序原理是,先将数组转换为大顶堆,然后将大顶堆中的第一个元素即最大的元素和最后一个元素交换,即最大的元素会在最后,然后最后一个元素不再参与排序,继续将数组转换成大顶堆,不过之后只需要将第一个元素重新转换就行了,然后同样将大顶堆的第一个元素和参与排序的最后一个元素位置进,循环上述操作。

public class HeapSort {
    public static void main(String[] args) {
        int[] array = new int[]{4,2,6,7,3,10,4,1,9,8};
        heapSort(array);
        System.out.println("堆排序:"+ Arrays.toString(array));
    }

    public static void heapSort(int[] array){
        //开始位置是最后一个非叶子节点
        int start = (array.length - 1)/2;
        //调整为大顶堆
        for(int i=start;i>=0;i--){
            maxHeap(array,array.length,i);
        }
        //先把数组中的第0个和堆中的最后一个数交换位置,再把前面的处理为大顶堆。
        for (int i = array.length-1;i>0;i--){
            int temp = array[0];
            array[0] = array[i];
            array[i] = temp;
            //只需将为位置0处重新转换为大顶堆,其它地方已经是大顶堆了
            //并且不再包含交换的元素,其已经是需要排序的元素中最大的值了,不再参与排序
            //因此size为i,即每次循环的时候减1,直至最后一个元素
            maxHeap(array,i,0);
        }
    }

    //将数组转换为大顶堆
    public static void maxHeap(int[] array,int size,int index){
        int leftNode = 2*index + 1;//左子节点
        int rightNode = 2*index + 2;//右子节点
        int max = index; //从当前节点index开始
        //和两个子节点进行比较,找出最大的节点
        if(leftNode < size && array[leftNode] > array[max]){
            max = leftNode;
        }
        if(rightNode < size && array[rightNode] > array[max]){
            max = rightNode;
        }
        //交换位置
        if(max != index){
            int temp = array[index];
            array[index] = array[max];
            array[max] = temp;
            //交换位置后,可能会破坏之前排好的堆,因此重新调整之前排好的堆
            maxHeap(array,size,max);
        }
    }
}


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值