经典排序算法代码实现(持续更新... 求补充)

5 篇文章 0 订阅
4 篇文章 0 订阅

1.快速排序Quick sort

原理,通过一趟扫描将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列

	/**
	 * 快速排序算法
	 * 
	 * @param array
	 *            待排序数组
	 * @param low
	 *            数组待排序部分开始索引
	 * @param high
	 *            数组待排序部分结束索引
	 */
	@Override
	public void fastSort(E[] array, int low, int high)
	{
		// TODO Auto-generated method stub
		if (low >= high || array == null)
			return;
		E sentry = array[low];
		int i = low, j = high;
		while (i < j)
		{
			while (i < j && sentry.compareTo(array[j]) <= 0)
				j--;
			if (i != j)
			{
				E temp = array[i];
				array[i] = array[j];
				array[j] = temp;
			}

			while (i < j && sentry.compareTo(array[i]) >= 0)
				i++;
			if (i != j)
			{
				E temp = array[i];
				array[i] = array[j];
				array[j] = temp;
			}
		}
		fastSort(array, low, i - 1);
		fastSort(array, i + 1, high);
	}

	/**
	 * 快速排序算法
	 * 
	 * @param array
	 *            待排序数组
	 */
	@Override
	public void fastSort(E[] array)
	{
		// TODO Auto-generated method stub
		if (array == null)
			return;
		fastSort(array, 0, array.length - 1);
	}

2. 桶排序Bucket sort

 桶排序是稳定的,桶排序是常见排序里最快的一种,但是同时也非常耗空间,基本上是最耗空间的一种排序算法

	/**
	 * 桶排序算法:适用于类型为非负整数的数组,数组中不可以有重复元素
	 * 
	 * @param array
	 *            待排序数组
	 */
	@Override
	public void bucketSort(int[] array)
	{
		// TODO Auto-generated method stub
		if (array == null)
			return;
		int maxE = 0;
		for (int i = 0; i < array.length; i++)
		{
			if (array[i] < 0)
				return;
			if (array[i] > maxE)
				maxE = array[i];
		}
		if (maxE == 0)
			return;

		int[] bucket = new int[maxE + 1];

		for (int i = 0; i < array.length; i++)
		{
			bucket[array[i]]++;
		}
		
		for (int i = 0, k = 0; i < bucket.length && k < array.length; i++)
		{
			if (bucket[i] > 0)
			{
				array[k++] = i;
			}
		}
	}

3. 鸽巢排序Pigeonhole sort

原理类似桶排序,数组的索引位置就表示值,该索引位置的值表示出现次数,如果全部为1次或0次那就是桶排序

	/**
	 * 鸽笼排序算法:对桶排序的改进,适用于类型为非负整数的数组,可以有重复元素
	 * 
	 * @param array
	 *            待排序数组
	 */
	@Override
	public void pigeonHoleSort(int[] array)
	{
		// TODO Auto-generated method stub
		if (array == null)
			return;
		int maxE = 0;
		for (int i = 0; i < array.length; i++)
		{
			if (array[i] < 0)
				return;
			if (array[i] > maxE)
				maxE = array[i];
		}
		if (maxE == 0)
			return;

		int[] pigeonHole = new int[maxE + 1];

		for (int i = 0; i < array.length; i++)
		{
			pigeonHole[array[i]]++;
		}
		for (int i = 0, k = 0; i < pigeonHole.length && k < array.length; i++)
		{
			if (pigeonHole[i] > 0)
			{
				for (int j = 0; j < pigeonHole[i]; j++)
					array[k++] = i;
			}
		}
	}

4. 插入排序Insertion sort

插入排序就是每一步都将一个待排数据按其大小插入到已经排序的数据中的适当位置,直到全部插入完毕。

	/**
	 * 插入排序算法
	 * 
	 * @param array
	 *            待排序数组
	 */
	@Override
	public void insertSort(E[] array)
	{
		// TODO Auto-generated method stub
		if (array == null)
			return;
		for (int i = 1; i < array.length; i++)
		{
			E cur = array[i];
			int j = i - 1;
			for (; j >= 0; j--)
			{
				if (cur.compareTo(array[j]) < 0)
					array[j + 1] = array[j];
				else
					break;
			}
			if (j + 1 != i)
				array[j + 1] = cur;
		}
	}

5. 希尔排序Shell sort

希尔排序Shell Sort是基于插入排序的一种改进

	/**
	 * 希尔排序算法:內部用插入排序算法
	 * 
	 * @param array
	 *            待排序数组
	 */
	@Override
	public void shellSort(E[] array)
	{
		// TODO Auto-generated method stub
		if (array == null)
			return;
		int increment = (array.length + 1) / 2;
		while (increment >= 1)
		{
			for (int i = 0; i + increment < array.length; i++)
			{
				for (int j = i + increment; j < array.length; j += increment)
				{
					E cur = array[j];
					int k = j - increment;
					for (; k >= i; k -= increment)
					{
						if (cur.compareTo(array[k]) < 0)
							array[k + increment] = array[k];
						else
							break;
					}
					if (k + increment != j)
						array[k + increment] = cur;
				}
			}
			increment /= 2;
		}
	}

6. 冒泡排序Bubble sort

临近的数字两两进行比较,按照从小到大或者从大到小的顺序进行交换

	/**
	 * 冒泡排序算法
	 * 
	 * @param array
	 *            待排序数组
	 */
	@Override
	public void bubbleSort(E[] array)
	{
		// TODO Auto-generated method stub
		if (array == null)
			return;
		boolean exchanged = true;
		for (int i = 0; i < array.length - 1; i++)
		{
			exchanged = false;
			for (int j = 0; j < array.length - i - 1; j++)
			{
				if (array[j].compareTo(array[j + 1]) > 0)
				{
					E temp = array[j];
					array[j] = array[j + 1];
					array[j + 1] = temp;
					exchanged = true;
				}
			}
			if (exchanged == false)
				break;
		}
	}

7. 鸡尾酒排序Cocktail sort

鸡尾酒排序基于冒泡排序,双向循环

	/**
	 * 鸡尾酒排序算法:鸡尾酒排序基于冒泡排序,双向循环
	 * 
	 * @param array
	 *            待排序数组
	 */
	@Override
	public void cocktailSort(E[] array)
	{
		// TODO Auto-generated method stub
		if (array == null)
			return;
		boolean exchanged = true;
		int ii = 0, jj = array.length - 1;
		while (exchanged && ii < jj)
		{
			exchanged = false;
			for (int i = ii; i < jj; i++)
			{
				if (array[i].compareTo(array[i + 1]) > 0)
				{
					E temp = array[i];
					array[i] = array[i + 1];
					array[i + 1] = temp;
					exchanged = true;
				}
			}
			jj--;
			for (int j = jj; j > ii; j--)
			{
				if (array[j - 1].compareTo(array[j]) > 0)
				{
					E temp = array[j];
					array[j] = array[j - 1];
					array[j - 1] = temp;
					exchanged = true;
				}
			}
			ii++;
		}
	}

8. 梳排序Comb sort

梳排序还是基于冒泡排序,与冒泡不同的是,梳排序比较的是固定距离处的数的比较和交换,类似希尔那样

这个固定距离是待排数组长度除以1.3得到近似值,下次则以上次得到的近似值再除以1.3,直到距离小至3时,以1递减

	/**
	 * 梳排序算法:梳排序还是基于冒泡排序,与冒泡不同的是,梳排序比较的是固定距离处的数的比较和交换,
	 * 类似希尔那样,这个固定距离是待排数组长度除以1.3得到近似值,下次则以上次得到的近似值再除以1.3,直到距离小至3时,以1递减
	 * 
	 * @param array
	 *            待排序数组
	 */
	@Override
	public void combSort(E[] array)
	{
		// TODO Auto-generated method stub
		if (array == null)
			return;
		int increment = (int) (array.length / 1.3);
		while (increment > 3)
		{
			for (int i = 0; i + increment < array.length; i++)
			{
				for (int j = i + increment; j < array.length; j += increment)
				{
					E cur = array[j];
					int k = j - increment;
					for (; k >= i; k -= increment)
					{
						if (cur.compareTo(array[k]) < 0)
							array[k + increment] = array[k];
						else
							break;
					}
					if (k + increment != j)
						array[k + increment] = cur;
				}
			}
			increment = (int) (increment / 1.3);
		}
		increment = 3;
		while (increment > 0)
		{
			for (int i = 0; i + increment < array.length; i++)
			{
				for (int j = i + increment; j < array.length; j += increment)
				{
					E cur = array[j];
					int k = j - increment;
					for (; k >= i; k -= increment)
					{
						if (cur.compareTo(array[k]) < 0)
							array[k + increment] = array[k];
						else
							break;
					}
					if (k + increment != j)
						array[k + increment] = cur;
				}
			}
			increment--;
		}
	}

9. 选择排序Selection sort

直接从待排序数组里选择一个最小(或最大)的数字,每次都拿一个最小数字出来,顺序放入新数组,直到全部拿完

	/**
	 * 简单选择排序算法
	 * 
	 * @param array
	 *            待排序数组
	 */
	@Override
	public void simpleSelectSort(E[] array)
	{
		// TODO Auto-generated method stub
		if (array == null)
			return;
		boolean exchanged = true;
		int min;
		for (int i = 0; i < array.length - 1; i++)
		{
			exchanged = false;
			min = i;
			for (int j = i + 1; j < array.length; j++)
			{
				if (array[j].compareTo(array[min]) < 0)
				{
					// min = j;
					E temp = array[min];
					array[min] = array[j];
					array[j] = temp;
					exchanged = true;
				}
			}
			// if (min != i)
			// {
			// E temp = array[min];
			// array[min] = array[i];
			// array[i] = temp;
			// exchanged = true;
			// }
			if (exchanged == false)
				break;
		}
	}

10. 归并排序Merge sort

把原始数组分成若干子数组,对每一个子数组进行排序,继续把子数组与子数组合并,合并后仍然有序,直到全部合并完,形成有序的数组

	private void mergeSort(E[] array, int start, int mid, int end)
	{
		if (array == null)
			return;
		if (start <= mid && mid < end)
		{
			Object[] arrayTemp = new Object[mid - start + 1];
			for (int i = 0; i < arrayTemp.length; i++)
				arrayTemp[i] = array[start + i];
			int i = start, j = mid + 1, k = start;
			while (i <= mid && j <= end)
			{
				if (((E) arrayTemp[i - start]).compareTo(array[j]) > 0)
				{
					array[k++] = array[j++];
				} else
				{
					array[k++] = (E) arrayTemp[i++ - start];
				}
			}
			while (i <= mid)
				array[k++] = (E) arrayTemp[i++ - start];
		}
	}

	/**
	 * 归并排序算法
	 * 
	 * @param array
	 *            待排序数组
	 * @param start
	 *            数组待排序部分开始索引
	 * @param end
	 *            数组待排序部分结束索引
	 */
	@Override
	public void mergeSort(E[] array, int start, int end)
	{
		// TODO Auto-generated method stub
		if (array == null)
			return;
		if (start < end)
		{
			int mid = (start + end) / 2;
			mergeSort(array, start, mid);
			mergeSort(array, mid + 1, end);
			mergeSort(array, start, mid, end);
		}
	}

	/**
	 * 归并排序算法
	 * 
	 * @param array
	 *            待排序数组
	 */
	@Override
	public void mergeSort(E[] array)
	{
		// TODO Auto-generated method stub
		if (array == null)
			return;
		mergeSort(array, 0, array.length - 1);
	}

11. 堆排序Heap sort

	private void buildingHeap(Object[] heapArray)
	{
		if (heapArray == null)
			return;
		int heapLength = heapArray.length;
		int startIndex = heapLength / 2;
		while (startIndex > 0)
		{
			int startIndexTemp = startIndex;
			while (startIndexTemp <= heapLength / 2)
			{
				int childIndex = startIndexTemp * 2 - 1;
				if (startIndexTemp * 2 + 1 <= heapLength)
					childIndex = (((E) heapArray[startIndexTemp * 2 - 1])
							.compareTo((E) heapArray[startIndexTemp * 2]) < 0) ? startIndexTemp * 2 - 1
							: startIndexTemp * 2;
				if (((E) heapArray[startIndexTemp - 1])
						.compareTo((E) heapArray[childIndex]) > 0)
				{
					Object temp = heapArray[startIndexTemp - 1];
					heapArray[startIndexTemp - 1] = heapArray[childIndex];
					heapArray[childIndex] = temp;
				}
				startIndexTemp = childIndex + 1;
			}
			startIndex--;
		}
	}

	private void heapify(Object[] heapArray, int n)
	{
		if (heapArray == null || n <= 1)
			return;
		int heapLength = n;
		for (int i = 1; i <= heapLength / 2;)
		{
			int childIndex = i * 2 - 1;
			if (i * 2 + 1 <= heapLength)
				childIndex = (((E) heapArray[i * 2 - 1])
						.compareTo((E) heapArray[i * 2]) < 0) ? i * 2 - 1
						: i * 2;
			if (((E) heapArray[i - 1]).compareTo((E) heapArray[childIndex]) <= 0)
				return;

			Object temp = heapArray[i - 1];
			heapArray[i - 1] = heapArray[childIndex];
			heapArray[childIndex] = temp;

			i = childIndex + 1;
		}
	}

	/**
	 * 堆排序算法
	 * 
	 * @param array
	 *            待排序数组
	 */
	@Override
	public void heapSort(E[] array)
	{
		// TODO Auto-generated method stub
		if (array == null)
			return;
		Object[] heapArray = new Object[array.length];
		for (int i = 0; i < heapArray.length; i++)
			heapArray[i] = array[i];
		int heapLength = heapArray.length;
		int arrayLength = 0;
		buildingHeap(heapArray);
		while (heapLength > 0)
		{
			array[arrayLength++] = (E) heapArray[0];

			Object temp = heapArray[0];
			heapArray[0] = heapArray[heapLength - 1];
			heapArray[heapLength - 1] = temp;

			heapLength--;

			heapify(heapArray, heapLength);
		}
	}

12. 地精排序Gnome Sort

最简单的排序算法,只有一层循环,默认情况下前进冒泡,一旦遇到冒泡的情况发生就往回冒,直到把这个数字放好为止

	/**
	 * 地精排序算法:最简单的排序算法,只有一层循环,默认情况下前进冒泡,一旦遇到冒泡的情况发生就往回冒,直到把这个数字放好为止
	 * 
	 * @param array
	 *            待排序数组
	 */
	@Override
	public void gnomeSort(E[] array)
	{
		// TODO Auto-generated method stub
		if (array == null)
			return;
		int n = array.length;
		int i = 0;
		while (i < n)
		{
			if (i == 0 || array[i - 1].compareTo(array[i]) <= 0)
				i++;
			else
			{
				E temp = array[i];
				array[i] = array[i - 1];
				array[--i] = temp;
				// i--;
			}
		}
	}

13. 奇偶排序Odd-even sort

基本思路是奇数列与相邻的下一个偶数列比较交换排一趟序,偶数列与相邻的下一个奇数列比较交换排一趟序,交替进行,直到全部有序

	/**
	 * 奇偶排序算法:基本思路是奇数列与相邻的下一个偶数列比较交换排一趟序,偶数列与相邻的下一个奇数列比较交换排一趟序,交替进行,直到全部有序
	 * 
	 * @param array
	 *            待排序数组
	 */
	@Override
	public void oddEvenSort(E[] array)
	{
		// TODO Auto-generated method stub
		if (array == null)
			return;
		int odd = 0, even = 1;
		boolean exchanged = true;
		while (exchanged)
		{
			exchanged = false;
			// 偶数列
			for (int i = odd; i < array.length - 1; i += 2)
			{
				if (array[i].compareTo(array[i + 1]) > 0)
				{
					E temp = array[i];
					array[i] = array[i + 1];
					array[i + 1] = temp;
					exchanged = true;
				}
			}
			// 奇数列
			for (int i = even; i < array.length - 1; i += 2)
			{
				if (array[i].compareTo(array[i + 1]) > 0)
				{
					E temp = array[i];
					array[i] = array[i + 1];
					array[i + 1] = temp;
					exchanged = true;
				}
			}
		}
	}

14. 计数排序Counting sort

选票数组用来统计比当前数小的数的个数,有几个数就有几张选票,那么最小的数有0张,最大的数有数组长度减1张。

根据选票数进行入桶,入桶后的顺序即使排好序的顺序。

	/**
	 * 计数排序算法:计数排序同时兼有桶排的高效和快排的霸道,时间复杂度O(n^2),空间复杂度O(n);小于等于桶排序的空间复杂度
	 * 
	 * @param array
	 *            待排序数组
	 */
	@Override
	public void countingSort(E[] array)
	{
		// TODO Auto-generated method stub
		if (array == null)
			return;
		int[] ballot = new int[array.length];
		Object[] bucket = new Object[array.length];

		for (int i = 0; i < array.length - 1; i++)
		{
			for (int j = i + 1; j < array.length; j++)
			{
				// 拉选票
				if (array[i].compareTo(array[j]) > 0)
					ballot[i]++;
				else
					ballot[j]++;
			}
		}
		for (int i = 0; i < array.length; i++)
		{
			bucket[ballot[i]] = array[i];
		}
		for (int i = 0; i < array.length; i++)
		{
			array[i] = (E) bucket[i];
		}
	}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值