[Datenstruktur – Handsortieralgorithmus Teil 4] Heap-Sortierung, ein Artikel führt Sie zum Verständnis der Heap-Sortierung

Inhaltsverzeichnis

1. Heap-Anwendung – Heap-Sortierung

1.1 Analyse der Idee der Heap-Sortierung

2. Erstellen Sie einen Haufen

2.1 Heap-Aufbau nach oben anpassen: O(N*logN)

2.1.1 Passen Sie den Code nach oben an

2.1.2 Anpassung der Haldenbauordnung nach oben

2.2 Heap nach unten anpassen: O(N)

2.2.1 Passen Sie den Code nach unten an

2.2.2 Passen Sie die Heap-Bauvorschriften nach unten an

3. Implementierungscode für die Heap-Sortierung

4. Heap-Sortierungstest


1. Heap-Anwendung – Heap-Sortierung

Der Heap ist ein vollständiger Binärbaum, und der vollständige Binärbaum verwendet Arrays, um Daten optimal zu speichern.

Bei der Heap-Sortierung wird die Idee des Heap-Sortierens verwendet. Sie ist in zwei Schritte unterteilt:
1. Erstellen Sie einen Heap

Aufsteigende Reihenfolge: Bauen Sie einen großen Stapel auf

Absteigende Reihenfolge: Erstellen Sie einen kleinen Haufen

2. Verwenden Sie zum Sortieren die Idee des Heap-Löschens

Die Abwärtsanpassung wird sowohl beim Heap-Aufbau als auch beim Heap-Löschen verwendet, sodass die Heap-Sortierung durch Beherrschung der Abwärtsanpassung abgeschlossen werden kann.

1.1 Analyse der Idee der Heap-Sortierung

In diesem Artikel verwenden wir zur Erläuterung einen kleinen Heap, und die Sortierung des kleinen Heaps erfolgt in absteigender Reihenfolge.

Studenten, die nicht viel über Heap wissen, können einen Blick auf den Artikel über Heap werfen: Klicken Sie hier, um zu springen

1. Wir passen zunächst die Elemente im Array nach unten an, um einen kleinen Heap zu bilden.

2. Das oberste Element des kleinen Heaps muss das kleinste im Array sein, daher tauschen wir das oberste Element (das erste Element des Arrays) durch das letzte Element des Arrays aus und betrachten das fehlende Element am Ende des Arrays als Element im Array (size-- ) , Dann beginnen Sie am oberen Rand des Heaps und passen Sie ihn nach unten an, um den kleinen Heap neu aufzubauen, und wiederholen Sie ihn kontinuierlich, um eine absteigende Sortierung zu erreichen (aufsteigende Reihenfolge kann durch Ändern des kleinen Heaps in a erreicht werden). großer Haufen).

2. Erstellen Sie einen Haufen

Wir können eine Aufwärtsanpassung verwenden, um Heaps zu erstellen, oder eine Abwärtsanpassung, um Heaps zu erstellen. Wie sollten wir wählen?

Dann muss ich denjenigen auswählen, der die geringste Zeitkomplexität hat. Als nächstes analysieren wir die Zeitkomplexität der beiden Heaps:

2.1 Heap-Aufbau nach oben anpassen: O(N*logN)

2.1.1 Passen Sie den Code nach oben an

void AdjustUp(HPDataType* a, int child)
{
	int parent = (child - 1) / 2;
	while (child > 0)
	{
		if (a[child] < a[parent])//这里控制大小堆
		{
			Swap(&a[child], &a[parent]);

			child = parent;
			parent = (child - 1) / 2;
		}
		else
		{
			break;
		}
	}
}

2.1.2 Anpassung der Haldenbauordnung nach oben

//建堆 -- 向上调整,时间复杂度:O(N*log(N))
for (int i = 0; i < size; i++)
{
	AdjustUp(a, i);
}

Lassen Sie uns ein Bild zeichnen, um die zeitliche Komplexität des Heap-Aufbaus mit Aufwärtsanpassung zu analysieren:

Der Heap ist ein vollständiger Binärbaum, und der vollständige Binärbaum ist auch ein vollständiger Binärbaum. Daher nehmen wir den vollständigen Binärbaum als Beispiel, um daraus abzuleiten, dass die zeitliche Komplexität der Aufwärtsanpassung und des Aufbaus des Heaps O(N*logN) beträgt ).

2.2 Heap nach unten anpassen: O(N)

2.2.1 Passen Sie den Code nach unten an

void AdjustDown(HPDataType* a, int size, int parent)
{
	int child = parent * 2 + 1;
	while (child < size)//当child大于了数组大小就跳出循环
	{
		//找出左右孩子中小/大的那个(假设法)
		if (child + 1 < size && a[child + 1] < a[child])
		{
			child++;
		}

		if (a[child] < a[parent])
		{
			Swap(&a[parent], &a[child]);

			parent = child;
			child = parent * 2 + 1;
		}
		else
		{
			break;
		}
	}
}

2.2.2 Passen Sie die Heap-Bauvorschriften nach unten an

for (int i = (size - 1 - 1) / 2; i >= 0; i--)
{
    AdjustDown(a, size, i);
}

Lassen Sie uns ein Bild zeichnen, um die zeitliche Komplexität des Heap-Aufbaus nach unten zu analysieren:

Komplexität der Heap-Erstellung nach unten: O(N).

Nach einer solchen Analyse können wir wissen, dass die beste Wahl darin besteht, den positiven Stapel nach unten anzupassen.

3. Implementierungscode für die Heap-Sortierung

//堆排序时间复杂度O(N + N*logN)
void HeapSort(int* a, int size)
{
	//升序 -- 建大堆
	//降序 -- 建小堆

	//建堆 -- 向上调整,时间复杂度:O(N*log(N))
	//for (int i = 0; i < size; i++)
	//{
	//	AdjustUp(a, i);
	//}

	//建堆 -- 向下调整,时间复杂度:O(N)
	//倒着调整
	//叶子节点不需要处理
	//倒数第一个非叶子节点:最后一个节点的父亲开始调整
	for (int i = (size - 1 - 1) / 2; i >= 0; i--)
	{
		AdjustDown(a, size, i);
	}

	//O(N*log(N))
	int end = size - 1;
	while (end)
	{
		//1.先交换
		Swap(&a[0], &a[end]);
		//2.再调整,选出当前大小的数组中最小数
		AdjustDown(a, end, 0);

		end--;
	}
}

4. Heap-Sortierungstest

Wir haben einen kleinen Haufen erstellt, sodass die letzte Zeile in absteigender Reihenfolge angezeigt wird.

*** Ende des Artikels ***

Ich denke du magst

Origin blog.csdn.net/Ljy_cx_21_4_3/article/details/131065900
Empfohlen
Rangfolge