排序算法

先来一个最简单的热热身:冒泡排序

/**  
 * 冒泡法排序<br/>  
 *
 * 比较相邻的元素。如果第一个比第二个大,就交换他们两个。
 * 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
 * 针对所有的元素重复以上的步骤,除了最后一个。
 * 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。 
 *
 * @param numbers  
 * 需要排序的整型数组  
 */ 
public static int[] soft(int[] array) {
	for (int i = 0; i < array.length; i++) {
		for (int j = 0; j < array.length; j++) {
			if (array[i] < array[j]) {
				int temp = array[i];
				array[i] = array[j];
				array[j] = temp;
			}
		}
	}
	return array;
}

难度+1:直接插入排序

        /**  
	 * 插入排序<br/>  
	 * <ul>  
	 * <li>从第一个元素开始,该元素可以认为已经被排序</li>  
	 * <li>取出下一个元素,在已经排序的元素序列中从后向前扫描</li>  
	 * <li>如果该元素(已排序)大于新元素,将该元素移到下一位置</li>  
	 * <li>重复步骤3,直到找到已排序的元素小于或者等于新元素的位置</li>  
	 * <li>将新元素插入到该位置中</li>  
	 * <li>重复步骤2</li>  
	 * </ul>  
	 *   
	 * @param numbers  
	 */         
        public static int[] soft(int[] array) {
		for (int i = 1; i < array.length; i++) {
			int temp = array[i] , j;
			for ( j = i ; j > 0 && temp < array[j-1]; j--)
				array[j] = array[j-1];
			array[j] = temp;
		}
		
		return array;
	}

希尔排序:

        public static int[] soft(int[] array) {
		for (int i = array.length/2; i > 0; i /= 2) {
			for (int j = i; j < array.length; j++) {
				int temp = array[j] , k;
				for (k = j-i; k >= 0 && temp < array[k]; k-=i)
					array[k+i] = array[k];
				array[k+i] = temp;
			}
		}
		return array; 
	}


快速排序:

        public static int[] soft(int[] array , int start , int end) {
		if (start < end) {
			int base = array[start]; // 选定的基准值(第一个数值作为基准值)
			int temp; // 记录临时中间值
			int i = start, j = end;
			do {
				while ((array[i] < base) && (i < end))
					i++;
				while ((array[j] > base) && (j > start))
					j--;
				if (i <= j) {
					temp = array[i];
					array[i] = array[j];
					array[j] = temp;
					i++;
					j--;
				}
			} while (i <= j);
			if (start < j)
				soft(array, start, j);
			if (end > i)
				soft(array, i, end);
		}
		return array;
	}

归并排序:

        /**  
	 * 归并排序<br/>  
	 * <ul>  
	 * <li>申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列</li>  
	 * <li>设定两个指针,最初位置分别为两个已经排序序列的起始位置</li>  
	 * <li>比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置</li>  
	 * <li>重复步骤3直到某一指针达到序列尾</li>  
	 * <li>将另一序列剩下的所有元素直接复制到合并序列尾</li>  
	 * </ul>  
	 *   
	 * @param numbers  
	 */ 
	public static void mergeSort(int[] numbers, int left, int right) {
		int t = 1;// 每组元素个数
		int size = right - left + 1;
		while (t < size) {
			int s = t;// 本次循环每组元素个数
			t = 2 * s;
			int i = left;
			while (i + (t - 1) < size) {
				merge(numbers, i, i + (s - 1), i + (t - 1));
				i += t;
			}
			if (i + (s - 1) < right)
				merge(numbers, i, i + (s - 1), right);
		}
	}

	// 归并算法实现
	private static void merge(int[] data, int p, int q, int r) {
		int[] B = new int[data.length];
		int s = p;
		int t = q + 1;
		int k = p;
		while (s <= q && t <= r) {
			if (data[s] <= data[t]) {
				B[k] = data[s];
				s++;
			} else {
				B[k] = data[t];
				t++;
			}
			k++;
		}
		if (s == q + 1)
			B[k++] = data[t++];
		else
			B[k++] = data[s++];
		for (int i = p; i <= r; i++)
			data[i] = B[i];
	}

直接选择排序:

        public static int[] soft(int[] array) {
		for (int i = 0; i < array.length; i++) {
			int min = i;
			for (int j = i+1; j < array.length; j++) 
				if (array[j] < array[min]) 
					min = j;
				
			if (min != i) {
				array = swap(array , i , min);
			}
		}
		
		return array;
	}

	private static int[] swap(int[] array, int i, int min) {
		// TODO Auto-generated method stub
		int temp = array[i];
		array[i] = array[min];
		array[min] = temp;
		return array;
	}
	
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		System.out.println("请输入数组大小:");
		int n = scanner.nextInt();
		int[] array = new int[n];
		for (int i = 0; i < n; i++) {
			array[i] = scanner.nextInt();
		}
		array = soft(array);
		for (int i = 0; i < array.length; i++) {
			System.out.print(array[i] + " ");
		}
		
	}

归并排序:

        /**  
	 * 归并排序<br/>  
	 * <ul>  
	 * <li>申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列</li>  
	 * <li>设定两个指针,最初位置分别为两个已经排序序列的起始位置</li>  
	 * <li>比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置</li>  
	 * <li>重复步骤3直到某一指针达到序列尾</li>  
	 * <li>将另一序列剩下的所有元素直接复制到合并序列尾</li>  
	 * </ul>  
	 *   
	 * @param numbers  
	 */ 
	public static void main(String[] args) {  
        int[] data = new int[] { 5, 3, 6, 2, 1, 9, 4, 8, 7 };  
        mergeSort(data);  
        System.out.println("排序后的数组:");  
        print(data); 
    }  
  
    public static void mergeSort(int[] data) {  
        sort(data, 0, data.length - 1);  
    }  
  
    public static void sort(int[] data, int left, int right) {  
        if (left >= right)  
            return;  
        // 找出中间索引  
        int center = (left + right) / 2;  
        // 对左边数组进行递归  
        sort(data, left, center);  
        // 对右边数组进行递归  
        sort(data, center + 1, right);  
        // 合并  
        merge(data, left, center, right);  
        print(data);  
    }  
  
    /** 
     * 将两个数组进行归并,归并前面2个数组已有序,归并后依然有序 
     *  
     * @param data 
     *            数组对象 
     * @param left 
     *            左数组的第一个元素的索引 
     * @param center 
     *            左数组的最后一个元素的索引,center+1是右数组第一个元素的索引 
     * @param right 
     *            右数组最后一个元素的索引 
     */  
    public static void merge(int[] data, int left, int center, int right) {  
        // 临时数组  
        int[] tmpArr = new int[data.length];  
        // 右数组第一个元素索引  
        int mid = center + 1;  
        // third 记录临时数组的索引  
        int third = left;  
        // 缓存左数组第一个元素的索引  
        int tmp = left;  
        while (left <= center && mid <= right) {  
            // 从两个数组中取出最小的放入临时数组  
            if (data[left] <= data[mid]) {  
                tmpArr[third++] = data[left++];  
            } else {  
                tmpArr[third++] = data[mid++];  
            }  
        }  
        // 剩余部分依次放入临时数组(实际上两个while只会执行其中一个)  
        while (mid <= right) {  
            tmpArr[third++] = data[mid++];  
        }  
        while (left <= center) {  
            tmpArr[third++] = data[left++];  
        }  
        // 将临时数组中的内容拷贝回原数组中  
        // (原left-right范围的内容被复制回原数组)  
        while (tmp <= right) {  
            data[tmp] = tmpArr[tmp++];  
        }  
    }  
  
    public static void print(int[] data) {  
        for (int i = 0; i < data.length; i++) {  
            System.out.print(data[i] + "\t");  
        }  
        System.out.println();  
    }

堆排序:

        public static void heap_sort(int[] arrays, int e) {
		if (e > 0) {
			init_sort(arrays, e);// 初始化堆,找出最大的放在堆顶
			// snp(arrays);
			arrays[0] = arrays[e] + arrays[0];
			arrays[e] = arrays[0] - arrays[e];
			arrays[0] = arrays[0] - arrays[e];
			// snp(arrays);
			heap_sort(arrays, e - 1);
		} else {
			snp(arrays);
		}
	}

	public static void snp(int[] arrays) {
		for (int i = 0; i < arrays.length; i++) {
			System.out.print(arrays[i] + " ");
		}
		System.out.println();
	}

	public static void init_sort(int[] arrays, int e) {
		int m = (e + 1) / 2;
		for (int i = 0; i < m; i++) {
			boolean flag = build_heap(arrays, e, i);
			// 如果孩子之间有交换,就要重新开始
			if (flag) {
				i = -1;
			}

		}

	}

	// 返回一个标记,如果有根与孩子交换就要重新从顶根开始查找不满足最大堆树结构
	public static boolean build_heap(int arrays[], int e, int i) {
		int l_child = 2 * i + 1;// 左孩子
		int r_child = 2 * i + 2;// 右孩子
		if (r_child > e) { // 判断是否有右孩子,没有的话直接比较,小于交换
			if (arrays[i] < arrays[l_child]) {
				arrays[i] = arrays[i] + arrays[l_child];
				arrays[l_child] = arrays[i] - arrays[l_child];
				arrays[i] = arrays[i] - arrays[l_child];
				return true;
			} else {
				return false;
			}
		}
		// 在根与两个孩子之间找出最大的那个值进行交换
		if (arrays[i] < arrays[l_child]) {
			if (arrays[l_child] > arrays[r_child]) {
				// 交换根与左孩子的值
				arrays[i] = arrays[i] + arrays[l_child];
				arrays[l_child] = arrays[i] - arrays[l_child];
				arrays[i] = arrays[i] - arrays[l_child];
				return true;
			} else {
				// 交换根与右孩子的值
				arrays[i] = arrays[i] + arrays[r_child];
				arrays[r_child] = arrays[i] - arrays[r_child];
				arrays[i] = arrays[i] - arrays[r_child];
				return true;
			}
		} else if (arrays[i] < arrays[r_child]) {
			// 交换根与右孩子的值
			arrays[i] = arrays[i] + arrays[r_child];
			arrays[r_child] = arrays[i] - arrays[r_child];
			arrays[i] = arrays[i] - arrays[r_child];
			return true;
		}
		return false;

	}

	public static void main(String[] args) {
		int[] a = { 17, 8, 45, 84, 2, 94 };
		heap_sort(a, a.length - 1);
	}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值