Thank you! If you like my content, I've been working on some projects during the past couple of months. If you would like to stay up-to-date, please consider subscribing to my mail list. Also, if you haven't already, please consider subscribing! I really appreciate the support, and if you want to support the channel, I do have a PayPal link paypal.me/VincentRusso1 for donations that go directly to the creation of content on this channel. I hope that the content I provide there will enhance the videos on my RU-vid page. bit.ly/lp_email
Using list instead of Queue ;) def levelorder(root): Queue=[ ] if root is None: return else: Queue.append(root) while(Queue!=[ ]): curr=Queue[0] if(curr.left): Queue.append(curr.left) if(curr.right): Queue.append(curr.right) print(curr.data) Queue.pop(0) PS: That was a great explanation.. thank you!!
As ppl's comments on the Queue FIFO(first in first out), I finally under stand your logic of using .insert(0, item) for enqueue and .pop(-1) for the dequeue. But I still prefer the sequence of .insert(len(self.items),item) for enqueue and .pop(0) for dequeue. It seems more straight forward following the python index. Albeit that this is probably not as clean on the coding script.
Definitely understand the point you're making and I can see why your approach is clearer, especially from the standpoint of the implementation of the Queue data structure. Thanks for sharing and for watching! :)
Never use List as a queue. It takes 0(1) to put an element in the back, but 0(N) to pop(0) or in reverse to put an element in front in takes 0(N). You slow down your program by thousands of times on a big dataset, use collections deque, it's included in all python
Cheers! If you enjoyed and benefited from my content, please consider liking the video and subscribing to the channel for more content like this. If you would like to support the content creation on this channel please consider unblocking ads when watching my videos as this is how I support my time to make content. I hope to be putting out more similar videos soon!
Hi Mr.Lucid, your content is really one of a kind. This channel definitely deserves more views and attention. Your way of explaining is great and you obviously master your stuff.
Cheers! If you enjoyed and benefited from my content, please consider liking the video and subscribing to the channel for more content like this. If you would like to support the content creation on this channel please consider unblocking ads when watching my videos as this is how I support my time to make content. I hope to be putting out more similar videos soon!
Cheers! If you enjoyed and benefited from my content, please consider liking the video and subscribing to the channel for more content like this. If you would like to support the content creation on this channel please consider unblocking ads when watching my videos as this is how I support my time to make content. I hope to be putting out more similar videos soon!
Thanks sir for explanation. I changed the function just using lists instead of Queue class, I use append to enqueue and pop(0) to dequeue. Here is the function. #Tree tree = BinaryTree(1) # tree.root.left = Node(2) # tree.root.right = Node(3) # tree.root.left.left = Node(4) # tree.root.left.right = Node(5) # tree.root.right.left = Node(6) # tree.root.right.right = Node(7) # tree.root.right.right.right = Node(8) def level_search(self): queue = [] final = [] queue.append(self.root) while len(queue) > 0: final.append(queue[0].value) elem = queue.pop(0) if elem.left: queue.append(elem.left) if elem.right: queue.append(elem.right) return final #final >>> [1, 2, 3, 4, 5, 6, 7, 8]
The queue illustration in the slides was a bit confusing for me in the beginning. I understand now that either way would work, but based on the diagram I thought enqueue inserts an item at index -1 position (end of the python list), whereas dequeue pops the index 0 item. Otherwise very clear explanation, thank you for the great work!
Hey Yongguang. Indeed, perhaps the diagram in the slides portion could have been a bit more explicit, but it sounds like you got the general gist of it. Thanks for the comment, I definitely try to factor these sorts of things into future videos as I want to attempt to be as clear as possible. Thanks for watching, and happy coding!
Cheers! If you enjoyed and benefited from my content, please consider liking the video and subscribing to the channel for more content like this. If you would like to support the content creation on this channel please consider unblocking ads when watching my videos as this is how I support my time to make content. I hope to be putting out more similar videos soon!
Cheers! If you enjoyed and benefited from my content, please consider liking the video and subscribing to the channel for more content like this. If you would like to support the content creation on this channel please consider unblocking ads when watching my videos as this is how I support my time to make content. I hope to be putting out more similar videos soon!
Cheers! If you enjoyed and benefited from my content, please consider liking the video and subscribing to the channel for more content like this. If you would like to support the content creation on this channel please consider unblocking ads when watching my videos as this is how I support my time to make content. I hope to be putting out more similar videos soon!
Thank you! If you like my content, I've been working on some projects during the past couple of months. If you would like to stay up-to-date, please consider subscribing to my mail list. Also, if you haven't already, please consider subscribing! I really appreciate the support. I hope that the content I provide there will enhance the videos on my RU-vid page. bit.ly/lp_email
Nice video, I think the somewhat confusing part was that the visual drawing of the list showed values/nodes being appended to the end of the list and later dequeued from the front, but the code inserts values/nodes at the beginning and then peeks & pops them from the end. That's the impression I got, but anyways, great video series!
Here is simple solution with less lines of code: hope u like this def levelOrder(self): traversal = "" l= list() t = self.root l.append(t) while(len(l)!=0): traversal += (str(l[0].data) + " ") if l[0].left: l.append(l[0].left) if l[0].right: l.append(l[0].right) l.remove(l[0]) return traversal
Hi , your explanation goes beyond perfect , even i am not a computer scientist student, but your explanation makes me love the data structures and coding :) i want to ask you something, why you stopped making tutorials? and is there any tutorials on graphs?
Cheers! If you enjoyed and benefited from my content, please consider liking the video and subscribing to the channel for more content like this. If you would like to support the content creation on this channel please consider unblocking ads when watching my videos as this is how I support my time to make content. I hope to be putting out more similar videos soon!
Cheers! If you enjoyed and benefited from my content, please consider liking the video and subscribing to the channel for more content like this. If you would like to support the content creation on this channel please consider unblocking ads when watching my videos as this is how I support my time to make content. I hope to be putting out more similar videos soon!
This is really great :) Just one qn - Could you explain the reason for overwriting length function, when we have a built in method (len) for list data structure
Thanks. And yeah, the reason we overload it is because the built-in length function is not defined for arbitrary data structures like this. It works on strings, lists, etc. but how would Python know how length is defined for this if we don't explicitly tell it how to quantify it?
Hi LucidProgramming! I just came across your videos, they're very good. I have a question about def print_tree. Why did you use tree.root as the function argument e.g. return self.inorder_print(tree.root)? I'm new to this, shouldn't it be self.root instead?
I had to watch the video twice to make sure I understood why we use a -1 index for the peek() function. Because of the nature of a queue, when you're inserting into the queue (enqueuing), you can use 0 index to add an element to the front of the queue... but when you're dequeuing an element, you have to "flip" the structure and use -1 as the index since a queue is "first in, first out". Essentially, the front becomes back. Does that make any sense at all? If so, is that the right way of thinking about it?
Yeah, I think that's a fine way to visualize it. A queue is like the queue in a shop where the first one in is the first one out, while a stack is based on being the first one in is the last one out; like a stack of plates at a buffet or a stack of pancakes.
sir,hi,you wrote if node.left: queue.enqueue(node.left) if node.right: queue.enqueue(node.right) isnt the enqueue function inserting nodes at position 0? so isnt there a clash?
Hi Jowadul. There shouldn't be any clash, as the enqueue function will automatically place the element in the next spot in the queue. I might be misunderstanding your question as well.
Hi Sir, thank you for the series. I have a question. In the code for the level order traversal, why didnt you use the built in python list for the queue. like below: def levelOrderPrint(self): ret = [] track = [] cur = self.root track.insert(0, cur) while len(track) != 0: cur = track.pop() ret.append(cur.data) if cur.left != None: track.insert(0, cur.left) if cur.right != None: track.insert(0, cur.right) return ret Because the built in list can do all of the needed operations. Is there any reason for the queue implementation?
Sure, it can do all the same things, but the queue object is going to give better runtime if you want to remove from the front / add to the back / etc.
just used your logic and instead of creating a queue, used an array and came with the following: def level_order(self, start, traversal): # create a queue # append the first root element # pop the first element, print it, and check if it has a left and a right node and append it to the stack # pop again the first element that has been appended in the stack, print it and then check again # 1, 1 has 2 and 3 to append # 2 pops, 2 has 4 and 5 to append # 3 pops, 3 has 6 and 7 stack = [start] while stack: start = stack.pop(0) traversal += (str(start.value)+'-') # print(start.value, end="-") if start.left: stack.append(start.left) if start.right: stack.append(start.right) return traversal
Heyy great tutorial.... I am not able to understand the concept behind .value in peek function. Is it some kind of inbuild function as we didn't define the "value" variable in our queue class. In my opinion the function should return self.items[-1]...but its showing error if I'm not using self.items[-1].value..
Thanks for such amazing tutorials , but I wanna ask - can we apply iteration method for DFS traversals aswell? I always found Recursion confusion so I was wondering can't I use just the iteration method to implement DFS :)
@@LucidProgramming Thanks for replying sir but one more thing : Can you make a detailed video on how recursion works in such cases?? I understand basics of it but i am not able to understand your implementation and how the traversal string is updated . I request you sir, if you get the time please make a short video explaining how recursion works in such situations where we update a given string via function calls. I really need to understand how it works in order to implement it for any use :)
@@KKinHD10 You can feel free to make suggestions on my Patreon page. This would streamline what you want to see and also help to support my channel. www.patreon.com/lucidprogramming
@@LucidProgramming He's referring to the Linked List videos that you created. When creating classes in those videos, you defined the class as: 'class LinkedList:', whereas in this video you defined the Queue class as: 'class Queue(object):' -- I'm kind of curious about this myself as I'm fairly new to creating classes in python. If the inclusion of (object) necessary in certain cases and not others?
@@LucidProgramming Thanks for posting programming videos. It has been a great learning. The concept of peek still isn't clear to me. Why don't we do peek at 0th element since 0th element will be first in queue and -1th element will be last element in queue. Also, while inserting aren't we supposed to append to the end of the list? Here, we are always inserting at 0th element so by that logic right element would precede the left element. Please help me to clarify this. Thanks in advance.
@@dewanggedia685 Ah, I see, and you know what, the peek for a queue should definitely take from the front. I suppose I was implementing a stack, really, for this level order traversal. The data structure implementation here does the trick, but I can see where this is misleading. I'll update the code on my github with appropriate comments. Thanks for pointing that out to me, and sorry for the confusion!
thanks for creating and sharing the nice video . i am not able to get the logic of peek function in class queue you are using -1 index , please explain. self.items[-1].value
Hi Amit. No problem, I hope that the video was useful to you! The general gist of the negative indexing is that it goes backward in the list. For instance self.items[-1] is the last item in the self.items list. The element self.items[-2] is the second to last item in the list and so on. Does that make sense? Actually, if you're interested in staying up-to-date with the content on my channel, you might want to sign up for the mailing list I'm starting: bit.ly/lp_email Cheers!
Each time enqueue is called (inside the if conditions), the start/item argument (whichever node you're on), is placed in the 0 index (first position) of the Queue self.items list. The peek method is returning the value of the last index position of the items list: self.items[-1].value This works because the enqueue method keeps placing the nodes it checks in sequential order at the beginning of the list (the zero argument in self.items.insert(0, item)). Meaning that even if it checks if a left node exists and places it in the first element, it will then go and check if a right node exists and then place THAT element in the 0 position (before the previous left node check), allowing the peek function to return the value of the left node - which is now the last item in the list. After calling the peek method, the dequeue method is called to pop out the last element of the Queue self.items list, allowing the process to repeat now with the peek method returning the next value in the self.items list (which would be the right node after a left node's value was returned). Hope that made some sense.
Cheers! If you enjoyed and benefited from my content, please consider liking the video and subscribing to the channel for more content like this. If you would like to support the content creation on this channel please consider unblocking ads when watching my videos as this is how I support my time to make content. I hope to be putting out more similar videos soon!