《数据结构与算法分析(Java语言描述)》读书笔记——排序算法和快速选择

1、插入排序

public static void insertionSort(int[] a) {
    for (int i = 1; i < a.length; i++) {
		int j;
		int temp = a[i];
		for (j = i; j > 0 && temp < a[j - 1]; j--) {
			a[j] = a[j - 1];
		}
		a[j] = temp;
	}
}

2、希尔排序

    选择不同的增量序列会有不同的复杂度,有n的3/2,4/3,6/5次方等复杂度

public static void shellSort(int[] a) {
	for (int gap = a.length >> 1; gap > 0; gap >>= 1) {
		for (int i = gap; i < a.length; i++) {
			int j;
			int temp = a[i];
			for (j = i; j >= gap && temp < a[j - gap]; j -= gap) {
				a[j] = a[j - gap];
			}
			a[j] = temp;
		}
	}
}

3、堆排序

public static int[] sort(int[] a) {
	for (int i = a.length >> 1; i >= 0; i--)
		percDown(a, i, a.length - 1);
	for (int i = a.length - 1; i > 0; i--) {
		int temp = a[i];
		a[i] = a[0];
		a[0] = temp;
		percDown(a, 0, i - 1);
	}
	return a;
}

public static void percDown(int[] a, int i, int n) {
	int temp = a[i];
	for (int child = i; (child << 1) + 1 <= n; i = child) {
		child = (i << 1) + 1;
		if (child + 1 <= n && a[child] < a[child + 1])
			child++;
		if (temp < a[child])
			a[i] = a[child];
		else
			break;
	}
	a[i] = temp;
}

3、归并排序

public static void mergeSort(int[] a, int[] tempArray, int left, int right) {
	if (left >= right)
		return;
	int mid = ((right - left) >> 1) + left;
	mergeSort(a, tempArray, left, mid);
	mergeSort(a, tempArray, mid + 1, right);
	merge(a, tempArray, left, mid + 1, right);
}
public static void merge(int[] a, int[] tempArray, int leftPos, int rightPos, int rightEnd) {
	int current = leftPos;
	int leftStart = leftPos;
	int rightStart = rightPos;

	while (leftStart <= rightPos - 1 && rightStart <= rightEnd) {
		if (a[leftStart] > a[rightStart])
			tempArray[current++] = a[rightStart++];
		else
			tempArray[current++] = a[leftStart++];
	}
	while (leftStart <= rightPos - 1)
		tempArray[current++] = a[leftStart++];
	while (rightStart <= rightEnd)
		tempArray[current++] = a[rightStart++];
	for (int i = leftPos; i <= rightEnd; i++)
		a[i] = tempArray[i];
}

4、快速排序

T(n) = 2T(n/2) + n,nlogn

public static void quickSort(int[] a, int low, int high) {
	if (low >= high)
		return;
	int pivot = partition(a, low, high);
	quickSort(a, low, pivot - 1);
	quickSort(a, pivot + 1, high);
}

public static int partition(int[] a, int low, int high) {
	int key = a[low];
	while (low < high) {
		while (a[high] >= key && high > low)
			high--;
		a[low] = a[high];
		while (a[low] <= key && high > low)
			low++;
		a[high] = a[low];
	}
	a[low] = key;
	return low;
}

5、快速选择  O(n)

public static void quickSelect(int[] a, int low, int high, int k){
	if(low >= high) return;
	int mid = partition(a, low, high);
	if(k == mid + 1)
		return;
	if(k <= mid)
		quickSelect(a, low, mid - 1, k);
	else
		quickSelect(a, mid + 1, high, k);
}

6、桶排序

    适用于小正整数的排序,需要知道元素上界,O(n)

7、外部排序

    多路归并:N个顺串构造完毕后,k路合并需要logk N趟

    替换选择:用于构造归并顺串的算法,可以构造大小是内存两倍的顺串。先用全部内存构造堆,输出堆顶的数字进入顺串,再读入一个数,如果比堆顶大则加入堆,如果比堆顶小就将堆的大小减一(因为这个数可能比刚输出的数小,把这个数放在堆的最后一位,将堆大小减一)。这样每次有一个数出堆,有0.5个数进堆,最后堆大小为0,顺串长度的期望值是内存大小的两倍。

你可能感兴趣的:(数据结构与算法)