Important Note: For deleteLast and deleteStart, if the return type was void this would be fine, but since we're returning a node, that node should not have any reference to the list (meaning you can still get to the list from that node). This means toDelete.next should be set to null for the deleteStart method and toDelete.prev should be set to null for the deleteLast method before returning toDelete.
You are a savior man, Best explained Double Linked on the Internet period... You explained it better in 17 mins than my prof did in 120mins! Thanks alot!
Got stuck at the last challenge of Section 9 of the "Java Programming Masterclass for Software Developers" by Tim Buchalka on Udemy. Your videos helped me a ton to understand the concepts of Singly/Doubly Linked Lists, which were not properly explained in my paid course Dude, you are a freakin' gem! Thanks a lot!
Yeah, once I saw that Singly linked list video, and was totally amazed of how simple you made it, when I got into your channel and found this video I was %100 sure it was going to be even better!
One of the most informative videos I have seen about linkedlists TY ! Just one question I have: at delAfter shouldn't last line of code be: toDelete.prev.next= null; ? Because at this point we know our toDelete is the last node of the list wouldn't setting its prev.next= toDelete.next; make it a nullPointerException ? This has been boggling my mind
Why dont you have a tail and only head? The main advantage of Doubly Linked List is that you dont have to traverse all the way to the end if you want to delete at the end or add at the end because you have tail. But you helped me a lot thank you
Thank you, it's very clear explained! Wouldn't be the time complexity for "Insert End" and "Delete End" also O(1) if the "head.prev" would point to the last element in the list, and the "last.next" to the head (head.prev.next = head)? So basically you would have a circle.
@Arber Osmani Thank you and I'm glad it helped :) So, what you're thinking about is most likely a circular doubly linked list (a small variation to the doubly linked list). In that case, then yup, head.prev would refer to the last node and head.prev.next would refer to head. Therefore inserting and deleting at the end would be an O(1) operation. This, however, happens to be a non-circular doubly linked list, so head.prev refers to null, and the only way to reference the end would be to traverse the entire list. Hope this helped. :)
@@BlueTreeCode but with a doubly linked list you also keep track of the tail and not only the head. so that means the time complexity of adding a node to the end is the same as adding a note to the benning being O(1)
I am having some issues understanding the syntax of the code from Delete Node After: "for (; toDelete !+ null; toDelete = toDelete.next)" what is the semi-colon at the beginning?
Thank you so much!! I no longer have the code, but it's something I will do in the future. Please don't forget to share as it will help the channel to grow.
Thank you for the feedback, Mana! I really do appreciate it. I have definitely slowed down in my later videos. You can try adjusting the speed to 0.75/0.5 via the settings icon.
Hi, wonderful explanation of linked list, but I would like to know why you did not choose to have another Node just for the last node in the list. Wouldn’t having a last node be more sufficient when you are trying to delete or add nodes in the end?
Hi Gabriel Zn, Thank You! I'm assuming you mean a "tail" reference. I chose to use just a "head" reference, because sometimes you will be given a DLL without a "tail" and for whatever reason you may be expected to manipulate the linked list as is. However, it depends on what you want out of the linked list. For example, a really good use of a Doubly Linked List with a "tail" would be a LRU(Least Recently Used) cache, where you'll remove the least recently used items from the "tail" for example and add the most recently used to the head. Whatever the situation, once you know how to manipulate the list without a tail, doing so with a tail will be very easy. Hope this helps :)
@@Gzzzzzz111 No Problem! Looking back at my answer, I meant to remove the LRU node from the tail. I'll edit it in. I'm glad it's helping. I would like to add more videos, especially to finish up the series on data structures, but I have quite a lot going on at the moment. Once things ease up, I'll try to get those videos up.
Hi, @@alex0917lfo. So to covert the for loop to a while loop, we want to look at the stopping(toDelete != null) and iterative (toDelete = toDelete.next) condtions. And all we do is replace the for loop with: while(toDelete != null){ if(toDelete.data == data){ toDelete = toDelete.next; } } For the recursive method, it's a bit more work but it's pretty simple. The first thing to do is get rid of the parameter 'curr' since this was only used for passing the state to the next recursive call. We can add curr inside the method block instead. Then starting from scratch: we'll check to make sure head != null. void addAfter(int insertAfter, int data){ DllNode curr = head; if(curr == null){ return; } ..... } The next step is to copy the 2nd if block along with its nested if and throwing it inside of a while loop (This is our logic). Then get rid of the else block, since that's used for the recursive call. while( curr != null){ if(curr.data == insertAfter){ DllNode n = new DllNode(data); if(curr.next != null){ curr.next.prev = n; n.next = curr.next; } curr.next = n; n.prev = curr; break; //once the node is inserted, break out the loop. } curr = curr.next; // iterates over the list. } And all we do is combine these parts, and that's it :) Hope this helps. void addAfter(int insertAfter, int data){ DllNode curr = head; if(curr == null){ return; } while( curr != null) { //stopping condition. if(curr.data == insertAfter){ DllNode n = new DllNode(data); if(curr.next != null){ curr.next.prev = n; n.next = curr.next; } curr.next = n; n.prev = curr; break; //once the node is inserted, break out the loop. } curr = curr.next // iterates over the list. } //end of while loop. }
Hi Tyrique, I think you may have mistaken n.prev with curr.prev. Note that 'n' will be the last node in the list. Not setting n.prev to curr will mean we cannot traverse backwards from the end of the list (which disrupts the formation of the Doubly Linked List). Hope this helps :)
Hi Edgar, you can compare nodes via their data or memory address. Comparing via memory addresses will let you know if the two references point to the same node. For example. If (p1 == p2) means p1 and p2 reference the same node. Comparing via data would be something like, if (p1.data == p2.data). This just compares their data properties, however it doesn't tell us if p1 and p2 are referencing the same node. Hope this helps :)
Hi Tyrique, in order to remove an object, there must not be any references pointing to that object. If we set toDelete to null, the previous node's next will still be pointing to the node that toDelete was originally pointing to. Notice that by setting toDelete.prev.next to Null, we're removing the only reference pointing to the last Node, therefore allowing it to be garbage collected / destroyed. Hope this helps :)
Hi Kenneth, that sounds like a 'Product', so you can create a Product class with instance variables (code, description, price, quantity, type). class Product { //You can adjust to whatever types you need. int code; String description; double price; double quantity; String type; public Product(code, desc, price, quantity, type){ /* Initialize the instance variables here with the arguments */ } } Once that's done, you can do something like this: class DllNode { Product product; DllNode next public DllNode(product){ //NB: product a reference to a Product Object. this.product = product; this.next = null; } } Hope this helps :)
@@BlueTreeCode Btw, how can I stored values of the variables System.out.print(" Enter a Code :"); code = sc.next(); System.out.print(" Enter a Description:"); desc = sc.next(); System.out.print(" Enter a price :"); price = sc.nextDouble(); System.out.print(" Enter a quantity :"); quant = sc.nextInt(); System.out.print(" Enter a type :"); type = sc.next().charAt(0); where to store? Product n = new Product(code,desc,price,quant,type); ?? then when I call it in a method InsertBegin() public class DoublyLinkedList{ public DoublyLinkedList(DllNode head){ this.head =head; } public void InsertBegin(Product product){ if (head == null){ head = new Product(code,desc,price,quant,type); } } } Im just practicing your tutorial.
Hi Evelyn! I'm so sorry about that. I was unaware of how fast I was speaking due to limited feedback in the beginning days of the channel. However, I've definitely adjusted in my later videos. For now you can try adjusting the video speed to 0.75/0.5 via the settings icon. Let me know if that helps and thank you for the feedback, Evelyn!
Important Note: For deleteLast and deleteStart, if the return type was void this would be fine, but since we're returning a node, that node should not have any reference to the list (meaning you can still get to the list from that node). This means toDelete.next should be set to null for the deleteStart method and toDelete.prev should be set to null for the deleteLast method before returning toDelete.
i have an exam in 7 hours , you're saving me thank you so much , i love the way you explain and the animations makes it more clear , please continue
That's the goal! Hope you aced that exam! Please don't forget to share / recommend the channel to others / on social media to help it grow.
You are a savior man, Best explained Double Linked on the Internet period... You explained it better in 17 mins than my prof did in 120mins!
Thanks alot!
I'm glad it helped!! Please don't forget to share / recommend the channel to others / on social media to help it grow.
Got stuck at the last challenge of Section 9 of the "Java Programming Masterclass for Software Developers" by Tim Buchalka on Udemy.
Your videos helped me a ton to understand the concepts of Singly/Doubly Linked Lists, which were not properly explained in my paid course
Dude, you are a freakin' gem! Thanks a lot!
Thank you!! I'm very glad it's helped you, Shermukhammad!
The visualization on the bottom and the code on the top is spot on, very easy to understand.
Best lecture by far on doubly linked lists on the web and possibly in college clear and to the point great job
@Liam, thanks! :)
Hey Everyone! Thanks for checking out my video! Don't forget to Like, Subscribe, and MOST IMPORTANTLY click that Notification Bell for updates! :)
This is the best Data structure series I would say. Thank you
Thank you, Dilruba! Please feel free to share these videos on social media as they do help out the channel a lot.
THIS WAS THE BEST VIDEO I HAVe SEEN SO FAR!!! Great work please post more!
Thank you for the kind comment, Angel!
I now understand doubly linked list because of you!!! These videos and animations are amazing!!
You're welcome, marhawk!
Sir you clear the whole concept of doubly and singly linkdlist in just one video
Glad to hear, Hamza! :)
Gosh..!
I never thought this topic is this much Simple and Easy...
Man You nailed it..!
Love You😍❤️
I'm glad it helped, Agha! :)
Clearly explained DLL along with animation and code, Thanks
I'm glad it helped, Jeevanandham! :)
Yeah, once I saw that Singly linked list video, and was totally amazed of how simple you made it, when I got into your channel and found this video I was %100 sure it was going to be even better!
Thank you so much!!!
Bundles of Thanks! sir for making my life easier, I appreciate your work, and keep it up.
You're very welcome, Mohammad! Thank you for the kind comment.
Pasa waaaa
@@MohsinAli-zq5mw Rasha kna Che pa Rapadesawam.
I'm so happy I found this video! and channel best explanation for LL
Thank you so much, Toyin!
Thank You!! The visual explanation helped a lot.
Glad it's helped, Cryptix 44! :)
One of the most informative videos I have seen about linkedlists TY ! Just one question I have: at delAfter shouldn't last line of code be: toDelete.prev.next= null; ? Because at this point we know our toDelete is the last node of the list wouldn't setting its prev.next= toDelete.next; make it a nullPointerException ? This has been boggling my mind
Thank you so much, I couldn't understand why doing .prev.next would change anything but now I do thanks to you!
Glad it helped, Samy!
Thank you, it's very clearly explained! I have followed you
Thank you so much, Jacob Huang! Please feel free to share these videos on social media as they do help out the channel a lot.
Why dont you have a tail and only head? The main advantage of Doubly Linked List is that you dont have to traverse all the way to the end if you want to delete at the end or add at the end because you have tail. But you helped me a lot thank you
cant tell you how much i love you right now
It's very much appreciated, prova_prime!
u just earned a new subscriber mate, very nice and informative video
Thank you, Arsyanda!
Amazing explanation!
Thanks, Dean :)
This was so informative and helpful, thank you!
Glad it helped, Melody! :)
Thank you, it's very clear explained!
Wouldn't be the time complexity for "Insert End" and "Delete End" also O(1) if the "head.prev" would point to the last element in the list, and the "last.next" to the head (head.prev.next = head)? So basically you would have a circle.
@Arber Osmani Thank you and I'm glad it helped :) So, what you're thinking about is most likely a circular doubly linked list (a small variation to the doubly linked list). In that case, then yup, head.prev would refer to the last node and head.prev.next would refer to head. Therefore inserting and deleting at the end would be an O(1) operation. This, however, happens to be a non-circular doubly linked list, so head.prev refers to null, and the only way to reference the end would be to traverse the entire list. Hope this helped. :)
@@BlueTreeCode but with a doubly linked list you also keep track of the tail and not only the head. so that means the time complexity of adding a node to the end is the same as adding a note to the benning being O(1)
Thank you sooo much for the explanation! way much better than my teacher did!! subscribed:)
Thank you, and I'm glad it helped, Ya Li! :)
Most amazing video on linked list ever💕💕💕💕
Thank you for the kind comment, BIBEK MAITY :)
Thanks man this was so helpful.
Thank you so much, Hrithik! Please feel free to share these videos on social media as they do help out the channel a lot.
@@BlueTreeCode sure!
You're a live saver!!!
Thank you, Ryan! I really appreciate it. If you enjoy this content, feel free to share it as it helps out the channel. :)
I am having some issues understanding the syntax of the code from Delete Node After:
"for (; toDelete !+ null; toDelete = toDelete.next)"
what is the semi-colon at the beginning?
Such great explanations! really appreciate your great work. Is it possible to post the actual codes for us to try them out?
Thank you so much!! I no longer have the code, but it's something I will do in the future. Please don't forget to share as it will help the channel to grow.
Much appreciate for explanation! 🇺🇦❤️
Thank you so much!! Please don't forget to share / recommend the channel to others / on social media to help it grow.
thank you for your explanation :)
Thank you! :) Please don't forget to share / recommend the channel on social media to help it grow.
bro ur so clutch for this video
Thank you very much, Neil Goswami! :)
thank you, it was well explained
Thank you Samandar! Please feel free to share these videos on social media as they do help out the channel a lot.
Thank you for your time. but ur lecture is like running water
Thank you for the feedback, Mana! I really do appreciate it. I have definitely slowed down in my later videos. You can try adjusting the speed to 0.75/0.5 via the settings icon.
Can I know how to do the Delete Node Before? I tried but it’s just not working
Guys quiick question, min 3:03 how does maikng before.next= head, then assigning head to before work(thats like saying 3->5, then saying 5->5 no?)
Sir you are great
Thank you, Hamza! I try my best.
Hi, wonderful explanation of linked list, but I would like to know why you did not choose to have another Node just for the last node in the list. Wouldn’t having a last node be more sufficient when you are trying to delete or add nodes in the end?
Hi Gabriel Zn, Thank You! I'm assuming you mean a "tail" reference. I chose to use just a "head" reference, because sometimes you will be given a DLL without a "tail" and for whatever reason you may be expected to manipulate the linked list as is. However, it depends on what you want out of the linked list. For example, a really good use of a Doubly Linked List with a "tail" would be a LRU(Least Recently Used) cache, where you'll remove the least recently used items from the "tail" for example and add the most recently used to the head. Whatever the situation, once you know how to manipulate the list without a tail, doing so with a tail will be very easy. Hope this helps :)
@@BlueTreeCode Thank you for getting back to me! Really appreciate the work. Hope you can make more data structure videos like this. :)
@@Gzzzzzz111 No Problem! Looking back at my answer, I meant to remove the LRU node from the tail. I'll edit it in. I'm glad it's helping. I would like to add more videos, especially to finish up the series on data structures, but I have quite a lot going on at the moment. Once things ease up, I'll try to get those videos up.
GREAT CONTENT !!
Thanks, huzi Jadli!
thank u soooo much that was sooooo helpful
Glad you found it helpful! :)
Sir why you are not upload that types of videos
I'm planning to upload a video on Hash Tables soon.
doesn't a doubly linked list have a tail? won't that makes adding and removing from the end easier and faster?
Yeah it should be O(1)
So basically, think of the next and previous of a node as the pointers to the address of another node.
Yep. The prev and next references are basically the addresses to the object(node) they are referring to. Hope this helps :)
Hi, is that possible you can upload the while loop version of DeleteToAfter? Thanks
and please also upload the while loop version of AddToAfter. Thanks
Hi, @@alex0917lfo. So to covert the for loop to a while loop, we want to look at the stopping(toDelete != null) and iterative (toDelete = toDelete.next) condtions. And all we do is replace the for loop with:
while(toDelete != null){
if(toDelete.data == data){
toDelete = toDelete.next;
}
}
For the recursive method, it's a bit more work but it's pretty simple. The first thing to do is get rid of the parameter 'curr' since this was only used for passing the state to the next recursive call. We can add curr inside the method block instead.
Then starting from scratch: we'll check to make sure head != null.
void addAfter(int insertAfter, int data){
DllNode curr = head;
if(curr == null){
return;
}
.....
}
The next step is to copy the 2nd if block along with its nested if and throwing it inside of a while loop (This is our logic). Then get rid of the else block, since that's used for the recursive call.
while( curr != null){
if(curr.data == insertAfter){
DllNode n = new DllNode(data);
if(curr.next != null){
curr.next.prev = n;
n.next = curr.next;
}
curr.next = n;
n.prev = curr;
break; //once the node is inserted, break out the loop.
}
curr = curr.next; // iterates over the list.
}
And all we do is combine these parts, and that's it :) Hope this helps.
void addAfter(int insertAfter, int data){
DllNode curr = head;
if(curr == null){
return;
}
while( curr != null) { //stopping condition.
if(curr.data == insertAfter){
DllNode n = new DllNode(data);
if(curr.next != null){
curr.next.prev = n;
n.next = curr.next;
}
curr.next = n;
n.prev = curr;
break; //once the node is inserted, break out the loop.
}
curr = curr.next // iterates over the list.
} //end of while loop.
}
@@BlueTreeCode Thanks a lot!
Thanks again
You're very welcome, Tyrique!
In adding a node to End why could you just say curr.next=n ? Isn't curr.prev already curr?
Hi Tyrique, I think you may have mistaken n.prev with curr.prev. Note that 'n' will be the last node in the list. Not setting n.prev to curr will mean we cannot traverse backwards from the end of the list (which disrupts the formation of the Doubly Linked List). Hope this helps :)
hi your videos are amazing, i have a question, how compare a nodo with other nodo in the double linked list
Hi Edgar, you can compare nodes via their data or memory address. Comparing via memory addresses will let you know if the two references point to the same node. For example. If (p1 == p2) means p1 and p2 reference the same node. Comparing via data would be something like, if (p1.data == p2.data). This just compares their data properties, however it doesn't tell us if p1 and p2 are referencing the same node. Hope this helps :)
Also why are you doing todelete.prev.next = null why not just todelete = null
Hi Tyrique, in order to remove an object, there must not be any references pointing to that object. If we set toDelete to null, the previous node's next will still be pointing to the node that toDelete was originally pointing to. Notice that by setting toDelete.prev.next to Null, we're removing the only reference pointing to the last Node, therefore allowing it to be garbage collected / destroyed. Hope this helps :)
Please answer
User input:
Code
Description
Price
Quantity
Type
How can I use double linked list if user input 5 instead of 1 base on your tutorial
Hi Kenneth, that sounds like a 'Product', so you can create a Product class with instance variables (code, description, price, quantity, type).
class Product {
//You can adjust to whatever types you need.
int code;
String description;
double price;
double quantity;
String type;
public Product(code, desc, price, quantity, type){
/* Initialize the instance variables here with the arguments */
}
}
Once that's done, you can do something like this:
class DllNode {
Product product;
DllNode next
public DllNode(product){
//NB: product a reference to a Product Object.
this.product = product;
this.next = null;
}
}
Hope this helps :)
@@BlueTreeCode thankyou btw. I already pass my project but I'm happy that I've learned new ways to do a linkedlist
@@kennethdelacruz9485 Glad to hear, Kenneth!
@@BlueTreeCode Btw, how can I stored values of the variables
System.out.print("
Enter a Code :");
code = sc.next();
System.out.print("
Enter a Description:");
desc = sc.next();
System.out.print("
Enter a price :");
price = sc.nextDouble();
System.out.print("
Enter a quantity :");
quant = sc.nextInt();
System.out.print("
Enter a type :");
type = sc.next().charAt(0);
where to store?
Product n = new Product(code,desc,price,quant,type); ??
then when I call it in a method InsertBegin()
public class DoublyLinkedList{
public DoublyLinkedList(DllNode head){
this.head =head;
}
public void InsertBegin(Product product){
if (head == null){
head = new Product(code,desc,price,quant,type);
}
}
}
Im just practicing your tutorial.
Confused also.
wahsh
12:52
like
Is it me or does he sound like he has marbles in his mouth sometimes
you speak too fast like a bullet train it's hard for me to catch up...
Hi Evelyn! I'm so sorry about that. I was unaware of how fast I was speaking due to limited feedback in the beginning days of the channel. However, I've definitely adjusted in my later videos. For now you can try adjusting the video speed to 0.75/0.5 via the settings icon. Let me know if that helps and thank you for the feedback, Evelyn!