Java排序

冒泡、选择、插入、归并、shell、快速排序

结果:从小到大排列

Bubble Sort

从左到右,相邻数据两两比较,右边数据小,则交换二者位置,每次将最大数据移至最右

 

Select Sort

从左到右,用maxDex为索引的数据(最右未有序的数据)和前面每个数据进行比较,如比maxDex指向的数据大,则用其索引替换maxDex,最后交换索引为maxDex和当前最右未有序处的数据。

 

Insert Sort

假设某数据右边的数据是有序的,将其存储在temp中,与右边的数据从左往右依次比较,每次都将比它小的数据左移一位,直到插入比它大的数据前面或放在最右。

Insert(BinarySearch) Sort

在寻找未有序的数据的右侧位置时,使用二分查找。

 

Merge Sort

归并

 

Shell Sort

Insert sort   h-增量排序

h=3*h+1

 

Quick Sort

划分

1.以最后一个数据为pivot。头、尾(pivot前一个)同时和pivot比较,头部不小于pivot的值和尾部不大于pivot的值互相交换。然后将pivot置于两组数之间(尾部的头部和pivot交换实现)。

2.以头中尾三个数据中,中等大小的为pivot。最小的置于头部,最大的置于尾部,pivot置于尾部左侧一位。头部右侧一位、尾(pivot前一个)同时和pivot比较……小于等于3个数据人工排序。

3.以头中尾三个数据中,中等大小的为pivot。小于等于10个数据用插入排序。

 

package sort;

import java.util.HashSet;
import java.util.Random;
import java.util.Set;

public class ArraySort {

	public static int[] createIntArray(int size) {
		int[] a = new int[size];
		for (int i = 0; i < size; i++) {
			a[i] = (int) (Math.random() * size);
		}
		return a;
	}

//这并不是一个很好的创建随机数组的方法
//当需要的随机数超过1000个就不能保证其是否有重复的数据
//float精确的不高
	public static int[] createIntArrayNoRepeat(int min, int max) {
		int length = max - min + 1;
		int[] a = new int[length];
		Set<Float> set = new HashSet<Float>();
		Random rand = new Random();
		for (int i = min; i < max+1; i++) {
			set.add(i + rand.nextFloat());
		}
		int j = 0;
		for (Float f : set) {
			a[j++] = (int) f.floatValue();
		}
		return a;
	}

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

	public static int[] copyArray(int[] a) {
		int[] b = new int[a.length];
		for (int i = 0; i < a.length; i++) {
			b[i] = a[i];
		}
		return b;

	}

	public static void bubbleSort(int[] a) {
		for (int out = a.length - 1; out > 0; out--) {
			for (int in = 0; in < out; in++) {
				if (a[in] > a[in + 1]) {
					int temp = a[in];
					a[in] = a[in + 1];
					a[in + 1] = temp;
				}
			}
		}
	}

	public static void selectSort(int[] a) {
		for (int out = a.length - 1; out > 0; out--) {
			int max = out;
			for (int in = 0; in < out; in++) {
				if (a[in] > a[max]) {
					max = in;
				}
			}
			int temp1 = a[out];
			a[out] = a[max];//最大值放在右侧
			a[max] = temp1;
		}
	}

	//
	public static void insertSort(int[] a) {
		if (a == null) {
			return;
		}
		for (int out = a.length - 1; out > 0; out--) {
			int tempValue = a[out - 1];
			for (int in = out; in < a.length; in++) {
				if (tempValue > a[in]) {
					a[in - 1] = a[in];
					if (in == a.length - 1) {
						a[in] = tempValue;
					}
				} else {
					a[in - 1] = tempValue;
					break;
				}
			}
		}
	}

	//
	public static void insertSortWithBinarySearch(int[] a) {
		if (a == null) {
			return;
		}
		for (int out = a.length - 1; out > 0; out--) {
			int tempValue = a[out - 1];

			int leftDex = out;
			int rightDex = a.length;
			int mid = 0;

			while (leftDex < rightDex) {
				mid = (leftDex + rightDex) >>> 1;
				if (tempValue > a[mid]) {
					leftDex = mid + 1;
				} else if (tempValue < a[mid]) {
					rightDex = mid;
				} else {
					// 可以有重复的数据,但是不保证重复数据的先后位置(不稳定的)
					break;
				}
			}

			int sDex = 0;
			// 没找到,这时 leftDex==rightDex is true,插入的数据一定比索引为leftDex的数小
			if (leftDex == rightDex) {
				sDex = leftDex;
			} else {
				// 找到与这个数据相同的数据,放在其左或右从结果来看都是一样的
				sDex = mid;
			}

			for (int i = out; i < sDex; i++) {
				a[i - 1] = a[i];
			}
			a[sDex - 1] = tempValue;
		}
	}

	private static void insertSort(int[] a, int low, int high) {
		if (a == null) {
			return;
		}
		for (int out = high; out > low; out--) {
			int tempValue = a[out - 1];
			for (int in = out; in <= high; in++) {
				if (tempValue > a[in]) {
					a[in - 1] = a[in];
					if (in == high) {
						a[in] = tempValue;
					}
				} else {
					a[in - 1] = tempValue;
					break;
				}
			}
		}
	}

	//
	public static void mergeSort(int[] a) {
		if (a.length == 0 || a.length == 1) {
			return;
		}
		int[] tempArray = new int[a.length];
		sort(a, 0, a.length - 1, tempArray);
	}

	private static void sort(int[] a, int lowerBound, int upperBound,
			int[] tempArray) {
		if (lowerBound == upperBound) {
			return;
		}
		int mid = (lowerBound + upperBound) >>> 1;
		sort(a, lowerBound, mid, tempArray);
		sort(a, mid + 1, upperBound, tempArray);
		merge(a, lowerBound, mid + 1, upperBound, tempArray);
	}

	private static void merge(int[] a, int lowDex, int highDex, int upperBound,
			int[] temp) {
		int tempArrayDex = lowDex;
		int lowerBound = lowDex;
		int lowPartUpperBound = highDex - 1;
		while (lowDex <= lowPartUpperBound && highDex <= upperBound) {
			if (a[lowDex] <= a[highDex]) {
				temp[tempArrayDex++] = a[lowDex++];
			} else {
				temp[tempArrayDex++] = a[highDex++];
			}
		}
		while (lowDex <= lowPartUpperBound) {
			temp[tempArrayDex++] = a[lowDex++];
		}
		while (highDex <= upperBound) {
			temp[tempArrayDex++] = a[highDex++];
		}
		for (int i = lowerBound; i < upperBound + 1; i++) {
			a[i] = temp[i];
		}
	}

	//
	public static void shellSort(int[] a) {
		if (a == null) {
			return;
		}
		int h = 1;
		while (h < a.length / 3) {
			h = h * 3 + 1;
		}
		while (h > 0) {
			for (int out = a.length - 1; out >= h; out--) {
				int tempValue = a[out - h];
				for (int in = out; in < a.length; in += h) {
					if (tempValue > a[in]) {
						a[in - h] = a[in];
						if (in + h >= a.length) {
							a[in] = tempValue;
						}
					} else {
						a[in - h] = tempValue;
						break;
					}
				}
			}
			h = (h - 1) / 3;
		}
	}

	// 以最右一个值为pivot
	public static void quickSort1(int[] a) {
		if (a == null || a.length <= 1) {
			return;
		}
		reFast1(a, 0, a.length - 1);
	}

	private static void reFast1(int[] a, int low, int high) {
		if (low < high) {
			int mid = partition1(a, low, high, a[high]);// 以最右一个值为pivot
			reFast1(a, low, mid - 1);
			reFast1(a, mid + 1, high);
		}
	}

	private static int partition1(int[] a, int low, int high, int pivot) {
		int left = low;
		int right = high - 1;// pivot is not included
		while (true) {
			while (a[left] < pivot) {// when left=high or a[left]=pivot then
										// break
				left++;
			}
			while (right > left && a[right] > pivot) {// right>left is needed
				right--;
			}
			if (left < right) {
				swap(a, left, right);
				left++;
			} else {
				break;
			}
		}
		swap(a, left, high);// small array, pivot, big array
		return left;
	}

	// 以第一个、中间以及最后一个值中的中等大小的值为pivot
	public static void quickSort2(int[] a) {
		if (a == null || a.length <= 1) {
			return;
		}
		reFast2(a, 0, a.length - 1);
	}

	private static void reFast2(int[] a, int low, int high) {
		if ((high - low) <= 0) {// <= 1个
			return;
		}
		if ((high - low) <= 2) {// 2、3个
			manualSort(a, low, high);
			return;
		}
		int pivot = medianOf3(a, low, high);
		int mid = partition2(a, low, high, pivot);
		reFast2(a, low, mid - 1);
		reFast2(a, mid + 1, high);
	}

	private static int partition2(int[] a, int low, int high, int pivot) {
		int left = low + 1;
		int right = high - 2;// a[high-1]=pivot,a[high]>=pivot
		while (true) {
			while (a[left] < pivot) {// when left=high-1,or a[left]>=pivot then
										// break
				left++;
			}
			while (a[right] > pivot) {// when right=low or a[right]<=pivot then
										// break
				right--;
			}
			if (left < right) {
				swap(a, left, right);
				left++;
			} else {
				break;
			}
		}
		swap(a, left, high - 1);
		return left;
	}

	private static void manualSort(int[] a, int low, int high) {
		if (high - low == 1) {
			if (a[low] > a[high]) {
				int temp = a[low];
				a[low] = a[high];
				a[high] = temp;
			}
		} else if (high - low > 1) {
			int mid = (high + low) >>> 1;

			if (a[low] > a[mid]) {
				swap(a, low, mid);
			}
			if (a[mid] > a[high]) {
				swap(a, mid, high);
			}
			if (a[low] > a[mid]) {
				swap(a, low, mid);
			}

		}
	}

	private static int medianOf3(int[] a, int low, int high) {
		manualSort(a, low, high);
		int mid = (high + low) >>> 1;
		swap(a, mid, high - 1);
		// swap(a,high-1,high);
		return a[high - 1];
	}

	// 对于length小于等于10的采用插入排序
	public static void quickSort3(int[] a) {
		if (a == null || a.length <= 1) {
			return;
		}
		reFast3(a, 0, a.length - 1);
	}

	private static void reFast3(int[] a, int low, int high) {
		if (low == high) {
		} else if ((high - low) < 10) {
			insertSort(a, low, high);
		} else {
			int pivot = medianOf3(a, low, high);
			int mid = partition2(a, low, high, pivot);
			reFast3(a, low, mid - 1);
			reFast3(a, mid, high);
		}
	}

	private static void swap(int[] a, int dex1, int dex2) {
		int temp = a[dex1];
		a[dex1] = a[dex2];
		a[dex2] = temp;
	}

}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值