zoukankan      html  css  js  c++  java
  • 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;
    		}
    	}
    
  • 相关阅读:
    利用js在Table中追加数据
    C#API配置跨域
    C#linq查询DataTable
    erlang格式化输出
    erlang 的源代码保护机制
    MP3格式音频文件结构解析
    使用异步 I/O 大大提高应用程序的性能
    虚拟机安装mac 关键是换引导
    C/C++规则整理
    字节对齐
  • 原文地址:https://www.cnblogs.com/pengcode/p/15503731.html
Copyright © 2011-2022 走看看