面试手撕代码全集(排序)

本文深入探讨了八种主要的排序算法,包括冒泡排序、选择排序、插入排序、快速排序、归并排序、基数排序、希尔排序和堆排序。通过详细解释和示例,帮助读者理解每种排序算法的工作原理及其应用。
摘要由CSDN通过智能技术生成

更多见手撕代码全集


在这里插入图片描述

2.1 冒泡排序

public void BubbleSort(int[] data){
    int temp = 0;
    boolean flag = false;  //定义flag,当一趟循环没有交换时,表示完成排序
    for(int i = 0; i <data.length; i++){
        for(int j = i+1; j < data.length; j++){
            if(data[i] > data[j]){
                temp = data[i];
                data[i] = data[j];
                data[j] = temp;
                flag = true;
            }
        }
        if(flag == false){
            break;
        }else{
            flag = false;  //flag 将 true 置为 false,服务于下趟循环判断
        }
    }
}

2.2 选择排序

2.3 插入排序

2.4 快速排序

取一个flag,左、右两边的数据分别大于、小于这个flag;然后对左、右两边继续此操作(递归)

public static void quickSort(int[] data, int left, int right){
    int mid = data[(left + right)/2];
    int i = left, j = right;
    int temp = 0;
    while (i < j){
        while (data[i] < mid)
            i++;
        while (data[j] > mid)
            j--;
        if (i >= j)
            break;
        temp = data[i];
        data[i] = data[j];
        data[j] = temp;
        if (data[i] == mid)
            j--;
        if (data[j] == mid)
            i++;
    }
    if (i == j){
        i++;
        j--;
    }
    if (i < right)
        quickSort(data, i, right);
    if (left < j)
        quickSort(data, left, j);
}

2.5 归并排序

数组细分,直到最小单元(一个数据),然后排序合并,再次排序合并,直到合并成整个数据大小

public static void mergeSort(int[] data, int left, int right, int[] temp){
    if (left < right){
        int mid = (left + right)/2;
        mergeSort(data, left, mid, temp);
        mergeSort(data, mid+1, right, temp);
        sort(data, left, mid, right, temp);
    }
}
public static void sort(int[] data, int left, int mid, int right, int[] temp){
    int i = left, j = mid+1, t = 0, leftTemp = left;
    while (i <= mid && j<= right){
        if (data[i] > data[j])
            temp[t++] = data[j++];
        else
            temp[t++] = data[i++];
    }
    while (i <= mid)
        temp[t++] = data[i++];
    while (j <= right)
        temp[t++] = data[j++];
    t = 0;
    while ( leftTemp <= right)
        data[leftTemp++] = temp[t++];
}

2.6 基数排序

按个位数值,分到0-9十个桶中,然后提取十个桶的元素(按0-9 / 9-0顺序);再按百位数值分到0-9十个桶中,再次提取;再百位、千位……直到最多位数(最大数字,位数最多)。

public static void sort(int[] data){
    if(data == null || data.length < 1)
    return;
    int max = data[0];
    for(int i = 1; i < data.length; i++){ //计算所有元素中的最大位数
        if(data[i] > max)
            max = data[i];
    }
    int maxBit = (max+"").length();
    int[][] bucket = new int[10][data.length]; //定义10个桶装元素
    int[] bCount = new int[10];//记录每个桶的元素个数
    for(int i = 0, n = 1; i < maxBit; n*=10, i++){
        for(int j = 0; j<data.length; j++){
            int m = (data[j]/n)%10; //根据元素每位数字,放到不同桶中
            bucket[m][bCount[m]] = data[j];
            bCount[m]++;//对应桶的元素个数+1
        }     
        for(int k = 0, t = 0; k < 10; k++){//将每个桶元素按桶号升序取出,放到原数组
            if(bCount[k] > 0){
                for(int v = 0; v<bCount[k]; v++){
                    data[t++] = bucket[k][v];
                }
                bCount[k] = 0; //取出每个桶的元素后,桶元素计数归零
            }
        }
    }
}

2.7 希尔排序

2.8 堆排序

/**
 *  堆排序
 * @param nums  待排序数组
 */
public static void heapSort(int[] nums){
    int n = nums.length - 1;
    // 升序排列时, 构造最大堆
    for (int i = n / 2; i >= 0; i--) {
        heapfy(nums, i, n);
    }
    for (int i = n; i > 0; i--) {
        // 此时0 为堆中最大值,交换 0节点 与 i-1 节点,
        // 构造0 -》 i - 1的最大堆
        swap(nums, 0, i);
        heapfy(nums, 0, i - 1);
    }
}
/**
 *  构造最大堆
 * @param nums 数组
 * @param i     父节点
 * @param size   数组的最后的index,后面交换后,递减此值
 */
public static void heapfy(int[] nums, int i, int size){
    // left i节点的左子节点;right i节点的右子节点
    int left = i * 2 + 1, right = (i + 1) * 2, max = i;
    if(left <= size && nums[left] > nums[max]) max = left;
    if(right <= size && nums[right] > nums[max]) max = right;
    // 当前i节点的值不是最大节点,需要交换
    if(max != i){
        swap(nums, i, max);
        // 递归 max 对应的节点,是所有节点都满足:父节点大于子节点
        heapfy(nums, max, size);
    }
}
public static void swap(int[] nums, int i, int j){
    int tmp = nums[i];
    nums[i] = nums[j];
    nums[j] = tmp;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值