`

Java实现的9种排序方法

阅读更多
详见代码。
package com.java.sort;

import java.util.Arrays;

public class Sort {

	/**
	 * 冒泡排序
	 * 
	 * @param array
	 */
	public static void bubble(int[] array) {
		for (int i = 0; i < array.length; i++) {
			for (int j = i + 1; j < array.length; j++) {
				if (array[i] > array[j]) {
					int temp = array[i];
					array[i] = array[j];
					array[j] = temp;
				}
			}
		}
	}

	/**
	 * 选择排序
	 * 
	 * @param array
	 */
	public static void selection(int[] array) {
		for (int i = 0; i < array.length; i++) {
			int min = i;// the index of minimum number
			for (int j = i + 1; j < array.length; j++) {
				if (array[j] < array[min]) {
					min = j;
				}
			}

			if (i != min) {
				int temp = array[i];
				array[i] = array[min];
				array[min] = temp;
			}
		}
	}

	/**
	 * 从index=1开始,然后index+1,一直到index=array.length-1。每次比较排序index。 插入排序的递归实现,尾递归
	 * 
	 * @param array
	 * @param index
	 */
	public static void insertion1(int[] array, int index) {
		if (index > 0 && index < array.length) {
			int key = array[index];
			int i = index - 1;
			for (; i >= 0 && array[i] > key; i--) {
				array[i + 1] = array[i];
			}
			array[i + 1] = key;
			insertion1(array, index + 1);
		}
	}

	/**
	 * 插入排序 使用场合:数组越接近于有序,插入排序所需做的工作越少
	 * 
	 * @param array
	 */
	public static void insertion(int[] array) {
		for (int i = 1; i < array.length; i++) {
			int key = array[i];
			int j = i - 1;
			for (; j >= 0 && array[j] > key; j--) {
				array[j + 1] = array[j];
			}
			array[j + 1] = key;
		}
	}

	/**
	 * 希尔排序 改进的插入排序算法
	 * 
	 * @param array
	 */
	public static void shell(int[] array) {
		for (int space = array.length / 2; space > 0; space /= 2) {
			space = (space % 2 == 0 ? (space + 1) : (space));// 为了来取消那些space为偶数的情况。因为如果不排除这一项,在排序的时候会有重复的排序.
			for (int i = 0; i < space; i++) {
				sort_array_space(array, i, space);
			}
		}
	}

	/**
	 * 为了辅助shell排序而设计的,类似于插入排序,只不过加入了space
	 * 
	 * @param array
	 * @param first
	 * @param space
	 */
	private static void sort_array_space(int[] array, int first, int space) {
		for (int i = first + space; i < array.length; i += space) {
			int key = array[i];
			int j = i - space;
			for (; j >= first && array[j] > key; j -= space) {
				array[j + space] = array[j];
			}
			array[j + space] = key;
		}
	}

	/**
	 * 归并排序的主函数。
	 * 为了让调用变得简单,实际上可以直接使用第二个主函数
	 * 在java中,sort(Object[] arr)使用便是归并排序
	 * 归并排序的效率是 nlog2n(2是底数),缺点是需要另外一个数组
	 * @param array
	 */
	public static void merge(int[] array){
		mergeSort(array,0,array.length-1);
	}
	
	/**
	 * 归并排序第二个主函数
	 * @param array
	 * @param left
	 * @param right
	 */
	private static void mergeSort(int[] array, int left, int right) {
		if (left < right) {
			int middle = (left + right) / 2;
			mergeSort(array, left, middle);
			mergeSort(array, middle + 1, right);
			mergeArray(array, left, middle, right);
		}
	}

	/**
	 * 将 array 数组中left 到 right的内容进行排序,并
	 * @param array
	 * @param left
	 * @param middle
	 * @param right
	 */
	private static void mergeArray(int[] array, int left, int middle, int right) {
		int[] temp = new int[array.length];
		int i = left;
		int j = middle + 1;
		int index = left;

		while ((i <= middle) && (j <= right)) {
			if (array[i] <= array[j]) {
				temp[index++] = array[i++];
			} else {
				temp[index++] = array[j++];
			}
		}

		if (i > middle) {
			for (int k = j; k <= right; k++) {
				temp[index++] = array[k];
			}
		} else {
			for (int k = i; k <= middle; k++) {
				temp[index++] = array[k];
			}
		}

		for (int k = left; k <= right; k++) {
			array[k] = temp[k];
		}
	}

	/**
	 * 快速排序的主要入口
	 * Java中对于基本数据类型使用的是快速排序 sort(type[] array)
	 * @param array
	 */
	public static void quick(int[] array){
		int p = 0;
		int r = array.length-1;
		qsort(array,p,r);
	}
	
	/**
	 * 快速排序主函数
	 * @param array
	 * @param p
	 * @param r
	 */
	private static void qsort(int array[], int p, int r) {
		if (p < r) {
			int q = partition(array, p, r);
			qsort(array, p, q - 1);
			qsort(array, q + 1, r);
		}
	}
	
	/**
	 * 进行一次排序,并得到分支点
	 * 过程如下:
	 * 	对p到r位置上的元素进行一一排序(标记位置由i来负责)
	 * 	index负责交换位置的确定。没交换一次位置,index++
	 * 	for循环结束的时候,比key小的元素会都在index的左边
	 * 	这样再将index和r位置上的两个元素交换
	 * @param array
	 * @param left
	 * @param right
	 * @return
	 */
	private static int partition(int array[], int left, int right) {
		int key = array[right];
		int index = left;
		for (int i = left; i < right; i++) {
			if (array[i] <= key) {//不关是否交换,index都要增加
				if(i != index){//避免交换相同的元素,不过index还是要增加的。
					swap(array, index, i);
				}
				index++;
			}
		}
		swap(array, index, right);
		return index;
	}
	
	private static void swap(int a[], int i, int j) {
		int tmp = a[i];
		a[i] = a[j];
		a[j] = tmp;
	}

	/**
	 * 桶式排序
	 * 
	 * @param array
	 */
	public static void bucket(int[] array) {
		
	}
	
	/**
	 * 基数排序
	 * @param array
	 */
	public static void base(int[] array){
		
	}
	

	public static void main(String[] args) {
		int[] array = new int[] { 3, 4, 5, 2, 6, 7, 1, 9, 8, 10 };
		bubble(array);
		System.out.println("bubble:\t\t" + Arrays.toString(array));

		array = new int[] { 3, 4, 5, 2, 6, 7, 1, 9, 8, 10 };
		selection(array);
		System.out.println("selection:\t" + Arrays.toString(array));

		array = new int[] { 3, 4, 5, 2, 6, 7, 1, 9, 8, 10 };
		insertion(array);
		System.out.println("insertion:\t" + Arrays.toString(array));

		array = new int[] { 3, 4, 5, 2, 6, 7, 1, 9, 8, 10 };
		shell(array);
		System.out.println("shell:\t\t" + Arrays.toString(array));

		array = new int[] { 3, 4, 5, 2, 6, 7, 1, 9, 8, 10 };
		merge(array);
		System.out.println("merge:\t\t" + Arrays.toString(array));

		array = new int[] { 3, 5, 2, 6, 7, 1, 9, 8, 10, 4};
		quick(array);
		System.out.println("quick:\t\t" + Arrays.toString(array));
	}
}






/**
 * @author Yuanbo Han
 */
public class HeapSort {

	private double[] elements = new double[10];
	private int size = 0;
	
	private HeapSort(){
		this.elements = new double[10];
		this.size = 0;
	}
	
	public void add(double e){
		if(size + 1 > elements.length){
			int newCapacity = elements.length * 3 / 2 + 1;
			double[] newElements = new double[newCapacity];
			System.arraycopy(elements, 0, newElements, 0, size);
			
			newElements[size++] = e;
			elements = newElements;
		}else{
			elements[size++] = e;
		}
	}
	
	public void heapsort(){
		for(int i=0;i<size;i++){
			int length = size - i;
			this.heapsort(length);
		}
	}
	
	/**
	 * 对前length个数据进行排序,得到最大的数据为index = 0,然后跟index = length-1的数据进行交换
	 * @param length
	 */
	private void heapsort(int length){
		int index = length / 2 - 1;
		for(int i=index;i>=0;i--){
			int head = i;
			for(;;){//进行交换之后,子树可能不是最大堆,所以要for循环进行重构最大堆
				int max = head;
				int left = 2 * head + 1;
				int right = 2 * head + 2;
				if(left < length && elements[max] < elements[left]){
					max = left;
				}
				if(right < length && elements[max] < elements[right]){
					max = right;
				}
				if(max != head){
					double tmp = elements[max];
					elements[max] = elements[head];
					elements[head] = tmp;
					head = left;
				}else{
					break;
				}
			}
		}
		
		double tmp = elements[0];
		elements[0] = elements[length-1];
		elements[length-1] = tmp;
	}
	
	@Override
	public String toString() {
		StringBuilder sb = new StringBuilder();
		sb.append("[");
		for(int i=0;i<size;i++){
			sb.append(elements[i] + ", ");
		}
		if(size > 0){
			sb = new StringBuilder(sb.substring(0, sb.length() - 2));
		}
		sb.append("]");
		return sb.toString();
	} 
	
	public static void main(String[] args) {
		HeapSort hs = new HeapSort();
		hs.add(15);
		hs.add(60);
		hs.add(72);
		hs.add(70);
		hs.add(56);
		hs.add(32);
		hs.add(62);
		hs.add(92);
		hs.add(45);
		hs.add(30);
		hs.add(65);
		
		hs.heapsort();
		System.out.println(hs);

	}
}





向一个已经排好序的数组中插入新的数据,使用二分查找来进行位置确定,时间复杂度为(log N)。

/**
 * @author Yuanbo Han
 */
public class Sort {

	private double[] elements = new double[10];
	private int size = 0;
	
	private Sort(){
		this.elements = new double[10];
		this.size = 0;
	}
	
	@Override
	public String toString() {
		StringBuilder sb = new StringBuilder();
		sb.append("[");
		for(int i=0;i<size;i++){
			sb.append(elements[i] + ", ");
		}
		if(size > 0){
			sb = new StringBuilder(sb.substring(0, sb.length() - 2));
		}
		sb.append("]");
		return sb.toString();
	}

	
	/**
	 * 升序排列
	 * @param a
	 * @return
	 */
	public void insert(double a){
		int index = this.getInsertIndex(a, 0, size-1);
		
		if(size + 1 > elements.length){
			int newCapacity = elements.length * 3 / 2 + 1;
			double[] newElements = new double[newCapacity];
			System.arraycopy(elements, 0, newElements, 0, index);
			
			newElements[index] = a;
			System.arraycopy(elements, index, newElements, index+1, size - index);
			
			elements = newElements;
		}else{
			System.arraycopy(elements, index, elements, index+1, size - index);
			elements[index] = a;
		}
		size++;
	}

	/**
	 * 升序排列
	 * @param a
	 * @param leftIndex
	 * @param rightIndex
	 * @return
	 */
	private int getInsertIndex(double a, int leftIndex, int rightIndex){
		if(rightIndex < 0){//the first time
			return leftIndex;
		}
		if(leftIndex == rightIndex){
			if(a > elements[rightIndex]){
				return rightIndex + 1;
			}
			return leftIndex;
		}
		int midIndex = (leftIndex + rightIndex) / 2;
		if(a > elements[midIndex]){
			return this.getInsertIndex(a, midIndex+1, rightIndex);
		}else if(a < elements[midIndex]){
			return this.getInsertIndex(a, leftIndex, midIndex-1);
		}else{
			return midIndex;
		}
	}
	
	public void testInsert(){
		this.insert(15);System.out.println(this);
		this.insert(60);System.out.println(this);
		this.insert(72);System.out.println(this);
		this.insert(70);System.out.println(this);
		this.insert(56);System.out.println(this);
		this.insert(32);System.out.println(this);
		this.insert(62);System.out.println(this);
		this.insert(92);System.out.println(this);
		this.insert(45);System.out.println(this);
		this.insert(30);System.out.println(this);
		this.insert(65);System.out.println(this);
	}
	
	public static void main(String[] args) {
		Sort hs = new Sort ();
		hs.testInsert();
	}
}


//输出结果
/*
[15.0]
[15.0, 60.0]
[15.0, 60.0, 72.0]
[15.0, 60.0, 70.0, 72.0]
[15.0, 56.0, 60.0, 70.0, 72.0]
[15.0, 32.0, 56.0, 60.0, 70.0, 72.0]
[15.0, 32.0, 56.0, 60.0, 62.0, 70.0, 72.0]
[15.0, 32.0, 56.0, 60.0, 62.0, 70.0, 72.0, 92.0]
[15.0, 32.0, 45.0, 56.0, 60.0, 62.0, 70.0, 72.0, 92.0]
[15.0, 30.0, 32.0, 45.0, 56.0, 60.0, 62.0, 70.0, 72.0, 92.0]
[15.0, 30.0, 32.0, 45.0, 56.0, 60.0, 62.0, 65.0, 70.0, 72.0, 92.0]
*/

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics