排序算法的java实现

排序算法的java实现

直接插入排序

public static void insertSort(int arr[]){
    int tmp, i, j;
    for (i = 1; i < arr.length; i++){
        tmp = arr[i];
        j = i - 1;
        while (j >= 0 && tmp < arr[j]){
            arr[j+1] = arr[j];
            j--;
        }
        arr[j+1] = tmp;
    }
}

简单选择排序

public static void selectSort(int arr[]){
    for (int i = 0; i < arr.length - 1; i++){
        int k = i; //记录本轮最小值的下标
        for (int j = i+1; j < arr.length; j++){
            if (arr[j] < arr[k]){
                k = j;
            }
        }
        if (k != i){
            //交换最小值与当前无序序列的第一个关键字
            int tmp = arr[i];
            arr[i] = arr[k];
            arr[k] = tmp;
        }
    }
}

冒泡排序

public static void  bubbleSort(int arr[]){
    for(int i = arr.length-1; i >= 1; i--){  // arr.length-1轮交换
        int flag = 0;   // 标记本轮是否有交换,0表示未交换,1表示交换
        for (int j = 0; j < i; j++){
            if (arr[j] > arr[j+1]){
                int tmp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = tmp;
                flag = 1; // 本轮发生了交换
            }
        }
        if (flag == 0){
            break; // 若本轮未发生交换排序结束
        }
    }
}

希尔排序

希尔排序

public static void shellSort(int arr[]){
	for (int step = arr.length/2; step >= 1; step/=2){
	    for (int i = step;i<arr.length;i+=step){
	        for (int j = i; j>0;j-=step){
	            if (arr[j]<arr[j-step]){
	                int tmp = arr[j];
	                arr[j] = arr[j-step];
	                arr[j-step] = tmp;
	            }
	        }
	    }
	}
}

快速排序

快速排序思路:

  • 选取第一个关键字作为枢轴 (pivot)
  • 一次划分过程,将比pivot小的关键字交换到前面,比pivot大的关键字交换到后面
  • 对划分后的左右区间重复第二步,直到各区间只有一个数

一次划分过程

在这里插入图片描述

public static int partition(int arr[], int startIndex, int endIndex){
    // 划分
    int low = startIndex;
    int high = endIndex;
    int pivotKey = arr[low];
    while (low < high){
        while (low < high && arr[high] >= pivotKey){ // 从右往左扫描
            high--; // 找到第一个小于pivotKey的关键字
        }
        if (low < high){
            arr[low] = arr[high];
        }
        while (low < high && arr[low] < pivotKey){ // 从左往右扫描
            low++;  // // 找到第一个大于pivotKey的关键字
        }
        if (low < high){
            arr[high] = arr[low];
        }
    }
    arr[low] = pivotKey;
    return low;  // 返回pivotKey所在位置 
}

public static void quickSort(int arr[], int startIndex, int endIndex){
    if (endIndex <= startIndex) {
        return;
    }    
    int pivotIndex = partition(arr, startIndex, endIndex);
    quickSort(arr, startIndex, pivotIndex-1);
    quickSort(arr, pivotIndex+1, endIndex);
}

堆排序

  • 完全二叉树的顺序存储结构

在这里插入图片描述

  • 大顶堆:每个节点的值都大于或等于其子节点的值,在堆排序算法中用于升序排列;

  • 小顶堆:每个节点的值都小于或等于其子节点的值,在堆排序算法中用于降序排列;

  • 构建堆

在这里插入图片描述

  • 输出堆顶元素并调整新堆

在这里插入图片描述

  • 堆排序算法

    1. 构建初始堆,将待排序列构成一个大顶堆(或者小顶堆),升序大顶堆,降序小顶堆; 将堆顶元素与堆尾元素交换,并断开(从待排序列中移除)堆尾元素。
    2. 重新构建堆。
    3. 重复2~3,直到待排序列中只剩下一个元素(堆顶元素)。
    public static void adjustHeap(int arr[], int parent, int length){
        // 调整为小顶堆
        int tmp = arr[parent];
        int lchild = 2 * parent + 1;  // 指向左孩子
        while (lchild < length) {
            // 若右孩子存在且更小,指向右孩子
            if (lchild + 1 < length && arr[lchild] > arr[lchild + 1]){
                lchild ++;
            }
            // 如果父结点的值小于最小孩子结点的值,则直接结束
            if (tmp <= arr[lchild]){
                break;
            }
    
            arr[parent] = arr[lchild];
            parent = lchild;
            lchild = 2 * lchild + 1;
        }
        arr[parent] = tmp;
    }
    public static void heapSort(int arr[]){
        // 实现降序排序
        //1. 创建小顶堆
        for(int i = arr.length/2-1; i >= 0; --i){
            // 从最后一个非叶节点向前筛选
            adjustHeap(arr, i, arr.length);
        }
        // 2. 输出堆顶元素并调整新堆
        for (int i = arr.length - 1; i > 0; i--) {
            //将堆顶元素与末尾元素进行交换
            int temp = arr[i];
            arr[i] = arr[0];
            arr[0] = temp;
            //重新对堆进行调整
            adjustHeap(arr, 0, i);
        }
    }
    

二路归并排序

在这里插入图片描述

public static void merge(int[] arr, int low, int mid, int high){
    // merge arr[low],...,arr[mid] 及 arr[mid+1], ..., arr[high]
    int n1 = mid - low + 1;  // 第一个子表的关键字个数
    int n2 = high - mid;  // 第二个子表的关键字个数
    int[] L = new int[n1];  // 存储第一个子表的关键字
    int[] R = new int[n2];  // 存储第二个子表的关键字
    for (int i = 0; i < n1; i++){
        L[i] = arr[low + i];
    }
    for (int j = 0; j < n2; j++){
        R[j] = arr[mid + 1 + j];
    }
    int i = 0;
    int j = 0;
    int k = low;
    while (i < n1 && j < n2){  // merge
        if (L[i] < R[j]){
            arr[k++]  = L[i++];
        }
        else{
            arr[k++]  = R[j++];
        }
    }
    while (i < n1){
        arr[k++] = L[i++];
    }
    
    while (j < n2){
        arr[k++] = R[j++];
    }
}

public static void mergeSort(int[] arr, int low, int high){
    if (low >= high){
        return;
    }
    int mid = (low + high)/2;
    mergeSort(arr, low, mid);  // 排序左子表
    mergeSort(arr, mid+1, high);  // 排序右子表
    merge (arr, low, mid, high);  // 归并操作
}

基数排序

在这里插入图片描述

总结

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值