排序算法-Java实现

快排

  • 选取pivot
  • 确定位置
  • 重复确定
package main;
import java.util.Scanner;
public class QuickSort {
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		while (true){
			int len = in.nextInt();
			int[] nums = new int[len];
			for (int i = 0; i < len; i++) {
				nums[i] = in.nextInt();
			}
			quickSort(nums,0,len-1);
			for (int i: nums
			) {
				System.out.print(i + " ");
			}
		}
	}
	private static void quickSort(int[] nums, int l, int r) {
		if(l < r){
			int partitionIndex = partition(nums,l,r);
			quickSort(nums,l,partitionIndex-1);
			quickSort(nums,partitionIndex+1,r);
		}
	}

	private static int partition(int[] nums, int l, int r) {
		int pivot = l;
		int index = pivot+1;
		for (int i = index; i <= r; i++) {
			if(nums[pivot] > nums[i]){
				swap(nums,i,index);
				index++;
			}
		}
		swap(nums,pivot,index-1);
		return index-1;
	}
	private static void swap(int[] nums, int i, int index) {
		int temp = nums[i];
		nums[i] = nums[index];
		nums[index] = temp;
	}
}

  1. 堆的定义
    堆是一棵节点含有内部比较器的完全二叉树。(说白了,堆就是完全二叉树,只不过它的节点对象实现了comparable接口)。也有种说法是,一个可以自我调整的完全二叉树.
  2. 堆的特性
    每个父节点都大于等于(或者小于等于)其所有后代结点。
    堆的根节点含有堆中最大(或者最小)的对象。
    堆中以任意节点为根节点的子树仍然是堆。
  3. 堆的分类
    最大堆(大根堆,大顶堆):根节点对象是最大对象的堆
    最小堆(小根堆,小顶堆):根节点对象是最小对象的堆

堆排序

  • 建堆
  • 调整堆
  • 首尾交换
  • 重复调整
public class HeapSort {
    public static void main(String[] args) {
        int[] nums = {16,7,3,20,17,8};
        headSort(nums);
        for (int num : nums) {
            System.out.print(num + " ");
        }
    }

    /**
     * 堆排序
     */
    public static void headSort(int[] list) {
        //构造初始堆,从第一个非叶子节点开始调整,左右孩子节点中较大的交换到父节点中
        for (int i = (list.length) / 2 - 1; i >= 0; i--) {
            headAdjust(list, list.length, i);
        }
        //排序,将最大的节点放在堆尾,然后从根节点重新调整
        for (int i = list.length - 1; i >= 1; i--) {
            int temp = list[0];
            list[0] = list[i];
            list[i] = temp;
            headAdjust(list, i, 0);
        }
    }

    private static void headAdjust(int[] list, int len, int i) {
        int k = i, temp = list[i], index = 2 * k + 1;
        while (index < len) {
            if (index + 1 < len) {
                if (list[index] < list[index + 1]) {
                    index = index + 1;
                }
            }
            if (list[index] > temp) {
                list[k] = list[index];
                k = index;
                index = 2 * k + 1;
            } else {
                break;
            }
        }
        list[k] = temp;
    }
}

插入排序

public class InsertSort {
    public static void sort(int[] arr) {
        if (arr.length >= 2) {
            for (int i = 1; i < arr.length; i++) {
                //挖出一个要用来插入的值,同时位置上留下一个可以存新的值的坑
                int x = arr[i];
                int j = i - 1;
                //在前面有一个或连续多个值比x大的时候,一直循环往前面找,将x插入到这串值前面
                while (j >= 0 && arr[j] > x) {
                    //当arr[j]比x大的时候,将j向后移一位,正好填到坑中
                    arr[j + 1] = arr[j];
                    j--;
                }
                //将x插入到最前面
                arr[j + 1] = x;
            }
        }
    }
}

冒泡排序

public class MaoPao {
    public static void  sort(int[] arr){
        for (int i = 1; i < arr.length; i++) {  //第一层for循环,用来控制冒泡的次数
            for (int j = 0; j < arr.length-1; j++) { //第二层for循环,用来控制冒泡一层层到最后
                //如果前一个数比后一个数大,两者调换 ,意味着泡泡向上走了一层
                if (arr[j] > arr[j+1] ){
                    int temp = arr[j];
                    arr[j] = arr[j+1];
                    arr[j+1] = temp;
                }
            }
        }
    }
}
 /**
 * 终极版冒泡排序
 * 加入一个布尔变量,如果内循环没有交换值,说明已经排序完成,提前终止
 * @param arr
 */
public static void sortPlus(int[] arr){
    if(arr != null && arr.length > 1){
        for(int i = 0; i < arr.length - 1; i++){
            // 初始化一个布尔值
            boolean flag = true;
            for(int j = 0; j < arr.length - i - 1 ; j++){
                if(arr[j] > arr[j+1]){
                    // 调换
                    int temp;
                    temp = arr[j];
                    arr[j] = arr[j+1];
                    arr[j+1] = temp;
                    // 改变flag
                    flag = false;
                }
            }
            if(flag){
                break;
            }
        }
    }
}

选择排序

public static void sort(int[] arr){
    for(int i = 0; i < arr.length - 1 ; i++){
        int min = i; // 遍历的区间最小的值
        for (int j = i + 1; j < arr.length ;j++){
             if(arr[j] < arr[min]){
                 // 找到当前遍历区间最小的值的索引
                 min = j;
             }
        }
        if(min != i){
            // 发生了调换
            int temp =  arr[min];
            arr[min] = arr[i];
            arr[i] = temp;
        }
    }
}

归并排序

public static void mergeSort(int[] a,int s,int e){
    int m = (s + e) / 2;
    if (s < e){
      mergeSort(a,s,m);
      mergeSort(a,m+1,e);
      //归并
      merge(a,s,m,e);
    }
  }
  private static void merge(int[] a, int s, int m, int e) {
    //初始化一个从起始s到终止e的一个数组
    int[] temp = new int[(e - s) + 1];
    //左起始指针
    int l = s;
    //右起始指针
    int r = m+1;
    int i = 0;
    //将s-e这段数据在逻辑上一分为二,l-m为一个左边的数组,r-e为一个右边的数组,两边都是有序的
    //从两边的第一个指针开始遍历,将其中小的那个值放在temp数组中
    while (l <= m && r <= e){
      if (a[l] < a[r]){
        temp[i++] = a[l++];
      }else{
        temp[i++] = a[r++];
      }
    }
    //将两个数组剩余的数放到temp中
    while (l <= m){
      temp[i++] = a[l++];
    }
    while (r <= e){
      temp[i++] = a[r++];
    }    
    //将temp数组覆盖原数组
    for (int n = 0; n < temp.length; n++) {
      a[s+n] = temp[n];
    }    
  }
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值