LongCut logo

A&DS S01E02. Data structures. Binary Heap. Heap sort

By Pavel Mavrin

Summary

Topics Covered

  • Operations Define Data Structures
  • Array Heap Attempts Fail Logarithmically
  • Array Stores Complete Binary Heap
  • Sift Up Ensures Heap Property
  • Build Heap Bottom-Up Linear Time

Full Transcript

[Music] so this is the second lecture of our course today we will talk about data structures so our course is about

algorithm and data structures last time we talked about algorithms today we'll

talk about data structures so what is the data structure data structure

and according to its name data structure is some structure that contains some data so we have some i don't know something like this some some structure

something i don't know something like that and this structure contains some good data ah this structure may be very different

from the from one little structure genetic structure so they all are very different and uh what is the common thing that is um structured and it contains some data why do you need some structure for your

data why can't you just get all your data and put it in some big array but create a big array and just just encode your data in some form

and just put it in the beginning why you may need some structure uh that's basically because you want to access your data

so you want to perform some operations say operations for example if you want to build some database you may want to

uh to find some element in the database by your request or if you create some i don't know some application and you want to show

to your user some statistics like show me the average income for the last year so you you want you want to be able to get this statistics first so you want to

just look in your data structure and find these statistics so these operations may be very different and actually these operations define what data structure do you need

so before you uh want to choose what data structure do you need in your algorithm you want to decide which operations do you need so first you need decide what operations do you need

then you decide what data structure do you need no not not opposite and all data structures are like split in divided in some classes

and each class is specified by the operations uh that are possible to make in the data structures of this class for example let's say let's say very

simple let's say array array is a very simple data structure it's not exactly the structure but let's say it's a data structure right

and what operations can you do in array now in array you can like put element in some by index you have index i

you can put element by the index and you can get element by index let's say get element by index i and put element

z by uv so this iteration is simply return i this operation is

a i equal to so let's it's very simple data structure it's actually not exactly the structure it's more like a primitive but

good enough now when you want to create a data structure you specify the operations you need in your data structure and when you analyze

your data structure you want to analyze the time complexity of each operation so for each operation separately we will calculate the time complexity for

example in this case we have two operations gate element and put element and each operation actually is performed in constant time

so for both the separation the time complexity is big of one that's all that's the first data structure we show now data structures and algorithms are

strongly uh related to each other because when you create a data structure you want to make operations and when you make a operation you use some algorithm to make this first

operation and when you design the algorithm you may use some data structure just to make your algorithm faster so after this structure we will

uh learn them in parallel in because uh very closely related to each other good and today we will learn our first

data structure our first stretch will be binary heap

so what is a binary heap so hips ah let's say heat or sometimes it's called it's how it's called

[Music]

it has a second name is so heaps of priority queues are the

class of data structures that can perform the phone operations uh so it contains some set of elements

and you can do two operations sometimes three or four but today we'll learn only two operations just for simplicity sometimes you can make some additional

operations uh we'll learn two operations first operation is insert an element and the second operation will be remove

the minimal element from the hip so remove minimal element a minimal element means that you can compare two elements

so you have some comparator that can compare two elements and there is always one element which is minimal in this set okay so i want to make these two operations

any questions by now oh good now first before we learn how to make a right binary heap we will learn how to make uh like simple data structures which can

do these two operations uh first attempt will be to use the simple array so first attempt

let's use just a simple array uh and say let's say that this array is big enough so we always have enough room to to put all elements

of our set in this array uh so we use first let's see first first ln elements of this array took to

contain this elements of the set so these first n elements from 0 to n minus 1 contain the elements of this set now let's just implement these two operations so first operation is in

inserting elements so we need to insert a new element into our array uh easiest way to do this is just insert it in the last position so we will get this element x put it into the in

the last position here and increment the size of a ratio we'll say insert x like this

and put it into position m and then increment the size for it cool now the second operation second question we need to remove the minimal element remove the minimal element from array we

need to find this minimal element first so how to find the minimal element in the radius i hope you know how to do it so to find the minimal element let's just iterate or all

elements and find the minimal one so let's say let's say j is the index of the minimal element so first j equal to zero then we iterate on all elements from one

to n minus one and see if this element is less than this element

then update the memory okay it looks fine so now we found the the minimal element in

the array so let's say it's somewhere here just somewhere here is the minimal element of the ring now we need to remove this element from

the right and when we remove this element there will be a hole here so so we want always uh to keep all elements close to each other so if we just remove this element

a little bit empty space here uh to fill this empty space we can for example swap this element with the last one so we

will smoke element j with the last element of the array and then remove the last element from the array let's say swap

a j of a n minus one

and then just remove the last element

let's see um and then return

looks fine so we found that first the minimal element then swap the minimal element the last element now the minimum last element is the minimal one

so we decrease n and return this last removed element good you can see something from time to time just to keep it live okay

so this is the first simple implementation of the by of the hip data structure so it is a correct hip data structure we can insert elements we can remove the minimal element

now let's calculate the time complexity of this data structure uh in this structure time complexity is different for these operations

so this operation costs your constant time why we return a n because we decrease that so let me show let me show here so we had

array a here we have element j and we had elements from zero to n minus one so this was the nimal element now we swapped this element with the

last one so we saw these two elements so now we have elements from zero to n minus one

and this is an email element we decrease n so we have this array and minimal element is here so in the end we want to return this

minimal element so minimal element has index n no no no it is this this need to be between spamming in the chat and be

quiet too much so so just don't spam but not to be very quiet there's not so many of you so

i hope it will be fine cool now what is time complexity of this separation in this in this operation you need uh to

make this side this for loop and this for loop it's erased over all elements of the array so the time complexity of this part of the desperation is linear so the

total time complexity of this operation will be bigger so this is the example of uh data

structure when you have two operations and they have different complexity so this this operation have some complexity because one and the inspiration have time connects to be called n sometimes it happens

okay let's try another one so if if we want to perform this separation first so if we want to remove the minimal element uh faster than just in linear time

what can we do ah for example we can maintain this sorted order in our array so if you keep the array sorted then it's easier to find the minimal element because

minimal element will be always in the end of the ring

let's try so second attempt will be to have not just array but the circuitry

cool so if we want to be able to remove the minimum uh it's better to to have sorted array in descending order

so we will have array a sorted in by in decreasing order so the minimum element will be the last one

from zero to n minus one minimal element will be always here now it's easier to make this remove mean because we can just skip

this part minimal element is always in the end so we just decrease m and return

uh huh now when i decrease no the minimal element

has index n minus 1 so after i decrease n the minimum element will have index m i have indices from 0 to n minus 1 so it

was n minus 1 then i decrease n now it is index m good so we can easily remove the minimal element from the

heap and now we need to be able to insert an element and this is complicated because we need to keep the array sorted so when we add element x here

we need to put it in the correct position so we need to put it in such position that the ray remains sorted ah let's say easiest way to do it is like

like we did in the previous lecture like when we had insertion sort we'll put it here and then we'll move it to the left until it reaches the correct position

let's say so we put it in the last position and then move it to the left so let's say i equal to m minus 1 so i is the index of

element x and now while i is greater than 0 and ah it is

it is greater than the previous element i just swapped them and decrease i again this procedure is the same as we used in previous lecture lecture when we had

insertion server we put the new element and then move it to the left until we have element this is greater than this element so after this after this while this

array will remain sorted good so what is time complexity here the time complexity of remove mean is obviously constant

but now the time complexion of this insertion is is is big because here you need to make this while and

the time complexion of this while is again linear so at least time complexity

okay now we have two options we can make fast insertion but slow remove or we can make fast remove but slow insertion

uh in the in real algorithm you can choose between these two structures but actually they are both pretty slow because in in real algorithm you

you have a big number of insertions and big number of removal so the total time complexity of the algorithm if you use this data crusher will be slow uh so now we will implement the third

version now the correct version correct binary heap uh and in the correct binary heap will have both these 10 complexities less than big o of n

and actually the time complexes here will be big o of logarithmic show it here so we have two versions let's see that

we have insert and remove first version uh this one we have insertion in constant time this second version is end here and one here

and now we'll make the correct binder here incorrect binary heap we have both the separation work and locally in logarithmic so we have a version this spoiler will

we will discuss it now so both this operation will have logan time uh it's hard to compare to data structures so for example if you compare these today

structures so this operation is faster but this operation is slower that's usually what happens when you compare to this structure but when you decide what the structure you can use in your algorithm

you need to calculate the number of operations you need to accept if you want to make an operation let's say let's say we have some data some algorithm and we need to perform

like n insertions and removals that what we will will be the time complexity

so in in these two in this case we have n insertions it cost you end time and then you have n removals each cost you end time so total tank of this will be n plus n square

and here you have n insertions so we have n square here plus m and here we have n log n plus n log n and now you see that this data structure is better than this of this function

because here we have n log n time complexes here and here we have n squared and complexity so if you have this number of operations you can compare in and see which data structure is

better usually you have like situation like this so this is the common situation usually you have uh about equal number of insertions and removals so the that's usually what happens so

usually this date rush is better than these two because when you insert the element in the hip you usually you need to remove it at some point so usually you have the same number of

insertions and removals okay no questions by now okay let's go

so now we'll discuss the binary heap

the binary heap looks like like this you have a binary tree

that's enough you have a binary tree what is a binary tree it is the set of nodes so each node have

at most two children nodes so we have one child is left child and another child is right child and this binary tree for for the for the binary heap will always look like this it will be

almost complete so all layers of the binary tree will be full except maybe the last layer in the last layer

you have some elements from the left but maybe not all elements to the right just because you don't have enough elements so for example if you have one

two three four seven if you have ten elements in your hip the binary 3 will always look like this so the structure of binary 3 is fixed by

this number n if you have 10 elements you will always have binary 3 like this now each node of these three contain one element of the set so you have ten elements in the set you

have these three and each node contains one element it did may be hard if you don't know how to program problems

so if you are new to programming maybe first thing you need to do is to learn some programming language and just learn how to how to get the simple algorithms like and let's learn

how to solve some simple problems go so now each node of the tree should contain one element of the set and we want to be able to find the

minimum so to be able to find the minimum we will keep this tree in some

almost sorted order um uh this is called the hip uh property so the property of the heap is that each element

is less or equal than it is children elements so these elements are less than this element and this element and this element and this one and this is which programming language should they

begin with it's this doesn't matter actually you can choose any programming language and just start learning this it's more than enough information in the internet how to learn programming

languages go so now we want to put our elements in this tree so that for each pair of nodes

these elements will be less or equal than this one for example let's put some elements here let's say we have 2 5

10 i don't know 7 9 uh 13

8 26 and 15 here and 19 here

so this is the correct binary heap we have all 10 elements in this nodes of the binary team and for each node it is greater or equal

than the parent node nice okay now how can we store this element in our programming language

there are different ways to store the binary tree in the programming language usually when you have binary three you have something like this you have like class note and you have

like pointers to the left child and the right child so have some some some complicated data structure but

in our case uh this structure of the tree is fixed so the tree of size 10 is always look like this so we don't need to just remember which element

is the sum of which element because we always have this three looks like this so instead of having some complicated structure of nodes we will just

uh enumerate all the nodes in right order so we'll enumerate all the nodes from top to bottom from left to right so this node will have index 0 1

2 three four five six seven eight and nine and now we'll just simply create an array of size 10

and put these elements in in this array

are using these indices so let's have this array and we have

elements 2 5 10.

7 30 15 90

9 6 nine and ten switch well it doesn't matter so we only need

uh the the relation between element and its parent so these two elements have no relation so they they must may be in

in any order and like any other so this element in this element made going different over and so on so we only need to maintain the relation between the element and its

parent sorry okay now to uh start saying this three in in the programming language

we'll have this one array uh let's call it array h

from the heap and to access the element of the tree we just get its index so for example we need we want to access this element

it has index 4 so we go into this array find the fourth element with this element linux form we just take this index go into into to array find the element

of this index and this is the element of this node good now we will need two traverse listings so we need to move to the parent or move to the child nodes

so how can we move uh around the three using this array that's quite simple so for example if we stay in some nodes so we stay in

some node i and we want to move to the left child of this node to this node ah we don't have the link so we don't

have the pointer from this node to this node so instead of having pointers we just calculate the index of this node if we stay in node i the index of the left child will

always be equal to 2 i plus 1.

and the index of the right child will always be equal to 2 to i plus 2.

you can prove it using mathematical induction i will not do it but if you if you want just for for the exercise you you can try to just to prove it that for any node i

the left child always have index to l plus one and the right shell will always have index to i plus two uh this is true because the three is complete because all layers of the three are complete from from left to right so you have two

in power of i elements on the layer i so so this one

for example if you stay in note let's say let's say you'll stay in note one so you stay you're staying here this is life and you want to move from this node to

this node so you only know the index of the node so you know the index is one so you stay here and you want to move to the left note of this

element so you calculate 2 i plus 1 it will be 2 multiplied by 1 plus 1 it will be free so you know that the index of the left child is 3 so you move from this node

to this node and this node will be the left child of this node good and sometimes we want to move to the parent node

so let's see what is the index of the parent node of the node i basically if it is the left node we need to calculate i minus 1 divided by 2 and if it is

right node it is i minus 2 divided by 2.

it can be simplified like this we'll say that the index of the parent is i minus 1 divided by 2 and round it down

so if this even then we'll have uh around down to 2i if if it is odd again we'll have i minus 2 divided by 2 will be equal to i

so from here you you will have i plus 0.5 so it will round down to i from here you will have i so it will be rounded down to i so this is the correct formula for both

cases okay any more questions by now don't see any questions okay i think that's all preparations now we now now we're ready to make operations

first let's learn how to insert elements so when we need to insert new element in the binary heap

let's see you you insert some new element uh it's floor so so it's rounded down

cool so let's say you want to insert new elements in the binary heap let's say you insert new like elements let's see insert four so we want we want to insert new element

four in in binary heap so what is what is the easiest place to insert a new node in the binary tree to insert new element in the binary tree

the easiest way to do is insert it here so we'll create a new node in the last layer which is not full

in the leftmost position we'll sort it here so it has index tab now we have a good binary tree so again we have

all layers full except the last layer last layer have some full elements from left and some empty elements to the right and now we just need to maintain this property because

this property that each element is greater or equal transparent is broken here so for this element we have element which is less

than than its current so here is the problem and we need to fix it let me just write the code here so let's see we have insert

x so first we put element in the last position uh last position has index n so again we'll say h and equal to x

and plus plus h this is m this is h this is h this is now we put this element here and now we

need to fix this broken property because for this two elements we have lower elements less than than experiment

how can we fix this property very easily we just will swap these two elements and we so we if we swap these two elements when we move

these 13 down move four up now what happens this property is satisfied because we have a big element here now

we have smaller element here so this property is still satisfied this property now satisfied because we moved the smaller element

up so this property now is satisfied here so now the only broken property may be in this node so for these two nodes we may have the

broken property of the heap so now we have this element less than the sum so this is the only place in the hip where we can

have a problem all other edges are satisfied cool now again we need to fix the property for these two elements again we'll just

swap these two elements so 5 goes down

this 4 goes up now we have this property satisfied this property is identified the only property that may break is for

these two nodes so this is the only place we have a broken property we check the property for these two nodes see that this node is greater equal than its parent so here

satisfied here is just five here this file so for all nodes the property is satisfied so we have the correct binary heap that's all that's how you insert new node in the binary heap you insert in

the last in in the last layer and then move it up until you have the satisfied property for this element in its parent so let's just write the code ah let's

say let's say again i is the index of the element x so first to import n increase n i equal to n minus one so

now i is the position of the element x of the new added element in environment here and now we just move it up so while while we can move it up we can move it

up if it is not the first element so if i is greater than zero and it is less than the its parent

less than its firm and parent have index i minus y power if it is less than apparent then we swap

these two elements so a i and a pi minus one

and continue to the new position y equal to i minus one

yeah that's all let's insert let's insert another element so let's insert another element for example insert two we only have element two well you you might have equal elements

that's not a big problem let's insert one more length uh let's insert one more element so new element must be the next element in the last layer so next element will

be the left l left child of this 15 so we insert new element here it will be the left child of now that's

not enough room here so let's uh just move to left 26 let's insert more element here so we

insert new element like 2 here now look on this property it's broken so we

swap these two elements move 15 down move two up now we say i

so i was here now we swap element i and element i i minus 1 over 2. swap

these two elements and say i equal to i minus 1 so i moved here now again we compare element i and its

parent this element is less than parent element

so again we swap these two elements and is here two is here and move i to the parent so i now is here

and now again we compare element i that this parent see it is greater or equal because they are equal so this property is satisfied everything is satisfied so it's fine

now again we have the correct binary heap so for for any element we see that it is greater equal than its parent element so we have a correct binary heap

that's all now let's calculate time complexity of this algorithm so what is the complexity time complexity will be equal to the number of

uh iterations of this while so we need to complete the number of iterations here here on on every iteration we move to the next layer of the tree

so we start on the bottom layer of the tree and then each time we move to the next layer of the tree the number of layers of this tree will be equal to logarithm of n

so we have at most logarithm of n number of iterations here so total time complexity of this function will be big o of logan as expected

cool so that's how we insert new element in binary heap in logarithmic time and now we need to learn how to remove elements let me check if you have any

questions now i don't see any questions good now let's see how remove elements from the binary here

first again we need to remove the minimal element from the binary heap how to find the minimal element of the binary heap that's quite easy because for each

element we know it is less wrinkle than its children so the minimal element of the binary heap must be in the root so minimal element is always here so we don't need to spend any more

additional time to find the minimal element we always know that minimal element is in the root of the tree and root of the tree have position zero in the array

so just this first element of the ray will always contain the minimal element of the binary heat good so now we located the minimal element it was easy

now we need to remove this minimal element and that's little bit more complicated if you just remove the root element from the tree the tree will break into two parts it

will have left subtree right subtree and we need somehow combine these two suppressing one big tree that's not as if they think so instead of just removing this node tree so we just we

need to remove this node so let's remove this when you remove the road node you have two independent subtrees let's open the right subtree and to combine in the one big three we'll do the phone we'll take the last

element of the tree this is 15 and put this 15 as new root of the tree just remove it from here and move

so this is new element uh we just remove everything unnecessary just move everything just to keep the picture

simple so we removed the minimal element it was in the root of the tree and replace it with last element we take this last element from the bottom layer

and put it in the place where the roof was good now we have the correct binary tree so we have again we have all layers filled

except the last layer and so on and now instead the only problem we have that that we have this property of the hip is not satisfied uh it is not satisfied with these two

nodes so here we have less and here we have less so these two nodes are broken so here

for these two nodes we have elements which is less than the parent element

good so how can we fix this property to fix the property for both these nodes at the same time we'll do the following we'll take one of the children actually the minimum

of the children so we will look on both children see which child is minimal and swap this route with the minimum of the children

so this two is less than four so we swap this 15 of these two so 15 goes here two goes and 15 goes here so again we had two children one was

four another was two and we need to satisfy these two notes at the same time to do this we take the minimum of two children and swap our element with this

meme okay now these two properties are satisfied so here we have a lesser equal here we have a lesson

and now we may have these two properties broken so so now we have for example this property work on

this properties now we have zero columns no matter which element we put these new

roots along the both of the right sides yes but yes it does not matter which element moves to the root but it's easier to move the last element because when you remove the last element you

have the correct binary tree so if if you move element from from the middle of the tree you have hole here so the it will be not correct binary tree so the easiest way to remove element

from the tree so keep it uh the correct balance binary three like we want we want all layers to be filled except the last layer so this element is just easier to remove you you can move any element to the root

but if you remove like this element you have hold here and we don't want to have any empty spaces in our binocular

yeah but we can take any element and put it in the in the root and now now we have problem here we have this element less than this element so again if we have problem like this we

just swap these two elements like we did before so big

fingers here these temples so now this is satisfied this is satisfied so we have the correct binder here

space in this part so i need to erase this hope you don't have any questions

hope your daughter hears that so i i

will just erase this awesome

go so let's write the code i need to remove the minimal elements uh first again we we take the root

elements remove it and replace the last element how can we do it let's just simply swap these two elements just yeah let's just swap these two

elements like first element and the last element it was not a it was h

let us swap the first element of the last element and now remove the last one okay now we have this last element in the root of the tree and we just move it down

that's a little bit more complicated than before because uh in the previous operation when when the third element we on this we only swapped the parent and we have only one parent

when we look on the children we may have zero children we might have one child we have two children so the quote will be a little bit more complicated but

i'll try to make it as simple as possible uh let's see so i is the index of the new element so again like before i is the index of the broken element so this broken

element may have incorrect property for these two children notes let's see so each time

we will find the minimal of these two children and try to swap this minimal minimal challenge we will build sorting algorithm but later we are talking about binary tips

right now we will create a sort algorithm let's go so we will look on both

children let's say well let's just see well two

now um let's see what why i have it most at least one chair so let's move element down until i reach the bottom layer so

when i have at most at at least one child uh uh uh when so if i have left child left childhood in this two i plus one

so while two i plus 1 is less than n so it means i have at most one chapter

at least now we need to take minimum of these two children um let's say j is the is the minimum so say

j equal to uh 2i plus one if the right child is less than left child

so if if i have the right child so if two i plus two is less than m

and this child is less than this child and not a but h h 2 i plus 2 is

less than h okay then it does change so now j is the index of the minimum of the child two children so okay this shall tell

this also now let's see if uh this if this minimum is greater than the element i it means that both children are greater

or equal than the element i it means that this both properties are satisfied so if h j is greater or equal than h i

it means that both children are correct so we just can return here let's break here we can just break from this cycle and

now if it is less then we make the swap and make scope

h h g and say looks fine

yeah yeah this lecture is full of jokes about parents and child and children yeah um cool

i think that's fine so sorry again we find meaning of these two children so we have we take the left child if we have right child and right child is less than left child

then j equal to right child now j is the index of the minimal child we just see if if it is correct we break if it is not correct we swap with the minimal channel and then

move to the middle chart looks fine now in the end we need to return the this removes minimal elements so in the end we just return

h whoo looks fine uh while the while two because we need to make this while only until we reach the bottom layer so if

2i plus 1 greater or equal to m it means the left child is outside of the tree so we don't have the left child if we don't have left child we don't have the right child because

right child have bigger bigger index so it means we have at least one child here if we don't have any children then all properties are satisfied because property is only broken when we

have element i and its children

yes it is the index of the left child if the left child is less than n it means

left child exists uh now we already discussed this that this three represent the memory like in

the big ray so we have index of each element from here and so on

and we just put these elements using these indices in array h we have this array h contain all these elements uh using this indices

you don't use linked lists here so that link list is nothing in linked list you can't access element by its index in one operation so we use like normal

normal arrays instead of not any lists or something but just let's just erase okay now let's calculate time complexity time complexity here will

also be logarithmic because again each on each iteration of this cycle we move one to the next layer of the tree we have at most logarithmic number of

layers so the total time complexity here also will be again oh that's basically all now we have both operations we can insert elements in logarithmic time and we can remove minimal elements in algorithmic

cool cool now now what we will do we will use this binary heap to create a sorting algorithm

like i said in the beginning lecture you can use data structure to make some fast algorithms and now we'll make the sourcing algorithm using this data structure

let's so this sorting algorithm is just called hip sort because you sort

array using heap um let's see let's see you have

a function sort which takes away so how can you sort array using binary heap actually very easily you take all elements of your array

insert them in into the heap and then return remove elements from the hip wide one by one so first you will remove the minimal element then you remove the second minimal

element and so on so you remove the elements of the array in increasing order so we'll just put all

elements in the binary here and then remove all elements from the binary heap [Music]

that's all so so when when you have the correct data structure some algorithms may be very simple just add all elements and remove all elements

and in the end you have the sorted array nice what is the time complexity of this sorting algorithm now it's quite easy to complete so each

operation costs you log on time we have any direction here an operation here so we have total two end operations each operation costs you log in time so total time complexity

will be illuminated so time complexity is the same as in the merchant operating we discussed in the previous lecture my questions now let's make some improvements so this

is the correct sorting algorithm we can we can use it now let's try to improve it a little bit uh the improvement will be the following so let's try

now if we implement it like this we need to have two arrays so imagine we have some array yes you can do the same using binary search tree yes that's correct but

binary search three is a little bit more complicated than structure we'll discuss it in the next semester but yes you can do the same using any binary search tree yeah

um now uh what kind what what's happening we have array a

and we need another array h so if you want to sort the array of size n you need to create another area size n just to put all

to use it as binary heap now you take all elements of your array move them to the binary heap and when you move all elements by the hip you need to move them back to array

a so you need to create another array of the same size that may be too much because sometimes you have not enough memory because something if your array is big

and feels almost all your memory you don't want to create another array so how can we do heap sort without creating a new array of the same size

let's see what what's happening so we have array a now i still need it ah so what's happening you have array a you move from left to right and take

elements from array a and insert them into array h so you already inserted this element into ray h and now you have only these elements

remaining in array h you have this only only this part of our edge is filled so the number of elements in array h is the same as the number of elements you removed from

array a so here you have this so that's what happened so you take one element from array a insert it into ray h using binary heap

algorithm now take this next element move it here and so on

now what will how can we improve it let's see we use only this part of ray a and only this part of ray h now let's combine these two parts in the

ones in in this the same array so instead of having two arrays we will have only one array the same array we take for the source so we take this

array a and use its left part as a binary heap so we'll split it into two parts here we'll have binary heap

and here we'll have the rest of the ray so now on each iteration what happens you need to take the next element from array a and insert into binary heap

so how to insert new elements a binary hip you put it in in the last position of the binary heap and then move it up to the three it's called sift up operation so when you have the element in the

bottom layer and then move it up using the insertion insertion procedure the separation calls sift up in the binder key and this this progression called shift down in the

binder here so when you add this new element in the binary heap you add it in the last position in the last layer of the binary heap

and then shift it up to the root uh so how how can if we use the single array we just look on this element we need to put in this position of rate h but it's already in the correct position

so we just take this element from this position here uh imagine it is now in the binary here so we just increase the size of a binary

heap to here and sift it up to the root of the binary chain all so in the end

you will have the whole array a as as the array of the binary heap

so we'll go from left to right then take each element and shift it up to the root point of the binary here shift sift up is again a sift up is this this part of the

insert operation when you have while and move element up to the root now in the end you will have the whole array be the array of the binary heap

uh and now you need to remove elements so when you remove the element from the binary what happens let's show it in dynamic so so first you have array a

now you add elements one by one so you have heap here and each time you add one more element to the binary pencil so in the end you will have whole array

equal to binary so whole element whole array is a binary heap and now you remove elements from the binary heap so each time you remove element

and put it in the end of the array so first you remove the first element i put in the last position then you remove the next element put it here remove the next element and so on so you

remove elements in increasing order so this element will be put here in some decreasing also something like this again this is the first elementary move

this is second elementary movement so so in the end you will have the array sorted in decreasing order uh then you can just reverse the array

or you can modify your binary heap to remove not the minimal element but the maximal element if you want to sort array in increasing order you can just remove not the minimal element but the maximal element

now let's go so what we do we just go from right to left two zero and say that a i equal to remove me right i i don't know

you see i want to use only this part of them is this the sieve down precision so i'll just swap this element to the last element so i

take this element slope of this element this is the minimal element i swap them and then sift down this element

um that's all that's how you make the heap sort without creating this additional ray so you only use the array that is giving you

a as array a so you take this array a make this rate a array of the binary heap and then remove these elements from the binary heaps and put them in the same

array to create a sort oh that's

basically all any more questions by now okay nice um

yes but it may be a little bit more complicated a little bit too complicated if it's the first algorithm you learn but i think it's quite clear so

now uh the final thing i want to discuss is how to create a binary heap inc in

linear time so now

and now oh

let's change let's let's try try one more time

okay take two so what i want to do i want to improve this part of the algorithm i want to create the binary heap from the given elements in linear time

uh what happens now now we add elements to the binary heap one by one so first we add this root element when we add these two elements and these four elements and so on how much time does it take to add

element it depends on the height of the tree so this first element we can add in one iteration so we just add this element and we don't seat it up because it is the root of the tree

so we spend like zero time to sift this element now for these two elements we may want to sift it up to the root so for each of this element we spend one

operation to sift it up to the root now for these elements we spend two operations for these elements with specific preparations and so on so if we have more layers

in the last layer we spend logan operations to sift it up to the root so the total time complexity will be

something like this it will be the sum uh for all layers let's say we have k is the number of the layer uh from zero to logan

and for layer k we have two in power key elements and for each element we need to spend k operations to sift it

this sum is big why the sum is big because uh basically because on the bottom layer of the tree we have

big number of nodes and for each node we need to spend log n operations to shift it up so in the worst case we have all elements all small elements in the bottom of the string

and we need like to sift all these elements in the bottom layer to the root one by one so each this shift up operation goes to log n time and half n

over two elements in the bottom layer so this this is this is only your handlebar how can we improve this part this one simple uh we will try to move elements not up to

the tree but down so instead of shift up operation we'll use sieve down operation how can we go from bottom to top and each time we have some something

like this so so this bottom part is correct so here we have all properties are satisfied now we take the next element

take the next element and try to satisfy these two properties to do this we make this same operation as when we remove the minimal element so we make the sieve down operation we just seep this element down to the

bottom of the tree so this element will be again this will be correct so after each iteration we have this part this bottom part will contain the

correct part of the binary heap what will be the difference difference will be the following so now we have many elements in the bottom layer but it's easier to sift down these elements

because they are already in the bottom so we have different situation here so in the bottom layer let's see let's say we only have this number of layers so

so for these elements when you sift down them uh you just spend zero operations for this element you spend one operation for this element span two operations

and three and so on so for the root you spend logan operations okay so we will not sift elements up to the root but down to the bottom

what will be the time complexity if we do it this way that's it uh time complexity will be it will be

the sum for k from 0 to log n so again in layer k we have um what is the easiest way to calculate this

let's say it's 2 in power k elements on layer k and the number of operations is

let's say log n minus k mm-hmm now let's show this this function is bigger how to show this uh let's calculate this

this sum in different way let's calculate for each layer the number of swaps we need to make to sift all elements from the bottom so

let's see let's say if we have layer key let's calculate number of swaps you need

to make to sift all elements from this layer down in in the layer more than k so each element from this top part

will be shifted down to this part at most once so for for for layer k we need to make at most twin power case slopes

from layer k to k plus one we make no more than twin power of caseworks so the total number of swaps in all sift

down operations will be the sum of k from 0 to logan and this sum is the sum of geometrical progression so this sum

equal to the power of k plus one minus one uh to the power of not log n power of log n plus one minus one [Music]

and this equal to two multiplied by n minus one this is bigger again what is the idea that is we have a big number of elements in the bottom of the tree and small number of elements in the

in the top of the tree so we try to make first operations for the for this big number of nodes and some small operations for this top part of the tree

so so we have big number of elements here but they are fast to sit down and we have uh slower sieve down here but but there are small number of elements here so the total time

complexity will be linear okay that's basically all i wanted to talk to today

any more questions

[Music]

do

[Music] do

[Music] you

Loading...

Loading video analysis...