Java实现希尔排序算法

希尔排序shell sort是一种算法,该算法首先对彼此分开的元素进行排序,然后依次减小要排序的元素之间的间隔。它是插入排序的通用版本。

在希尔排序中,将按特定间隔对元素进行排序。元素之间的间隔根据使用的顺序逐渐减小。shell排序的性能取决于给定输入数组使用的序列类型。

使用的一些最佳顺序是:

  • Shell的原始顺序: N/2 , N/4 , …, 1
  • Knuth的增量: 1, 4, 13, …, (3k – 1) / 2
  • Sedgewick的增量: 1, 8, 23, 77, 281, 1073, 4193, 16577...4j+1+ 3·2j+ 1
  • 希伯德的增幅: 1, 3, 7, 15, 31, 63, 127, 255, 511…
  • Papernov和Stasevich增量: 1, 3, 5, 9, 17, 33, 65,...
  • 普拉特: 1, 2, 3, 4, 6, 9, 8, 12, 18, 27, 16, 24, 36, 54, 81....

Shell Sort如何工作?

  1. 假设我们需要对以下数组进行排序。壳排序步骤

    初始数组

  2. 我们(N/2, N/4, ...1在算法中使用了shell的原始序列作为间隔。

    在第一个循环中,如果数组大小为0 N = 8,则对间隔为的元素N/2 = 4进行比较并交换(如果它们不按顺序排列)。
    1. 将第0个元素与 第四名 元素。
    2. 如果第0个元素大于 第四名 然后, 第四名首先将元素存储在temp变量中,并将0th元素(即更大的元素)存储在该4th位置中,将其中存储的元素temp存储在该0th位置中。壳排序步骤

      以n / 2间隔重新排列元素


      对于所有其余元素,此过程将继续进行。外壳排序步骤

      以n / 2间隔重新排列所有元素

  3. 在第二个循环中,采用的间隔,N/4 = 8/4 = 2并再次对位于这些间隔的元素进行排序。壳排序步骤

    以n / 4间隔重新排列元素


    此时您可能会感到困惑。壳排序步骤

    比较当前间隔中数组中的所有元素。


    的元素 第四名和2nd位置进行比较。的元素第二名和0th位置也进行比较。比较当前间隔中数组中的所有元素。
  4. 其余元素的处理相同。壳排序步骤

    以n / 4间隔重新排列所有元素

  5. 最后,当间隔N/8 = 8/8 =1为时,对间隔为1的数组元素进行排序。现在,该数组已完全排序。壳排序步骤

    以n / 8间隔重新排列元素


希尔排序算法

希尔排序(数组,大小)
  为间隔I < -大小/ 2n的下降到1
    对每个间隔“i”的数组
        排序所有在间隔元件“i”的
结束希尔排序

Java示例

 

import java.util.Arrays;

public class ShellSortDemo {
	/* An utility function to print array of size n */

	/* function to sort array using shellSort */
	void sort(int A[]) {
		int n = A.length;

		// Start with a larger gap, then reduce the gap to 1
		// we take gap sequence in order of |N/2|, |N/4|, |N/8|...1
		for (int gap = n / 2; gap > 0; gap /= 2) {
			// we perform gapped insertion sort for this gap size.
			// The first gap elements a[0..gap-1] are already
			// in gapped order keep adding one more element
			// until the entire array is gap sorted
			for (int i = gap; i < n; i += 1) {
				// store a[i] in temp and make a hole at
				// position i
				int temp = A[i];
				// shift earlier gap-sorted elements up until
				// the correct location for a[i] is found
				int j;
				for (j = i; j >= gap && A[j - gap] > temp; j -= gap)
					A[j] = A[j - gap];

				// put temp (the original a[i]) in its correct
				// location
				A[j] = temp;
			}
		}
	}

	// Driver method
	public static void main(String args[]) {
		int arr[] = { 61, 109, 149, 111, 34, 2, 24, 119, 122, 125, 27, 145 };
		// print unsorted array using Arrays.toString()
		System.out.print("Unsorted array: ");
		System.out.println(Arrays.toString(arr));

		ShellSortDemo ob = new ShellSortDemo();
		ob.sort(arr);

		System.out.print("Sorted array: ");
		// print sorted array
		System.out.println(Arrays.toString(arr));
	}
}
public class ShellSortDemo2 {
	public static void main(String[] args) {
		// Array of 20 elements
		int[] intArr = { 47, 85, 620, 3456, 7, 10, 4500, 106, 345, 1000, 67, 80, 5500, 34, 78, 782, 4, 0, 99, 190 };
		int[] sortedArray = shellSort(intArr);
		System.out.println("Sorted array is- ");
		for (int num : sortedArray) {
			System.out.print(num + " ");
		}
	}

	private static int[] shellSort(int[] intArr) {
		int gap = 1;
		int temp;
		// initial gap value calculation
		while (gap <= intArr.length / 3) {
			gap = (gap * 3) + 1;
		}
		while (gap > 0) {
			for (int i = gap; i < intArr.length; i++) {
				temp = intArr[i];
				int j;
				for (j = i; j > gap - 1 && intArr[j - gap] >= temp; j = j - gap) {
					intArr[j] = intArr[j - gap];
				}
				intArr[j] = temp;
			}
			// next gap value calculation
			gap = (gap - 1) / 3;
		}
		return intArr;
	}
}

复杂

Shell排序是一种不稳定的排序算法,因为该算法不会检查间隔之间的元素。

时间复杂度

  • 最坏情况复杂度:小于或等于 shell排序的最坏情况复杂度始终小于或等于。 根据Poonen定理,壳排序的最坏情况复杂度是或或介于两者之间。O(n2)
    O(n2)

    Θ(Nlog N)2/(log log N)2)Θ(Nlog N)2/log log N)Θ(N(log N)2)
  • 最佳情况复杂度O(n*log n)
    对数组进行排序后,每个时间间隔(或增量)的比较总数等于数组的大小。
  • 平均案件复杂度O(n*log n)
    在左右。O(n1.25)

 

 

复杂程度取决于选择的间隔。对于选择的不同增量序列,上述复杂度有所不同。最佳递增顺序未知。

空间复杂度:

外壳排序的空间复杂度为O(1)


希尔排序应用

在以下情况下使用Shell排序:

  • 调用堆栈是开销。uClibc库使用这种排序。
  • 递归超出限制。bzip2压缩器使用它。
  • 当靠近的元素相距很远时,插入排序的效果不佳。壳排序有助于缩短封闭元素之间的距离。因此,将执行的交换次数将更少。

猜你喜欢

转载自blog.csdn.net/allway2/article/details/114002093
今日推荐