冒泡、插入、希尔、快速、归并、堆排序算法实现(Java)

/**
 * 实现排序算法:冒泡、插入、希尔、快速、归并、堆
 * 
 * @author yhr
 *
 */
public class SortUtil {

	/**
	 * 冒泡排序(每趟确定一个值放后面,相邻比较) 稳定,最好n,最差n2,平均n2
	 * 
	 * @param arr
	 */
	void bublleSort(int[] arr) {

		int tmp;

		for (int i = arr.length - 1; i > 0; i--) {
			for (int j = 0; j < i; j++) {
				if (arr[j] > arr[j + 1]) {
					tmp = arr[j];
					arr[j] = arr[j + 1];
					arr[j + 1] = tmp;
				}
			}
		}
	}

	/**
	 * 插入排序( 每趟取一个值往前比较,前面已排序) 稳定,最好n,最差n2,平均n2
	 * 
	 * @param arr
	 */
	void insertSort(int[] arr) {

		int current, j;

		for (int i = 1; i < arr.length; i++) {
			current = arr[i];
			for (j = i - 1; j >= 0; j--) {
				// 注意判断
				if (current >= arr[j]) {
					break;
				}
				arr[j + 1] = arr[j];
			}
			arr[j + 1] = current;
		}
	}

	/**
	 * 希尔排序(带步长的插入排序) 不稳定
	 * 
	 * @param arr
	 */
	void shellSort(int[] arr) {

		int current, j;

		for (int step = arr.length / 2; step >= 1; step /= 2) {
			for (int i = step; i < arr.length; i++) {
				current = arr[i];
				for (j = i - step; j >= 0; j -= step) {
					if (current >= arr[j]) {
						break;
					}
					arr[j + step] = arr[j];
				}
				arr[j + step] = current;
			}
		}
	}

	/**
	 * 快速排序(每趟确定pivot的位置,然后递归) 不稳定,最好nlogn,最坏n2,平均nlogn
	 * 
	 * @param arr
	 * @param start
	 * @param end
	 */
	void quickSort(int[] arr, int start, int end) {
		if (start >= end) {
			return;
		}

		// 选start或者end位置的值作为pivot
		int pivot = arr[start];
		int i = start + 1;
		int j = end;
		while (i <= j) {
			while (i <= end && arr[i] < pivot) {
				i++;
			}
			while (j >= start && arr[j] > pivot) {
				j--;
			}
			// 可能arr[i]等于arr[j]等于pivot
			if (i <= j) {
				int tmp = arr[i];
				arr[i] = arr[j];
				arr[j] = tmp;
				// 有相等交换后指针需要移动
				i++;
				j--;
			}
		}

		arr[start] = arr[j];
		arr[j] = pivot;
		quickSort(arr, start, j - 1);
		quickSort(arr, j + 1, end);
	}

	/**
	 * 归并排序(分割、递归、合并) 稳定,最好nlogn,最坏nlogn,平均nlogn
	 * 
	 * @param arr
	 * @param start
	 * @param end
	 * @param tmpArr
	 */
	void mergeSort(int[] arr, int start, int end, int[] tmpArr) {
		if (start >= end) {
			return;
		}

		int mid = (start + end) / 2;
		mergeSort(arr, start, mid, tmpArr);
		mergeSort(arr, mid + 1, end, tmpArr);
		merge(arr, start, mid, end, tmpArr);
	}

	void merge(int[] arr, int lStart, int lEnd, int rEnd, int[] tmpArr) {
		int rStart = lEnd + 1;
		int tmpArrStart = lStart;
		int arrStart = lStart;

		while (lStart <= lEnd && rStart <= rEnd) {
			if (arr[lStart] <= arr[rStart]) {
				tmpArr[tmpArrStart++] = arr[lStart++];
			} else {
				tmpArr[tmpArrStart++] = arr[rStart++];
			}
		}
		while (lStart <= lEnd) {
			tmpArr[tmpArrStart++] = arr[lStart++];
		}
		while (rStart <= rEnd) {
			tmpArr[tmpArrStart++] = arr[rStart++];
		}

		while (arrStart <= rEnd) {
			arr[arrStart] = tmpArr[arrStart];
			arrStart += 1;
		}
	}

	/**
	 * 堆排序(通过下滤建堆和删除堆顶) 不稳定,最好nlogn,最坏nlogn,平均nlogn
	 * 
	 * @param arr
	 */
	void heapSort(int[] arr) {
		// 最后个节点为arr.length - 1,它的父节点即为最后个有孩子的节点为arr.length / 2 - 1
		for (int i = arr.length / 2 - 1; i >= 0; i--) {
			down(arr, arr.length, i);
		}
		for (int i = arr.length - 1; i > 0; i--) {
			int tmp = arr[0];
			arr[0] = arr[i];
			arr[i] = tmp;
			down(arr, i, 0);
		}
	}

	void down(int[] arr, int n, int pos) {
		// 取需要下滤的值向下比较一直到没有孩子或比较完成
		int current = arr[pos];
		for (int child = 2 * pos + 1; child < n; child = 2 * pos + 1) {
			if (child != n - 1 && arr[child] < arr[child + 1]) {
				child += 1;
			}
			if (arr[child] <= current) {
				break;
			}
			
			arr[pos] = arr[child];
			pos = child;
		}
		arr[pos] = current;
	}

}
发布了5 篇原创文章 · 获赞 0 · 访问量 2543

猜你喜欢

转载自blog.csdn.net/yyy_hr/article/details/105135045