Loading

Algorithm 选择、冒泡、插入、归并排序

选择排序

    public static void selectSort(int[] arr){
      //边界判断啊
        if(arr == null || arr.length < 2 ){
            return ;
        }
        int minIndex;
      //外循环是对1-n 取最小值,2-n 取最小值
        for(int i = 0; i < arr.length-1; i++){
            minIndex = i;
          
            for(int j = i+1; j<arr.length -1 ; j++){
              //判断
                minIndex = arr[j] < arr[minIndex]? j : minIndex;
            }
          //交换
            swap(arr, i, minIndex);
        }
    }
		//交换位置
    public static void swap(int[] arr,int i,int j){
        int tmp = arr[i];
        arr[i] = arr[j];
        arr[j] = tmp;
    }   

冒泡排序

public static void bubbleSort(int[] arr) {
		if (arr == null || arr.length < 2) {
			return;
		}
		// 0 ~ N-1
		// 0 ~ N-2
		// 0 ~ N-3
  //冒泡排序是优先将最大值先排好
		for (int e = arr.length - 1; e > 0; e--) { // 0 ~ e
			for (int i = 0; i < e; i++) {
        //大的值往后放
				if (arr[i] > arr[i + 1]) {
					swap(arr, i, i + 1);
				}
			}
		}
	}

	// 交换arr的i和j位置上的值
// 这种等同于tmp做中间变量的交换
	public static void swap(int[] arr, int i, int j) {
		arr[i] = arr[i] ^ arr[j];
		arr[j] = arr[i] ^ arr[j];
		arr[i] = arr[i] ^ arr[j];
	}

插入排序

public static void insertionSort(int[] arr) {
		if (arr == null || arr.length < 2) {
			return;
		}
		// 不只1个数
		for (int i = 1; i < arr.length; i++) { // 0 ~ i 做到有序
			//当j--后 j为-1时,代表这个小排序达成,跳出,进行接下来的排序
			for (int j = i - 1; j >= 0 && arr[j] > arr[j + 1]; j--) {
				swap(arr, j, j + 1);
			}
		}
	}

	// i和j是一个位置的话,会出错
	public static void swap(int[] arr, int i, int j) {
		arr[i] = arr[i] ^ arr[j];
		arr[j] = arr[i] ^ arr[j];
		arr[i] = arr[i] ^ arr[j];
	}

归并排序

递归方法

public static void process(int[] arr, int L, int R) {
		if (L == R) { // 如果左边界 = 右边界,那其实不用排序
			return;
		}
  	// 这是求的中点
		int mid = L + ((R - L) >> 1); 
  	// 递归左 --- 中点
		process(arr, L, mid);
  	// 递归中点 --- 右 
		process(arr, mid + 1, R);
  
  	//merge是让他们拼凑在一起
		merge(arr, L, mid, R);
	}

	public static void merge(int[] arr, int L, int M, int R) {
		int[] help = new int[R - L + 1];
		int i = 0;
		int p1 = L;
		int p2 = M + 1;
    // 这里p1和p2是要都不越界才可以继续进行
		while (p1 <= M && p2 <= R) {
      //p1和p2谁指到的数大,谁就把他放在help这个新数组里,++是因为如果放到了新数组,我需要指针往下移
			help[i++] = arr[p1] <= arr[p2] ? arr[p1++] : arr[p2++];
		}
		// 如果跳出来while循环,要么p1越界了,要么p2越界了
    // 那么无论是p1还是p2越界了,对方一定是排好序的最大值,直接放到新数组就好
		while (p1 <= M) {
			help[i++] = arr[p1++];
		}
		while (p2 <= R) {
			help[i++] = arr[p2++];
		}
		for (i = 0; i < help.length; i++) {
			arr[L + i] = help[i];
		}
	}

非递归

public static void mergeSort2(int[] arr) {
		if (arr == null || arr.length < 2) {
			return;
		}
		int N = arr.length;
		// 步长
		int mergeSize = 1;
  	// 当步长 > N的时候 就可以跳出while了
		while (mergeSize < N) { // log N
			// 当前左组的,第一个位置
			int L = 0;
			while (L < N) {
				if (mergeSize >= N - L) {
					break;
				}
				int M = L + mergeSize - 1;
				int R = M + Math.min(mergeSize, N - M - 1);
				merge(arr, L, M, R);
				L = R + 1;
			}
			// 防止溢出
			if (mergeSize > N / 2) {
				break;
			}
      //其实就是步长 x 2
			mergeSize <<= 1;
		}
	}

归并排序

递归方法

public static void process(int[] arr, int L, int R) {
		if (L == R) { // 如果左边界 = 右边界,那其实不用排序
			return;
		}
  	// 这是求的中点
		int mid = L + ((R - L) >> 1); 
  	// 递归左 --- 中点
		process(arr, L, mid);
  	// 递归中点 --- 右 
		process(arr, mid + 1, R);
  
  	//merge是让他们拼凑在一起
		merge(arr, L, mid, R);
	}

	public static void merge(int[] arr, int L, int M, int R) {
		int[] help = new int[R - L + 1];
		int i = 0;
		int p1 = L;
		int p2 = M + 1;
    // 这里p1和p2是要都不越界才可以继续进行
		while (p1 <= M && p2 <= R) {
      //p1和p2谁指到的数大,谁就把他放在help这个新数组里,++是因为如果放到了新数组,我需要指针往下移
			help[i++] = arr[p1] <= arr[p2] ? arr[p1++] : arr[p2++];
		}
		// 如果跳出来while循环,要么p1越界了,要么p2越界了
    // 那么无论是p1还是p2越界了,对方一定是排好序的最大值,直接放到新数组就好
		while (p1 <= M) {
			help[i++] = arr[p1++];
		}
		while (p2 <= R) {
			help[i++] = arr[p2++];
		}
		for (i = 0; i < help.length; i++) {
			arr[L + i] = help[i];
		}
	}

非递归

public static void mergeSort2(int[] arr) {
		if (arr == null || arr.length < 2) {
			return;
		}
		int N = arr.length;
		// 步长
		int mergeSize = 1;
  	// 当步长 > N的时候 就可以跳出while了
		while (mergeSize < N) { // log N
			// 当前左组的,第一个位置
			int L = 0;
			while (L < N) {
				if (mergeSize >= N - L) {
					break;
				}
				int M = L + mergeSize - 1;
				int R = M + Math.min(mergeSize, N - M - 1);
				merge(arr, L, M, R);
				L = R + 1;
			}
			// 防止溢出
			if (mergeSize > N / 2) {
				break;
			}
      //其实就是步长 x 2
			mergeSize <<= 1;
		}
	}
posted @ 2021-11-03 15:16  Pen9  阅读(36)  评论(0编辑  收藏  举报