排序算法的代码简单实现

一.冒泡算法

冒泡排序(Bubble Sort)是一种简单的排序算法,因其基本操作过程中较小的元素逐渐“浮”到数组前端而得名。下面是冒泡排序的详细说明:
基本原理
比较相邻元素:算法重复地遍历待排序的数列,一次比较两个元素,如果它们的顺序(如从小到大或从大到小)错误就把它们交换过来。
重复遍历:每次遍历都会使未排序的部分中最大(或最小)的元素“冒泡”到数列的一端。
减少检查次数:每一轮遍历后,由于最大的元素已经“冒泡”到了正确的位置,下一轮遍历时可以略过数组的末尾部分,减少不必要的比较。
终止条件:当整个数列变成有序时,算法结束。
特点
时间复杂度:平均和最坏情况下时间复杂度均为O(n^2),其中n是数组长度。最好情况下(即数组已经是排序状态)时间复杂度为O(n)。
空间复杂度:O(1),因为它是原地排序,不需要额外的存储空间。
稳定性:冒泡排序是稳定的排序算法,即相等的元素的相对顺序不会改变。

import java.util.Arrays;
public class BubbleSort {
    public static void main(String[] args) {
        int[]arr=new int[10];
        for (int i = 0; i <arr.length ; i++) {
            arr[i]=(int)(Math.random()*100+1);
        }
        System.out.println(Arrays.toString(arr));
        System.out.println("------------------------");
        //升序:
        for (int i = 0; i < arr.length-1 ; i++) {
            for (int j = 0; j < arr.length-1-i ; j++) {
                if (arr[j]>arr[j+1]) {
                    int temp=arr[j];
                    arr[j]=arr[j+1];
                    arr[j+1]=temp;
                }
                System.out.println(Arrays.toString(arr));

            }
            System.out.println();
        }
        System.out.println("----------------------");
        //降序:
        for (int i = 0; i < arr.length; i++) {
            for (int j = 0; j < arr.length-1-i; j++) {
                if (arr[j]<arr[j+1]){
                    int temp=arr[j];
                    arr[j]=arr[j+1];
                    arr[j+1]=temp;
                }
                System.out.println(Arrays.toString(arr));
            }
            System.out.println();
        }

 }

对冒泡排序所用时间以及排序中交换次数的比较的输出

import java.util.Arrays;
import java.util.Random;

public class BubbleSort2 {
    public static void main(String[] args) {
        /*
        int[]arr=new int[10];
        for (int i = 0; i <arr.length ; i++) {
            arr[i]=(int)(Math.random()*100+1);
        }
        System.out.println(Arrays.toString(arr));
        System.out.println("------------------------");

         */
        Random random=new Random();
        int numberbound=100;
        int numbercount=50;
        int[]arr=new int[numbercount];
        for (int i = 0; i < arr.length; i++) {
            arr[i]=random.nextInt(numberbound);
        }
        System.out.println(Arrays.toString(arr));
        //比较次数:
        int compareCount=0;
        //交换次数:
        int swapCount =0;
        //循环开始时间
        long startTime=System.currentTimeMillis();
        for (int i = 0; i < arr.length-1 ; i++) {
            for (int j = 0; j < arr.length-1-i ; j++) {
                compareCount++;
                if (arr[j]>arr[j+1]) {
                    swapCount++;
                    int temp=arr[j];
                    arr[j]=arr[j+1];
                    arr[j+1]=temp;
                }
                System.out.println(Arrays.toString(arr));

            }
            System.out.println();
        }
        //循环结束时间:
        long endTime=System.currentTimeMillis();
        System.out.println("循环运行时间为"+(endTime-startTime));
        System.out.println("循环比较次数为"+compareCount);
        System.out.println("循环交换次数为"+swapCount);
    }
}

二.插入排序

插入排序(Insertion Sort)是一种简单直观的排序算法,它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。以下是插入排序的详细步骤和示例代码。
基本步骤
从第一个元素开始,该元素可以认为已经被排序。
取出下一个元素,在已经排序的元素序列中从后向前扫描。
比较:如果该元素(已排序)大于新元素,将该元素移到下一位置。
重复步骤3,直到找到已排序的元素小于或等于新元素的位置。
将新元素插入到该位置。
重复步骤2~5。
特点
时间复杂度:平均和最坏情况下时间复杂度均为O(n^2),其中n是数组长度。最好情况下(即数组已经是排序状态)时间复杂度为O(n)。
空间复杂度:O(1),因为它是在原地进行排序,不需要额外的存储空间。
稳定性:插入排序是稳定的排序算法,即相等的元素的相对顺序不会改变。

import java.util.Arrays;
import java.util.Random;
import java.util.Scanner;

public class InsertionSort {
    public static void main(String[] args) {
        Scanner scan=new Scanner(System.in);
        Random random=new Random();
        System.out.println("请输入数组长度:");
        int length=scan.nextInt();
        System.out.println("请输入数组取值范围");
        int bound= scan.nextInt();
        int[]arr=new int[length];
        for (int i = 0; i < arr.length; i++) {
            arr[i]= random.nextInt(bound);
        }
        System.out.println("原数组为"+ Arrays.toString(arr));

        //升序:
        for (int i = 1; i < arr.length ; i++) {
            int j= i;
            while (j>0){
                if(arr[j]<arr[j-1]){
                    int temp=arr[j];
                    arr[j]=arr[j-1];
                    arr[j-1]=temp;
                    j--;
                }else {
                    break;
                }
                System.out.println(Arrays.toString(arr));
            }
            System.out.println();
        }
        System.out.println("升序后的数组为"+Arrays.toString(arr));


        //降序:
        for (int i = 1; i < arr.length ; i++) {
            int j= i;
            while (j>0){
                if(arr[j]>arr[j-1]){
                    int temp=arr[j];
                    arr[j]=arr[j-1];
                    arr[j-1]=temp;
                    j--;
                }else {
                    break;
                }
                System.out.println(Arrays.toString(arr));
            }
            System.out.println();
        }
        System.out.println("降序后的数组为"+Arrays.toString(arr));
    }
}

三.归并排序

归并排序(Merge Sort)是一种分而治之的算法,其核心思想是将数组分成两半分别排序,然后将排序好的两部分合并在一起。下面是归并排序的详细步骤和示例代码。
基本步骤
分解:将当前区间一分为二,即求中点。
递归排序:递归地对两个子区间a[low...mid]和a[mid+1...high]进行归并排序。
合并:将已排序的两个子区间合并成一个有序区间。
特点
时间复杂度:无论最好、最坏还是平均情况,时间复杂度均为O(n log n),其中n是数组长度。
空间复杂度:需要O(n)的辅助空间来存放临时数组用于合并过程。
稳定性:归并排序是稳定的排序算法,即相等的元素的相对顺序不会改变。

 

import java.util.Arrays;

public class MergeSort {
    public static void main(String[] args) {
        int[]arr=new int[8];
        for (int i = 0; i <arr.length ; i++) {
            arr[i]=(int)(Math.random()*100+1);
        }
        System.out.println(Arrays.toString(arr));
        System.out.println("------------------------");
       int[]arr1=mergeSort(arr,0,arr.length-1);
        System.out.println(Arrays.toString(arr1));
        int[]arr2=mergeSort1(arr,0,arr.length-1);
        System.out.println(Arrays.toString(arr2));
    }
    //升序
    public static int[] mergeSort(int[]array,int start,int end){
        if(start==end){
            return new int[]{array[start]};
        }
        int mid=start+(end-start)/2;
        int []leftArray=mergeSort(array, start, mid);
        int []rightArray=mergeSort(array, mid+1, end);
        int []newArray=new int[leftArray.length+rightArray.length];
        int l=0,r=0,n=0;
        while (l<leftArray.length &&r<rightArray.length){
            newArray[n++]=leftArray[l]<=rightArray[r]?leftArray[l++]:rightArray[r++];
        }
        while (l<leftArray.length){
            newArray[n++]=leftArray[l++];
        }
        while (r<rightArray.length){
            newArray[n++]=rightArray[r++];
        }
        return newArray;
    }

    //降序
    public static int[] mergeSort1(int[]array,int start,int end){
        if(start==end){
            return new int[]{array[start]};
        }
        int mid=start+(end-start)/2;
        int []leftArray=mergeSort1(array, start, mid);
        int []rightArray=mergeSort1(array, mid+1, end);
        int []newArray=new int[leftArray.length+rightArray.length];
        int l=0,r=0,n=0;
        while (l<leftArray.length &&r<rightArray.length){
            newArray[n++]=leftArray[l]>=rightArray[r]?leftArray[l++]:rightArray[r++];
        }
        while (l<leftArray.length){
            newArray[n++]=leftArray[l++];
        }
        while (r<rightArray.length){
            newArray[n++]=rightArray[r++];
        }
        return newArray;


四.快速排序

快速排序(Quick Sort)是一种高效的排序算法,采用分治法策略,其基本思想是选择一个基准元素,通过一趟排序将待排序的记录分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。以下是快速排序的详细步骤和示例代码。
基本步骤
选择基准:从数列中挑出一个元素,称为“基准”(pivot)。
分区操作:重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。
递归排序:递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。
特点
时间复杂度:平均情况下时间复杂度为O(n log n),最坏情况下(数组已经是正序或逆序)为O(n^2),但可以通过随机选取基准元素来优化,使得最坏情况概率极低。
空间复杂度:O(log n),主要来自于递归调用栈的深度。
稳定性:快速排序不是稳定的排序算法,因为相等的元素可能会因为分区操作而改变原有的相对顺序。

 

import java.util.Arrays;

public class QuickSort {
    public static void main(String[] args) {
        int[]arr=new int[10];
        for (int i = 0; i <arr.length ; i++) {
            arr[i]=(int)(Math.random()*100+1);
        }
        System.out.println(Arrays.toString(arr));
        System.out.println("------------------------");
        QuickSort(arr,0, arr.length-1);
        System.out.println(Arrays.toString(arr));
    }

    public static void QuickSort(int[]array,int start,int end){
        int pivot=array[end];
        int x=start-1;
        for (int i = start; i <end ; i++) {
            if(array[i]<pivot){
                if(i-x>1){
                    int temp=array[i];
                    array[i]=array[x+1];
                    array[x+1]=temp;
                    x++;
                }else {
                    x=i;
                }
            }

        }
        if(pivot<array[x+1]){
            array[end]=array[x+1];
            array[x+1]=pivot;
        }
        if (x>start){
            QuickSort(array, start, x);
        }
        if(end-x-1>1){
            QuickSort(array, x+2, end);
        }

    }
}

五.希尔排序

希尔排序(Shell Sort)是插入排序的一种高效改进版本,由D.L. Shell于1959年提出。其核心在于将原始数据集合分成多个子序列,每个子序列进行插入排序,随着排序的进行,子序列的数量逐渐减少,直到最后整个数据集合变为一个子序列并完成排序。这种排序算法通过比较相距一定间隔的元素,间隔逐步减小,直至为1,来达到提高效率的目的。以下是希尔排序的基本步骤和特点:
基本步骤
选择增量序列:首先选择一个增量序列,初始增量较大,然后逐渐减小增量。
分组排序:将原始数据集合分成若干子序列,每个子序列包含相隔某个增量的元素,对每个子序列应用直接插入排序。
减小增量:按照预设的规则减小增量,重复步骤2,直到增量为1,此时进行最后一次直接插入排序。
特点
时间复杂度:最好的时间复杂度情况下可以达到O(n log^2 n),但最坏情况下仍可能是O(n^2),实际性能依赖于增量序列的选择。
空间复杂度:O(1),因为希尔排序是原地排序算法。
稳定性:希尔排序不是稳定的排序算法,因为在不同的子序列中插入排序可能破坏相等元素的原有顺序。

 

import java.util.Arrays;
import java.util.Random;
import java.util.Scanner;

public class ShellSort {
    public static void main(String[] args) {
        Scanner scan=new Scanner(System.in);
        Random random=new Random();
        System.out.println("请输入数组长度:");
        int length= scan.nextInt();
        System.out.println("请输入数组取值范围:");
        int bound=scan.nextInt();
        int[]arr=new int[length];
        for (int i = 0; i < arr.length; i++) {
            arr[i]= random.nextInt(bound);
        }
        System.out.println("原数组为"+ Arrays.toString(arr));

        //升序:
        for (int gap = arr.length/2; gap >0 ; gap/=2) {
            for (int i = gap; i < arr.length ; i++) {
                for (int j = i-gap; j >=0 ; j-=gap) {
                    if(arr[j]>arr[j+gap]){
                        int temp=arr[j];
                        arr[j]=arr[j+gap];
                        arr[j+gap]=temp;
                    }else {
                        break;
                    }
                    System.out.println(Arrays.toString(arr));
                }
                System.out.println();
            }
        }
        System.out.println("升序后的数组为"+Arrays.toString(arr));
        //降序:
        for (int gap = arr.length/2; gap >0 ; gap/=2) {
            for (int i = gap; i < arr.length ; i++) {
                for (int j = i-gap; j >=0 ; j-=gap) {
                    if(arr[j]<arr[j+gap]){
                        int temp=arr[j];
                        arr[j]=arr[j+gap];
                        arr[j+gap]=temp;
                    }else {
                        break;
                    }
                    System.out.println(Arrays.toString(arr));
                }
                System.out.println();
            }
        }
        System.out.println("降序后的数组为"+Arrays.toString(arr));

    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值