Heap Træer

 

Video: GetInsertParentNode

 

Simulation:HEAP

 

 

Heap træet er en speciel udgave af et binært træ. Den har et krav, at Parant note er mindre end de to Child notes. Heap bruges ofte til Prioritetskøer.

Der er to slags Heap træer, Min og Max. Min har altid det mindst element i root´en, mens Max har det største element i root´en.

 

 

 

Læg mærke til at lige meget hvilke node du kikker på (Min Heap) så er de noder nedenfor større. Træet kan bruges som Search Træ, fordi det ikke er sorteret, således at den værdi som er til højre er større end den vi har lige nu. Se hvordan node 3 (Min Heap) har 7 til højre og 36 til venstre, så det fungerer ikke som Search træ.

Insert

Hvordan indsætter vi så i Heap Træet? Fidusen er, at man altid indsætter fra venstre til højre lige som vi skriver i et dokument, og når man kommer helt til højre, starter vi en ny linje.

 

Nedenfor ser du et billede, hvor vi ligge har indsat værdien 5 i en ny node. Du kan se, at den sætte ved siden af 52, som var den sidste værdi som blev indsat. Hvis vi skulle indsætte en ny værdi efter 5, så vil den skulle indsættes til venstre under 12.

 

HeapifyUP går ud på at få træet til at funger igen således at den laveste/højest er oppe i toppen, og alle værder er større/mindre under den aktuelle. Prøv og kik på billedet hvor 5 lige er sat ind (rød). Du kan se, at 5 er mindre end den node som er lige ovenover (48), så disse skal byttes, og det er akkurat det som HeapifyUp gør. Og så kører den hele vejen op til ROOT. Derfor ender vi med at 5 rykker helt op til venstre for root, men ikke helt op til root, fordi root er mindre (3).

 


 

GetInsertParentNode

Hvordan finder man så næste position hvor man skal indsætte en ny værdi i. Se følgende billede og kode.

 

 

Før du indsætter den ny værdi, skal du lige finde den node som skal holde den ny værdi. Og når du har fået denne node, må du også spørge om der er plads til venstre, og er der ikke det indsætter du i højre.

Delete (ikke del af pensum)

Følgende billed viser hvordan der slettes i et Heap Træ. Når der slettes er det altid fra toppen. Og når så tager man den sidste node som blev sat ind og flytter den til root´en. Så skal man gøre det modsatte fra indsæt, nemlig bytte om, men nu ned til bladene.

Du ser også nedenfor at der er kode for denne HeapifyDown, som tager sig af bytningen fra root til et blad.


 

Koden for et Heap Træ

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

 

namespace HeapTræ

{

    class Program

    {

        static void Main(string[] args)

        {

            HeapTree træ = new HeapTree();

            træ.insertNewNode(4);

            træ.insertNewNode(8);

            træ.insertNewNode(3);

            træ.insertNewNode(9);

            træ.insertNewNode(2);

            træ.insertNewNode(66);

            træ.insertNewNode(1);

            træ.insertNewNode(21);

            træ.printTræ();

            træ.Delete();

            træ.printTræ();

        }

    }

    class HeapTree

    {

        Node root;

        Node lastNode;

        List<Node> insertListe = new List<Node>();

        public void insertNewNode(int data)

        {

            Console.WriteLine("--Ny node: " + data + " indsat");

            Node ny = new Node();

            ny.number = data;

            insertListe.Add(ny);

 

            if (lastNode == null)

            {

                root = ny;

                lastNode = ny;

            }

            else

            {

                Node aktuel = GetInsertParantNode();

                if (aktuel.left == null)

                {

                    aktuel.left = ny;

                    ny.parent = aktuel;

                    lastNode = ny;

                }

                else

                {

                    aktuel.right = ny;

                    ny.parent = aktuel;

                    lastNode = ny;

                }

            }

            HeapifyUp();

        }

        public Node GetInsertParantNode()

        {

            Node result = lastNode;

            while ((result != root) && (result.parent.left != result))

            {

                result = result.parent;

            }

            if (result != root)

            {

                if (result.parent.right == null)

                {

                    result = result.parent;

                }

                else

                {

                    result = result.parent.right;

                    while (result.left != null)

                    {

                        result = result.left;

                    }

                }

            }

            else

            {

                while (result.left != null)

                {

                    result = result.left;

                }

            }

            return result;

        }

        public void HeapifyUp()

        {

            int temp;

            Node next = lastNode;

            while ((next != root) && (next.number < next.parent.number))

            {

                temp = next.number;

                next.number = next.parent.number;

                next.parent.number = temp;

                next = next.parent;

            }

        }

 //Delete og HeapifyDown IKKE DEL AF PENSUM

        public int Delete()

        {

            int svar = root.number;

            Console.WriteLine("--Slettet node: " + svar + " ");

            root.number = lastNode.number;

            if(lastNode == lastNode.parent.left )

                lastNode.parent.left = null;

            else

                lastNode.parent.right = null;

         

            Node n = insertListe[insertListe.Count -2];

            insertListe.RemoveAt(insertListe.Count-1);

            lastNode = n;

           

            HeapifyDown();

            return svar;

        }

        public void HeapifyDown()

        {

            int temp;

            Node node = root;

            Node left = node.left;

            Node right = node.right;

            Node next;

            if ((left == null) && (right == null))

                next = null;

            else if (left == null)

                next = right;

            else if (right == null)

                next = left;

            else if ((left.number < right.number))

                next = left;

            else next = right;

            while ((next != null) && (next.number < node.number))

            {

                temp = node.number;

                node.number = next.number;

                next.number = temp;

                node = next;

                left = node.left;

                right = node.right;

                if (left == null && right == null)

                    next = null;

                else if (left == null)

                    next = right;

                else if (right == null)

                    next = left;

                else if (left.number < right.number)

                    next = left;

                else next = right;

            }

        }

 

        public void printTræ()

        {

            Console.WriteLine("-----------Print Start ----------------");

            root.printMig(0);

            Console.WriteLine("---------------------------------------");

        }

    }

    class Node

    {

        public Node parent;

        public Node left;

        public Node right;

        public int number;

 

        public void printMig(int tal)

        {

            tal++;

            String s = "-";

            String samlet = "";

            for (int i = 0; i < tal; i++)

            {

                samlet = samlet + s;

            }

            if (left != null)

                left.printMig(tal);

            Console.WriteLine(samlet + number);

 

            if (right != null)

                right.printMig(tal);

        }

    }

}

 

 

 

 

Fagudtryk(Heap-Træ)

Heap

Heap er en speciel udgave af et træ. Den har en krav, at Parant note er mindre end de to Child notes. Heap bruges ofte til Prioritetskøer.

 

Træet kan ikke bruges som Search Træ, fordi det ikke er sorteret.  Se hvordan node 3 (Min Heap) har 7 til højre og 36 til venstre, så det fungerer ikke som Search træ.

Min Heap

Hvor Parant er mindre end Child note. Læg mærke til at lige meget hvilke node du kikker på (Min Heap) så er de noder nedenfor større.

Min-heap.png

Max Heap

Hvor Parant er større end Child note.https://lh5.googleusercontent.com/D8JriUXLB0iRkSmvRjkhSOH6_Sq4elkQeeFl4L_icwyWGscd_cXUyBHlx3Zyn7i3pa6KqwzB07EVNijjuZoc5DGjdqOnNV8CRKzpX2xaJw-za7VjU3c