データ構造とアルゴリズムのバイナリツリーソートの詳細な説明

バイナリツリー(ヒープ)の概念

バイナリツリー(ヒープ)は構造です。各ノードは2つの子ノードを持つことができるため、逆ツリー構造を形成し、配列もバイナリツリーと見なすことができ、バイナリツリーの各ノードは配列の1つと見なすことができます。要素。

       10
   23      25
134 135   9

示されているバイナリツリーは、配列[10,23,25,134,135,9]に対応しています。

ヒープの各ノードが2つの子ノードより大きい場合、このバイナリツリーを最大ヒープと呼びます。

ノードiのサブツリーがすべて最大ヒーププロパティを満たす場合、2つのサブツリーをそれより大きなサブツリーに交換し、ノードが最大ヒープになるときにサブヒープをiと交換できます。コードは次のとおりです。

    /**
	 * 如果i节点下是最大堆,将包括i的子树构建成最大堆
	 * 
	 * @param array
	 * @param i
	 * @param heapSize 二叉树的有效长度
	 * @return
	 */
	public static int[] maxHeapify(int[] array, int i, int heapSize) {
		int l = left(i);
		int r = right(i);
		int large;
		if (l < heapSize && array[l] > array[i]) {
			large = l;
		} else {
			large = i;
		}
		if (r < heapSize && array[r] > array[large]) {
			large = r;
		}

		if (large != i) {
			int a = array[i];
			array[i] = array[large];
			array[large] = a;
			return maxHeapify(array, large, heapSize);
		}
		return array;
	}

通常の配列が最大ヒープとして生成されると言うにはどうすればよいですか?

次のコードを実行できます。

    /**
	 * 生成最大堆
	 * 
	 * @param array
	 * @return
	 */
	public static int[] buildMaxHerp(int[] array) {
		for (int i = array.length / 2 - 1; i >= 0; i--) {
			maxHeapify(array, i, array.length);
		}
		return array;
	}

ノードi、i + 1、n、nが各サイクル後の最大ヒープであることを保証できます。

  • これらのノードは最初は子ノードだったため、最初に明確に確立されました。
  • 各サイクルの後、iノードには最大ヒーププロパティがあり、変更後のノードの最大ヒーププロパティは変更されません。
  • ループが終了すると、配列全体が最大のヒープになります。

上記のアルゴリズムは線形時間で完了することができます。

ヒープソート

配列をO(n)時間で最大ヒープに変換できたので、それをソートしたいと思います。

最初のステップ:最大値、つまりルートノードを最大ヒープから移動し、配列の最後の要素と入れ替えます。このとき、n番目の行は配列の最大値であり、最初のn-1の数値は最大ヒープではありません。ルートノードが最大ヒープの性質を満たさない可能性があるためです。

2番目のステップ:以前のn-1の数値を最大ヒープとして維持します。1つのノードが満たされていないため、この操作はすべて線形時間で完了できます。

3番目の部分では、前のn-1の数値で構成される最大のヒープの最大値が、次に大きい配列の数値と交換されます。

上記の手順を繰り返して、配列を並べ替えます。

完全なコードは次のとおりです。

/**
 * @author xuyu 二叉树排序
 */
public class BinaryTree {
	public static void main(String[] args) {
//		ArrayUtil.printArray(buildMaxHerp(new int[] { 16, 4, 10, 14, 7, 9, 3, 2, 8, 1 }));
		int[] array = { 13, 3112, 1, 12, 3123, 35, 32, 89, 435, 7987, 2364176, 342, 4584, 234 };
		ArrayUtil.printArray(heapSort(array));
	}

	/**
	 * 堆排序
	 * 
	 * @return
	 */
	public static int[] heapSort(int[] array) {
		buildMaxHerp(array);
		for (int i = array.length - 1; i >= 1; i--) {
			int a = array[i];
			array[i] = array[0];
			array[0] = a;
			maxHeapify(array, 0, i);
		}
		return array;
	}

	/**
	 * 生成最大堆
	 * 
	 * @param array
	 * @return
	 */
	public static int[] buildMaxHerp(int[] array) {
		for (int i = array.length / 2 - 1; i >= 0; i--) {
			maxHeapify(array, i, array.length);
		}
		return array;
	}

	/**
	 * 如果i节点下是最大堆,将包括i的子树构建成最大堆
	 * 
	 * @param array
	 * @param i
	 * @param heapSize 二叉树的有效长度
	 * @return
	 */
	public static int[] maxHeapify(int[] array, int i, int heapSize) {
		int l = left(i);
		int r = right(i);
		int large;
		if (l < heapSize && array[l] > array[i]) {
			large = l;
		} else {
			large = i;
		}
		if (r < heapSize && array[r] > array[large]) {
			large = r;
		}

		if (large != i) {
			int a = array[i];
			array[i] = array[large];
			array[large] = a;
			return maxHeapify(array, large, heapSize);
		}
		return array;
	}

	/**
	 * 左孩子的下标
	 * 
	 * @param i
	 * @return
	 */
	public static int left(int i) {
		return 2 * i + 1;
	}

	/**
	 * 右孩子的下标
	 * 
	 * @param i
	 * @return
	 */
	public static int right(int i) {
		return 2 * i + 2;
	}

}
19件の元の記事を公開しました 賞賛されました8 訪問4041

おすすめ

転載: blog.csdn.net/u014068277/article/details/103002221