面试常见排序算法

冒泡排序

冒泡排序的基本思想是: 通过对待排序序列从前向后(从下标较小的元素开始),依次比较相邻元素的值,若发现逆序则交换,使值较大的元素逐渐从前移向后部,就象水底下的气泡一样逐渐向上冒。

1、比较两个相邻的数,如果前面的数大于后面的数,则将这两个数交换位置。第一次遍历后,最大的数会被放到数组的最后位置,即array[length - 1]。

2、第二次遍历时跳过最后一个元素,因为该元素通过第一次遍历已经确定是最大值。

3、持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

优点:冒泡排序算法简单,稳定可靠。

缺点:当数据量庞大并且乱序严重时,比较次数多,排序效率低。

public class Test {
    public static void main(String[] args) {
    int[] nums = {1,2,31,4,5,50};
        bubbleSort(nums);
        System.out.println(Arrays.toString(nums));
    }
     private static void bubbleSort(int[] nums){
        for(int i = 0;i<nums.length-1;i++){
            for(int j = 0;j< nums.length-i-1;j++){
                if(nums[j]>nums[j+1]){
                    int temp = nums[j];
                    nums[j] = nums[j+1];
                    nums[j+1] = nums[j];
                }
            }
        }
    }

}

快速排序

快速排序算法通过多次比较和交换来实现排序,其排序流程如下:
(1) 首先设定一个分界值通过该分界值将数组分成左右两部分
(2) 将大于或等于分界值的数据集中到数组右边,小于分界值的数据集中到数组的左边。此时,左边部分中各元素都小于或等于分界值,而右边部分中各元素都大于或等于分界值。
(3) 然后,左边和右边的数据可以独立排序。对于左侧的数组数据,又可以取一个分界值,将该部分数据分成左右两部分,同样在左边放置较小值,右边放置较大值。右侧的数组数据也可以做类似处理。
(4) 重复上述过程,可以看出,这是一个递归定义。通过递归将左侧部分排好序后,再递归排好右侧部分的顺序。当左、右两个部分各数据排序完成后,整个数组的排序也就完成了。
快速排序的优点是平均性能好,缺点是不稳定,如果初始序列是有序的,那么时间复杂度为O(n^2)。
public class Test {
    public static void main(String[] args) {
    int[] nums = {1,2,31,4,5,50};
    sort(nums,0,nums.length-1);
        System.out.println(Arrays.toString(nums));
    }
    public static void quickSort(int[] arr,int low,int high) {
        int i, j, temp, t;
        if (low > high) {
            return;
        }
        i = low;
        j = high;
        //temp就是基准位
        temp = arr[low];

        while (i < j) {
            //先看右边,依次往左递减
            while (temp <= arr[j] && i < j) {
                j--;
            }
            //再看左边,依次往右递增
            while (temp >= arr[i] && i < j) {
                i++;
            }
            //如果满足条件则交换
            if (i < j) {
                t = arr[j];
                arr[j] = arr[i];
                arr[i] = t;
            }
        }
        //最后将基准为与i和j相等位置的数字交换
        arr[low] = arr[i];
        arr[i] = temp;
        //递归调用左半数组
        quickSort(arr, low, j - 1);
        //递归调用右半数组
        quickSort(arr, j + 1, high);
    }
}

归并排序

归并排序是一种基于分治思想的排序算法,它将待排序的数组分成两部分,分别对这两部分递归地进行排序,最后将两个有序子数组合并成一个有序数组。它的时间复杂度为 O(nlogn)。

归并排序的基本思路是将待排序的数组分成两个部分,分别对这两部分进行排序,然后将排好序的两部分合并成一个有序数组。这个过程可以用递归来实现。具体的实现步骤如下:

分解:将待排序的数组不断分成两个子数组,直到每个子数组只有一个元素为止。

合并:将相邻的两个子数组合并成一个有序数组,直到最后只剩下一个有序数组为止。

合并的过程中,需要用到一个辅助数组来暂存合并后的有序数组。具体来说,假设待合并的两个有序数组分别为 A 和 B,它们的长度分别为 n 和 m,合并后的有序数组为 C,那么合并的过程可以按如下步骤进行:

定义三个指针 i、j 和 k,分别指向数组 A、B 和 C 的起始位置。

比较 A[i] 和 B[j] 的大小,将小的元素放入 C[k] 中,并将对应指针向后移动一位。

重复步骤 2,直到其中一个数组的元素全部放入 C 中。

将另一个数组中剩余的元素放入 C 中。

归并排序的优点是稳定性好,即对于相等的元素,在排序前后它们的相对位置不会改变。缺点是需要额外的空间来存储辅助数组。

public class Test {
    public static void main(String[] args) {
    int[] nums = {1,2,31,4,5,50};
        mergesort(nums,0, nums.length-1);
        System.out.println(Arrays.toString(nums));
    }    
    private static void mergesort(int[] nums,int left,int right){
        if(left>=right){
            return;
        }

        int mid = left+right>>1;
        mergesort(nums,left,mid);
        mergesort(nums,mid+1,right);

        int[] temp = new int[right-left +1];
        int k = 0,i = left,j = mid+1;

        while (i<=mid&&j<=right){
            if(nums[i]<nums[j]) temp[k++] = nums[i++];
            else temp[k++] = nums[j++];
        }
        while(i<=mid) temp[k++] = nums[i++];
        while (j<=right) temp[k++] = nums[j++];
        for(i = left,j = 0;i<=right;i++,j++)
            nums[i] = temp[j];


    }
}

 各种排序算法的复杂度比较

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值