every good programmer should know how to code this data structure (its easy)

  Рет қаралды 195,066

Low Level Learning

Low Level Learning

Күн бұрын

Every new programmer should learn how to make a linked list in C. Linked lists not only demonstrate proficiency with pointers in lower level languages, but also act as a tool that you can take with you to other projects that require dynamic storage that is both searchable and fast.
In this video, we discuss what a linked list is, the various operations you perform using a linked list, and how linked lists can be built in C.
Code: www.github.com/lowlevellearni...
🏫 COURSES 🏫
www.udemy.com/course/c-progra...
🔥🔥🔥 SOCIALS 🔥🔥🔥
Low Level Merch!: www.linktr.ee/lowlevellearning
Follow me on Twitter: / lowleveltweets
Follow me on Twitch: / lowlevellearning
Join me on Discord!: / discord

Пікірлер: 431
@LowLevelLearning
@LowLevelLearning Жыл бұрын
Go check out the code here: www.github.com/lowlevellearning/singly-linked-list and let me know if you want more data structure videos!
@anon_y_mousse
@anon_y_mousse Жыл бұрын
This is okay for how a first year CS student would code it, but I'd like to see you do a tutorial that shows the more experienced method of turning the code into a generic library. Also, using void* for the structure was a bad idea for type checking purposes as well as introduces the possibility on some older, but potentially still relevant, platforms of pointer size mismatch. Better is to do typedef struct node_s node_t; struct node_s { int data; node_t *next; }; // While reusing the structure name in a typedef is allowed in C, as in typedef struct node_t node_t; I personally dislike the practice for various reasons.
@Stopinvadingmyhardware
@Stopinvadingmyhardware Жыл бұрын
Dynamic stacked structures? I know it's more for general compute, but I have never seen anyone discuss it.
@Ak4n0
@Ak4n0 5 ай бұрын
@@anon_y_mousse Para el caso también podría hacer: typedef struct node_t { node_t *next; int data; } Node; y no tienes que separar la definición en dos lineas. De todas formas usar node_t* o void* en este contexto es lo mismo: Un puntero, sea del tipo que sea tiene un tamaño fijo, por lo que no cambia el tamaño de la estructura. Por otra parte en este tipo simple de estructura el puntero no va a tener aritmética ni se va a usar con notación de de array, por lo que no le afecta de que tipo sea. Lo único que debe hacerle el cast cada vez que quiera dereferenciarlo.
@anon_y_mousse
@anon_y_mousse 5 ай бұрын
@@Ak4n0 If I'm understanding you based on an automated translation, on older platforms where you had near and far pointers they were indeed multiple sizes, and void * was allowed to be the largest size possible if the implementation desired. It's less relevant on modern computers, but the type checking argument is still valid, and your struct is actually invalid. If you want to define it in one statement it would be typedef struct node_s { struct node_s *next; int data; } node_t; That's a semi-acceptable method too, but I prefer a separate statement because if you deal with more links you don't need to repeat the struct keyword that many times.
@esra_erimez
@esra_erimez Жыл бұрын
For those interested in fundamental data structures and algorithms, I highly recommend "Algorithms + Data Structures = Programs" by Niklaus Wirth. It is the seminal authority on the the topic.
@elitearmedforce
@elitearmedforce Жыл бұрын
Link pls
@esra_erimez
@esra_erimez Жыл бұрын
@@elitearmedforce Here you go: en.wikipedia.org/wiki/Algorithms_%2B_Data_Structures_%3D_Programs
@leninalopez2912
@leninalopez2912 Жыл бұрын
Agreed. Reading books is a more efficient use of your time, and the best way of not loosing time with this kind of inefficient clickbait.
@twothreeoneoneseventwoonefour5
@twothreeoneoneseventwoonefour5 Жыл бұрын
@@leninalopez2912 If you think reading books is efficient for your learning then you don't know what is efficient learning at all and haven't ever been learning efficiently yourself. Reading books is the LEAST (time) efficient way of ALL to learn stuff. It is thorough, yes, but that's all there is to it. Reading can *never* be more efficient than watching a video(Audio+Visual input) if we assume both have the same quality content. When you read you do indeed go into more theory and detail, but what is the purpose of that if you can't apply 80% of stuff that you read in practice("Tutorial Hell" from reading books is *magnitudes* worse than "tutorial hell" from videos, I can explain the reasoning if you are interested). You can't really say "books" and "efficient use of your time" in one sentence as this is just a contradiction because of the reasons above. I am 100% sure that I can outlearn(have better learning results than) *every single person* who studies by reading books, by studying using a video material with the same quality instead, for example. I really dislike people who haven't really been competitive or (really) care about efficiency, yet talk like they tried every single thing and know the best. No, you just went with what first worked for you(or preference), blindly thinking it is "efficient", without ultimately seeking for what is actually most efficient in reality. Efficiency is not about optimizing your own preferences, it is about being competitive and adapting to the best environment possible. You can say fast walking is more efficient than normal walking, but I am saying that I will rather run, even if I never ran in my entire life, if in the end it will be more efficient, that is the difference.
@svaira
@svaira Жыл бұрын
@@twothreeoneoneseventwoonefour5 it's not about efficiency, that's simply a dumb perspective. Learning is about seeing what you already know in a new light and not running ahead to something else. For good reason the advice is "_stop_ and think!". In order to really think, it's best to first stop and reconsider if it's a good idea at all. Wirth was a mathematician first, and I see that in his writing. It has proofs of fact, mathematical proofs, not just proofs of concept. The kind of sloppiness of "just hacking away at it" and "being efficient and productive" without evaluating the goals of your own enterprise is exactly why the tech industry is at the point where it is today: stalled for ideas, producing buggy messes and completely separated from any critical understanding of it's own creations
@alistair.foggin
@alistair.foggin Жыл бұрын
In removeNode, you only free the removed node if it is in the middle or the end of the list. If it is the head, it is not freed so there is still a memory leak. Other than that, this is a fantastic tutorial! Keep up the good work!
@LowLevelLearning
@LowLevelLearning Жыл бұрын
Crap. Feel free to put in a PR on the github! :D
@kuroikenjin7652
@kuroikenjin7652 Жыл бұрын
@@LowLevelLearning Also forgot to free the list on exit.
@xBZZZZyt
@xBZZZZyt Жыл бұрын
@@kuroikenjin7652memory is no longer used when process exits
@TheStuartstardust
@TheStuartstardust Жыл бұрын
Nice flex 💪😎 🤓
@thev01d85
@thev01d85 Жыл бұрын
@@xBZZZZyt Still a memory leak.
@chossuh9058
@chossuh9058 Жыл бұрын
Due to caching linked lists are usually slower than a simple contiguous vector. Bi-directional Linked lists typically require 3x the number of bytes as a simple vector structure, so they hurt performance for even medium sized lists.
@softwarelivre2389
@softwarelivre2389 Жыл бұрын
Truth hath been spoken
@MrSephirothJenova
@MrSephirothJenova Жыл бұрын
I wonder if it would be worth it to first copy all of the data into a contiguous array from a linked list before operating on it with a complicated algorithm, and then copying it back at the end. Somehow this sounds better than running an algorithm (like sort) on the list itself.
@softwarelivre2389
@softwarelivre2389 Жыл бұрын
@@MrSephirothJenova The best use for a linked list is when you need to add or remove an element in the middle of the list, then it is great!
@colejohnson66
@colejohnson66 Жыл бұрын
@@softwarelivre2389 but to remove from the middle (at least by index), you must traverse the whole list. The cache thrashing that results makes it so much worse than an array/vector that uses memcpy.
@softwarelivre2389
@softwarelivre2389 Жыл бұрын
@@colejohnson66 good point, but sometimed you have to merge two linked lists at a position (put one in the middle of the other), which can be very fast in the case of linked lists
@lennonmclean
@lennonmclean Жыл бұрын
I left a PR that fixes a couple issues with the code. As Alistair Foggin said, there is a memory leak in removeNode, and the call to malloc() in addNode only needs to occur in one place. Additionally, as noted by Mohammad Salman, the insertNode() function does not interate through the list each time the position variable is decremented. This means that insertNode only ever inserts into the second position.
@user-dp3zr1qe3s
@user-dp3zr1qe3s Жыл бұрын
This guy is so bad at coding I can't believe the support he's receiving.
@mwanikimwaniki6801
@mwanikimwaniki6801 Жыл бұрын
@@user-dp3zr1qe3s Mistakes are made.. smh.
@ignacio_falco
@ignacio_falco Жыл бұрын
I read the insertion loop over and over again trying to understand what was I missing, to finally realize that there was an error
@martinfinch5011
@martinfinch5011 Жыл бұрын
@@ignacio_falco lol. So did I. Thought I was going nuts and almost called in to quit my job as a coder lol
@hanspeterbestandig2054
@hanspeterbestandig2054 Жыл бұрын
@@user-dp3zr1qe3s I totally agree! Can't believe it either! 😳This video should not be recommended how to learn to implement a single linked list in C. It's a big mess, riddled with serious bugs and reveals a totally sloppy attitude towards clean working... The only thing that is of any use is the graphic explanation. Sorry to say that. 😐
@ekenedilichukwuekeh4647
@ekenedilichukwuekeh4647 Жыл бұрын
I noticed your new use of transitions since I’m a part time videographer as well. Your production quality is up from last year! Keep it up. I’m loving the consistency!!
@misterrreco2535
@misterrreco2535 Жыл бұрын
My favourite implementation of a linked list is a circular doubly linked list. Here the nodes have 2 references, previous and next. The head of the list is not a part of the list (its data is unimportant), instead it points to the first node and the last node as its next and previous references, respectively. If the list is empty, then the head points to itself on both previous and next. The reason why I like this is because, being circular, there are no edge cases. Removing the first element is the same as removing an element in the middle of the list or the end. Inserting an element is the same regardless if the list is empty, you are inserting at the start, end or middle. This simplicity makes fixing bugs and adding more functionality to the list much easier.
@no-one3795
@no-one3795 Жыл бұрын
I love how clean this tutorial is. Keep it up 👍
@LowLevelLearning
@LowLevelLearning Жыл бұрын
Thank you! Cheers!
@hanspeterbestandig2054
@hanspeterbestandig2054 Жыл бұрын
“Clean”? Are you serious? 😳It’s a whole mess mixed with pretty serious Bugs in it! Almost every rule of good software development is violated in this course! It contains wrong semantics, memory leaks and shows a ridiculous bad style of coding habits! Such a basic thing as a common Data container has to be robust. My advice: You should better watch videos from people who work clean and are aware of their responsibility for their big count of subscribers. 🙄
@pqsk
@pqsk Жыл бұрын
Doesn't matter how long I've been programming, there's something about implementing and viewing the code for a linked list that's just fascinating. Great stuff. I was taught to always have a head and tail node. So I always code that out of habit. It does complicate the code just a little bit though.
@MECHANISMUS
@MECHANISMUS Жыл бұрын
What's the use of the tail?
@pqsk
@pqsk Жыл бұрын
@@MECHANISMUS so when you do an insert at the end of the linked list you do it in O(1).
@zenverak
@zenverak Жыл бұрын
@@MECHANISMUS I believe that a doubly linked list. Which as the other user stated, gives you access to more efficient opporations because you know the end and beginning of the list. So you can trace inwards with both at the same time, cutting any O(N) time down and as he said, insert into list O(1) time.
@cl-7832
@cl-7832 Жыл бұрын
@@zenverak having a head and tail node doesnt always imply having a double linked list. But it will make implementing a queue or stack easy because you will always have access to the head or tail with O(1) time.
@RockOfGreece
@RockOfGreece 7 ай бұрын
Having a tail is essential for FIFO
@dagoberttrump9290
@dagoberttrump9290 Жыл бұрын
You don't need to branch if head points to NULL, just assign head to the new node, if its NULL so be it. Also position 0 should semantically mean "before the first", it seems now you can only insert after the first element (you can add though but add can be implemented in terms of insert as a simplified function)
@larrycarlson3088
@larrycarlson3088 Жыл бұрын
Currently having to do a .cpp paper for an engineering degree and I find everything you've done in c very helpful. I learn best from seeing functional examples with explinations and your channel is great for it. I do have a code example from my course that I would appreciate an explination for though, as I can't make heads nor tails of what it is actually doing. If you want a picture I can send it to you, basically it is allocating information in a table structure, but in the book (learning through correspondence) it isn't clearly outlined.
@twentyeightO1
@twentyeightO1 Жыл бұрын
I think to append a node in constant time, we can maintain a tail pointer. So in push() we push new node into head pointer if it's null and make tail equal to heads next, else we push new node into tail and make tail equals to tails next.
@odealianaffairs9001
@odealianaffairs9001 11 ай бұрын
im learning how to code using the cs50 course on youtube and the section about linked lists absolutely stumped me. After watching this tutorial i realized my understanding of the syntax in C was wrong and i finally figured it out. thank you so much.
@manvardhan6982
@manvardhan6982 Жыл бұрын
hey just wanna let u know im watching ur channel since last year and i really appreciate ur content, thx for making quality videos
@wknd3822
@wknd3822 Жыл бұрын
I love these kind of videos from you keep on going. I try to recreate everything you do myself and I leave every of your videos a bit smarter. Thank you a lot keep on going!
@hanspeterbestandig2054
@hanspeterbestandig2054 Жыл бұрын
...that said and hopefully you realized, that his code is full of (partial serious) bugs? 🙄😳 Furthermore, the presence of a lot of *redundant* (with its rendundant bugs) code reveals that this guy has no real practice about programming and hence as an total novice he should not try to teach others in this matter... we’re here in Germany are used to say: “Schuster, bleib‘ bei Deinen Leisten“ 😉
@refeals
@refeals 5 ай бұрын
Man this content takes me back to first year of college, having to create all these different data structures from scratch. Good times. A lot of people using high level languages dont realize how important it is to have a good grasp on how all this works behind the scenes.
@osamaanees8406
@osamaanees8406 Жыл бұрын
Please continue with this series.
@pieter2308
@pieter2308 Жыл бұрын
Very helpful! Everything i see a video from you i will save it so watch is again and again when i need it. Thanks!
@LowLevelLearning
@LowLevelLearning Жыл бұрын
You are welcome!
@maruseron
@maruseron 7 ай бұрын
why are we appending to the front? why are we using void pointers? why are we nesting if + switch instead of using a guard clause or just letting the menu default? we are duplicating mallocs in different branches of addNode, we have a memory leak in removeNode, we're not handling negative values for position NOR EVER MOVING THE CURRENT NODE in insertNode (no wonder it literally doesn't work) this implementation is borderline insane and it's even crazier that you had the balls to upload this
@Y3llowMustang
@Y3llowMustang Жыл бұрын
Love the videos bro, keep it up
@LowLevelLearning
@LowLevelLearning Жыл бұрын
Thanks, will do!
@khroomlet8821
@khroomlet8821 Жыл бұрын
A fun followup to this is a fibonacci heap, which heavily uses linked list concepts but is O(1) for many of its operations!
@yochayken6446
@yochayken6446 Жыл бұрын
You are doing an amazing videos! I would just suggest that if you want to append element in the list you could do it in complexity of O(1) by creating a pointer named “tail” which points to the last node. 😊
@greendog105
@greendog105 Жыл бұрын
what about doing it like this: ``` void ft_lstadd_back(t_node **lst, t_node *new) { t_node *temp; if (!lst || !new) return ; if (!*lst) { *lst = new; return ; } temp = *lst; while (temp->next) temp = temp->next; temp->next = new; } ```
@hanspeterbestandig2054
@hanspeterbestandig2054 Жыл бұрын
Yes at least this video indeed is amazing... ...amazing because of the abundance of serious bugs! Honestly - I don't want to be harsh - but this video is not really a good example to learn software development conscientiously. 🤨See I'm a senior embedded Software Engineer and such (actually simple) code would not have survived a code-review. Seriously! In my opinion this is *not* a good example of how to do clean software development. I'm sorry to say that. Hope he prepares better next time! Remember - a good preparation is 90% of success.
@greendog105
@greendog105 Жыл бұрын
Oh right, my suggestion made no sense, this would not be O(1)
@LoveChaac
@LoveChaac 11 ай бұрын
@@hanspeterbestandig2054 brother it’s possible to come across significantly less arrogant than you did here
@MysteriousFoxy87
@MysteriousFoxy87 7 ай бұрын
@@LoveChaac Not only that, but he didn't even bother pointing out what was wrong...
@darkfire2703
@darkfire2703 Жыл бұрын
I would definitely agree that a programmer should know and be able to implement a linked list but that being said, linked lists are almost never the best solution to a problem. Due to the expensive heap allocations, CPU cache, deref iterations and a bunch of other things linked lists are generally "slow as shit" except in a few very rare cases
@PalladinPoker
@PalladinPoker Жыл бұрын
Sadly true, depending on language 95% of this kind of thing should be array or vector.
@leninalopez2912
@leninalopez2912 Жыл бұрын
Sure and agreed. But is an easy exposition and serves equally well as material for clickbait...
@jeffspaulding9834
@jeffspaulding9834 Жыл бұрын
Depends if performance is your goal. One major advantage of linked lists is that they're dead simple and can be optimized for all kinds of tasks. If I'm in a language that has a decent set of data structures*, then I don't usually use lists. I tend to use them in C because they're quick to write and debug. * Besides Lisp languages, which usually have a full set of data structures but use lists for all kinds of stuff
@darkfire2703
@darkfire2703 Жыл бұрын
@@jeffspaulding9834 A linked list is definitely not simpler than a Array based list / vector. As long as you don't have a rather large list where you constantly remove elements from the middle, a vector is probably faster
@jeffspaulding9834
@jeffspaulding9834 Жыл бұрын
@@darkfire2703 Depends what you're doing with the list. If you're adding and removing from both ends, a linked list is simpler than an array. As far as faster, I don't debate that.
@johngeverett
@johngeverett 5 ай бұрын
I have a task manager app that I implement in any new language i learn. It uses doubly linked lists with sub-lists available for any task. It puts me through tha paces of multiple features of any language: Data structures, pointers, memory allocation, functions, classes (if OOP), file I/O, user interface.
@CarloCattano
@CarloCattano Жыл бұрын
Loving this videos. This one helped me internalize more what I've been learning at 42 School. Could you give a try to lists with void type data? That's where it gets messy real quick for me
@zenhdn3580
@zenhdn3580 Жыл бұрын
Greeting From Venezuela I've learned alot with you through this couple of years. Thx for all
@houssem009
@houssem009 Жыл бұрын
This new video format is amazing!
@LowLevelLearning
@LowLevelLearning Жыл бұрын
Glad to hear it!
@zxuiji
@zxuiji 5 ай бұрын
1:11, If you do this with offset pointers instead you can also keep the benefits of a buffer (access by index), something like: link = head + link->next will get you the next link in this scenario. UX side you still need to loop through the remaining list items to update their positions (not their indices, the ordered positions as far as the user is concerned) when you add/remove items but that's still much cheaper than actually moving every item in the list. Since both index and position can be attached to UX elements and only the position reported to the user you can just grab the index/offset (depends which you stored, both can be converted to the other using sizeof(link)) and add that back to the head element to get the intended link. Comes at the cost of memory but I'd argue speed is more worthwhile in all cases for this particular case.
@richardericlope3341
@richardericlope3341 Жыл бұрын
I was once forced to implement a cyclic singly linked list for a game I made in a fairly new language called freebasic. It was in its beta stage so you pretty had to code everything. It was a nice mind exercise too.
@daggerone3370
@daggerone3370 Жыл бұрын
Simple and to the point, nice video.
@yt-sh
@yt-sh Жыл бұрын
we need more of these!
@Noodle999
@Noodle999 5 ай бұрын
I've never done a huge amount of C so I was secretly proud of myself that I spotted the bug you found at ~20:08, when you originally typed it.
@alexandrohdez3982
@alexandrohdez3982 Жыл бұрын
Easy to understand, please continue Binary Trees and then Graphs 😉👏👏👏. It would be usefull that you explain in which situations you have used those data structures in your projects. Thank you 💪
@hanspeterbestandig2054
@hanspeterbestandig2054 Жыл бұрын
Sorry I have to disagree. This code is a pure mess and full of serious bugs! Didn't you recognise this? 🥺😮‍💨 Well, I hope he prepares better next time! ... and I hope he realizes his responsibility to his 156k subscribers to want to teach people something solid here.
@zxuiji
@zxuiji Жыл бұрын
1:08, the last node doesn't have to point to NULL, NULL is just an easy exit condition but you can also just check the pointer you have does not match the one you started with, this allows the option of a semi-permanent loop that doesn't check for said match since it only needs to process the nodes, this is particularly useful if you 're making a multiplayer game or even just physics, the players/"actors" would be nodes that need their position constantly updated even if they're not rendered during the update, a linked list of nodes that circles on itself would allow the loop to be optimised to just check for game exit instead of both that and a NULL pointer
@VojtaJavora
@VojtaJavora Жыл бұрын
This is also how Linux kernel organizes tasks
@glennmiller394
@glennmiller394 Жыл бұрын
I use extra pointers. One for the last and one for the previous. It allowed me to walk forward or backward and I didn't have to walk the list to get to the end. It was especially helpful for large lists. The code to keep the pointers current is less than one might expect.
@SomeSubhuman
@SomeSubhuman Жыл бұрын
That’s not singly linked.
@thev01d85
@thev01d85 Жыл бұрын
If you have very large lists you should either: a) Consider using a different data structure, maybe a map or self-balancing BST. It really depends on what you're doing b) Doubly linked skip list, requires a sorted list of course.
@glennmiller394
@glennmiller394 Жыл бұрын
@@thev01d85 I first worked with linked lists in the early 80s in a business environment. They served most purposes.
@thev01d85
@thev01d85 Жыл бұрын
@@glennmiller394 So... you're telling me linked lists are good for large sets of data because you used them a long time ago?
@glennmiller394
@glennmiller394 Жыл бұрын
@@thev01d85 I wrote my first linked list in C in 1986. I haven't written one lately using C++. It provides functionality to avoid that.
@mathiasdreke180
@mathiasdreke180 4 ай бұрын
Back in the days in the year 2000, I learned that in 11. grade at high school using Turbo Pascal. We had a really good computer science teacher then. We also learned to make tree structures in similar way....including sort and search functionality. I suppose such things are not tought in high school anymore since very few teachers know that stuff.
@japroz
@japroz Жыл бұрын
Kudos on the LLL animation! It's really amazing
@LowLevelLearning
@LowLevelLearning Жыл бұрын
only took me 5 sweaty hours in adobe after effects LOL
@japroz
@japroz Жыл бұрын
@@LowLevelLearning worth it!
@nothingbshr5590
@nothingbshr5590 Жыл бұрын
Great video, thank you !!!
@EUPThatsMe
@EUPThatsMe 5 ай бұрын
So much of the data structure education I got in school went out the window when I got into embedded where node count (or maximum node count) is part of the design so it just becomes predefined array
@jurekrasovec
@jurekrasovec Жыл бұрын
at 8 minute, you allocated a new Node object, and then later on set the "next" variable to NULL. It works in your case, but for real life cases it is strongly suggested (at least from my view) that you do a memset(new, 0x00, sizeof(Node));
@iDontProgramInCpp
@iDontProgramInCpp Жыл бұрын
Ironically I think that doubly linked lists are faster if you have a pointer to a specific node, since you can do it in O(1) time by simply connecting node->prev with node->next and updating the heads, rather than having to go through the whole list again to find the previous element which points back there. Addition to both heads is also O(1) if you keep track of them. *By O(1) I mean that their execution time is constant as the data set's size increases, since they're operations where you don't need to create any loops, instead simply manipulating a few pointers.
@stephenreaves3205
@stephenreaves3205 Жыл бұрын
When you decrement position in the insert function, you aren't moving the current pointer
@semicharmedkindofguy3088
@semicharmedkindofguy3088 Жыл бұрын
haha love that realization at 11:23 that your code is gonna crash, then being surprised that you actually wrote the correct code the first time around. Relatable feeling.
@roslinked
@roslinked Жыл бұрын
I use technology every day, and in the background; all of this code is running. Someone sat for hours, days, weeks, even months and years in some cases, to create the code for all of it to happen and work without bugs. It's crazy to think about it in terms like that and I guess programmers are really sort of the unsung hero's of the technological age. Thank you!
@EVL624
@EVL624 Жыл бұрын
For the add method, is it really necessary to separate between and empty list and a non-empty list? Is it not enough to do what you do for the non-empty case in both of the cases, since head == NULL, and therefore new->next = head is the same as new->next = NULL?
@nehrilisoruz8182
@nehrilisoruz8182 4 ай бұрын
Thanks ! That's a very cool video 👌
@m4rt_
@m4rt_ 4 ай бұрын
Though if you want a thing with dynamic size, you could make a dynamic array. It isn't that hard to do. You just need a structure with a pointer, the count, and the max size, and if you want to add to the array and the new size will be larger than the allocated space, you just use realloc and decide on how much to increase it (you could double it until you have enough, you could add some number to it until you have enough, or you could do some clever math, it's up to you.) Then maybe consider shrinking it if you don't need all that space anymore. The advantage of using a dynamic array instead of a linked list is that you have all the data in one place instead of scattered all over the place (unless you use an arena allocator or something), also the data will be easier to traverse, and you may need less allocations if you do it right. Though the linked list has one advantage... you can quickly and easily remove a single element in the middle of the list. If you want to try it out, try making a string that you can print, append to, remove stuff from, etc.
@qowkerf
@qowkerf Жыл бұрын
A fun challenge to expand on this video is indexing the list. Give the node struct an index integer. Makes it easier to reach a certain element n by just reading the index. It also completely changes how you add, remove or insert elements into the list, since all indexes from that point on have to be adjusted.
@theRPGmaster
@theRPGmaster Жыл бұрын
This is a good reason to allocate it contiguously, then the pointer for the index becomes: root node pointer + size of node * index. This is much faster than jumping through the links, but of course, it goes against the point of having a linked list to begin with (why have next-pointers at all if the nodes are already right next to each other in memory, AKA an array).
@qowkerf
@qowkerf Жыл бұрын
@@theRPGmaster Yup. Although one could argue that the point of linked lists in C in the first place is simply to have dynamic arrays.
@MikeM8891
@MikeM8891 Жыл бұрын
Me: Seems easy enough, I'll code it up in Rust real quick. Rust: Imma about to end this man's whole career.
@keatonhatch6213
@keatonhatch6213 Жыл бұрын
To anyone reading the head pointer is the front of the list. He said it correctly at first then when testing the add function he switched his definition implying the head pointer was at the end, and then switched it back correctly when testing the insert function. This might be confusing for people trying to learn.
@agustinvalenzuela5242
@agustinvalenzuela5242 8 ай бұрын
Hi, one question why arent you changing *current in the while loop of the "insertNode" function? I think that the function is inserting the node in the same place every time, after the *head. Havent ran the code before but i think this is the way of doing it: while (current != NULL && position != 0) { current = current->next; position--; } Thanks for the video.
@hatkidchan_
@hatkidchan_ Жыл бұрын
Also you could use `typedef struct node { struct node *next; int data; } Node;` to make life much, much easier when going certain number of nodes forward (`some_node->next->next->next`) without casting it to `Node` every time
@Daniel_Zhu_a6f
@Daniel_Zhu_a6f 6 ай бұрын
one should probably use array instead (i know only 2 very specific cases where linked lists are better, sort of). arrays are also quite flexible: you can have a "fat pointer" or store header directly on the array, you can have capacity variable to reduce allocations or you can have no extra capacity and prioritize space efficiency. arrays are far better than linked lists for pushing a new element to the end and popping last element (because they normally don't need new allocations for that), they have fast access and sorting and so on. even insert in the middle of array is often faster than insert in the middle of a linked list (modern chips are good at copying contiguous chunks of memory).
@HudaDemirtas
@HudaDemirtas Жыл бұрын
hey man, mind telling me what font is your vc code?
@euglossine4ever
@euglossine4ever Жыл бұрын
Excellent video❤
@BubblegumChewer
@BubblegumChewer Жыл бұрын
What do you use to draw on screen? Are you using a touch screen laptop or a separate wacom tablet thing?
@igorthelight
@igorthelight Жыл бұрын
What about just using a mouse? ;-)
@Koroistro
@Koroistro 7 ай бұрын
He said it 7 seconds into the video, that's impressive. Usually titles like that wait until the 75% mark to do that :_D (love the content btw)
@rafaelveronezi8730
@rafaelveronezi8730 10 ай бұрын
There's an issue with the insertion code, it's missing an instruction on the initial loop to update the `current` reference, just like that: while (current != NULL && position != 0) { position--; current = current->next; } Without this, the code will just run down the position, but the item will always be inserted as the next from the head, since the current never changes. Other than that pretty cool video, thank you!
@XenoTravis
@XenoTravis 6 ай бұрын
Thank you for making sure I am not crazy! I was thinking that. He doesn't ever check any other positions other than the case it works.
@alexaneals8194
@alexaneals8194 7 ай бұрын
I like the use of the void*. In the past, I have always typedef a Node ahead of defining it and used Node* in the Node. However, the void* makes more sense.
@31redorange08
@31redorange08 Жыл бұрын
The Rust docs say that using a linked list is very rarely appropriate.
@wreckt_sigma9942
@wreckt_sigma9942 Жыл бұрын
Can you not use a external script to define main() so you would not need so many parameters and everything else at once?
@null_carrier
@null_carrier Жыл бұрын
If only I had your content available 12 years ago on my CS course...
@Entropy67
@Entropy67 Жыл бұрын
Usually when I make my linked lists I make a struct representing the entire list with a pointer to both the head and the tail, allows for o(1) adding and removal from both ends of the list ;)
@igorthelight
@igorthelight Жыл бұрын
You could do that but that costs additional memory - everything ha it's costs ;-)
@annguyenhoangphu451
@annguyenhoangphu451 Жыл бұрын
In the insertNode function, the while loop doesn't update current node so when insert you will all way insert into position 0 (right after the head node). I think you should add current = current->next inside that loop. Edit: It should be like this while(current != NULL && --position != 0){ current = current->next; }
@navadeep.ganesh
@navadeep.ganesh Жыл бұрын
This is true. I was wondering about it and cross checked w GitHub code. Seems same there and updating the current makes it perfect! Thanks for putting that up.
@aculleon2901
@aculleon2901 Жыл бұрын
Thanks I was wondering how it went over the list. It only worked when pos = 0 which was the only thing tested.
@steamrangercomputing
@steamrangercomputing Жыл бұрын
I highly recommend programming on the Amiga. Most of the operating system works on linked lists.
@GlobalYoung7
@GlobalYoung7 Жыл бұрын
thank you❤
@AUsernameTooMany
@AUsernameTooMany 4 ай бұрын
In AddNode, the malloc, NULL check and data assignment should all be above the if statement. Code duplication can lead to errors if one copy is changed and the other is not.
@filmamundo9194
@filmamundo9194 5 ай бұрын
i am new to c. Shouldnt head in the add function be a pointer to a pointer as its equal to new, which is a pointer?
@xMinoYTx
@xMinoYTx 2 ай бұрын
Is it important to put `return` at the end of the printMenu function, even if it's void?
@pup4301
@pup4301 Жыл бұрын
I use super traits in rust with get and any functions to make this work.
@rolling_marbles
@rolling_marbles 7 ай бұрын
15:55 I was just screaming at my TV “Memory Leak!”
@zxuiji
@zxuiji Жыл бұрын
6:20, nope, not necessary, you can maintain 2 types of lists for the same nodes, one is a simple array of pointers to nodes int the order they are declared to be, the other is the linked list, when you want to append a node you select the last node pointer in the array and just set it's next value to the new pointer and add the new pointer to the end of the list (increasing the count while you're at it), when removing by index you load the node from the pointer list and make the nodes it's linked to link to each other instead, then you shift the pointers in the list up 1 and iterate through them all to correct their stored index, when inserting you likewise load the node already stored at said index and set the new pointers next to that node and update the previous node it was connected to, sure this method is a little more memory hogging but in most cases that is less an issue than the speed
@max1point8t
@max1point8t 2 ай бұрын
They are also a fantastic way for people to get comfortable with recursion, as any algorithm for a recursive data strucutre can be implented with a recursive algorithm.
@minilathemayhem
@minilathemayhem 4 ай бұрын
Red-black tree best data structure >.> I've always liked how understanding singly-linked lists is essential to implement most other data structures, tbh. A lot of them are extremely similar in concept to a linked list.
@MrHolliday4434
@MrHolliday4434 Жыл бұрын
What are some good sources to learn C?
@jimrhea5484
@jimrhea5484 5 ай бұрын
While all the other physicist were specializing in their field, Einstein was specializing in none but watching all. It resulted in general relativity. To see someone so good that they can deduce so many coding disciplines reminds me of what Einstein did there.
@guilherme5094
@guilherme5094 Жыл бұрын
👍Thanks!
@christophergodawski5663
@christophergodawski5663 Жыл бұрын
I'll fire up the old LISP machine and give it a try !😄
@shaohengguan1657
@shaohengguan1657 4 ай бұрын
nice! but I have to say there is an error in the function insert node function. the current node pointer is not changed in the while loop. one line should be added into the while loop to update the current pointer to the position where to add the new node: current = current->next;
@rafagd
@rafagd Жыл бұрын
Linked lists are a great exercise on how to use pointers, but they are also old data structures that do not work very well in modern computer architectures. They are relics of the past and have very few remaining use-cases where they are superior to vector-style arrays, even taking into account the reallocation+move times.
@raianmr2843
@raianmr2843 Жыл бұрын
Linked List is the Latin of data structures. It exists by being dissolved into other, more complex and useful data structures like LFU caches for example.
@IBelieveInCode
@IBelieveInCode Жыл бұрын
"they are also old data structures that do not work very well in modern computer architectures." Cache locality issues ?
@dagoberttrump9290
@dagoberttrump9290 Жыл бұрын
Sometimes they're still the right tool my man. E.g. what do you do if the list items are not movable or copyable?
@federicosalvetti7703
@federicosalvetti7703 Жыл бұрын
Super tutorial, I am now learning to handle frees with new best friend Valgrind.I have a question: what are the actual use cases for linked lists in a real world program? I am only learnig the basics now but I would like to know when Is the best and optional situation for when to use them, especially considering performance and fastness of the program one is writing. Probably It would make a nice video this topic, but thanks in advance for the answer!
@az-kalaak6215
@az-kalaak6215 Жыл бұрын
Hi! in real world, it is quite rare to use a real linked list as it is quite slow (huge allocation overhead). However, you can cheat to remove this slowness. In c++, if I remember correctly, the std::deque is a linked list of enormous arrays, meaning you have to allocate array after array without having a really big allocation issue. I think of it more of a way to extend an existing array rather than being the sole container. same language, still c++, std::vector (allocated array) is almost always faster than std::list. However, when you have to keep references (or pointers) to the object, linked list are actually the best. if you remove a node from the list, it only invalidates the pointers (or iterators) to the specific node. same goes if you ever add a node. If you ever need to keep huge quantity of pointers to members of an array which could reallocate at anytime, I would suggest using a linked list if the array is not in a critical chokepoint. Still the same pattern though, one allocation for a pool of nodes I would pick from to reduce performances drop. You could still have better performances with an array, however the code required to make it work would probably require way more memory. In production code, I actually never used linked list in its pure form (std::list) but used them in the hidden form (std::deque).
@tommasoriconda8845
@tommasoriconda8845 4 ай бұрын
Sorry I'm just watching the video and checking the code and I'm a bit confused.. On the InsertNode method, inside the while loop u're decrementing position without setting current to current->next, in this way whatever position you receive, current just points to head without moving... or am I wrong?
@diandradeeke
@diandradeeke 5 ай бұрын
what is the difference between linked lists and the list-object? As far as i can see they both have the same funcionality
@Freakhealer
@Freakhealer Ай бұрын
Why at 9:00 you repeat the start of both if conditions while you could do it outside the if statement once?
@Leonhart_93
@Leonhart_93 3 ай бұрын
Good for theoretic implementation and understanding of pointers, bad for practical applications minus few isolated edge cases. Even the creator of C said that arrays are better in any way as you don't need to traverse them to get to a certain element.
@skeleton_craftGaming
@skeleton_craftGaming Жыл бұрын
If you're going to make bigger projects, did you c++ and and C++ std::vector because vector doesn't sig fault if you are handed invalid user input.
@MeredyFT
@MeredyFT Жыл бұрын
Can u help us how to set C on Vs studio? I am a new programmer and i am learning, but i am lost using VS studio
@filipemelo1107
@filipemelo1107 5 ай бұрын
I am kinda confused with the "head" being the latest added item on the list (behaving like a stack maybe?)
@__hannibaalbarca__
@__hannibaalbarca__ Жыл бұрын
Can we make heterogeneous data structure linked list like : Object1->object2->…->objectn with void* pointer rather than typed pointer ,
@mikefochtman7164
@mikefochtman7164 Жыл бұрын
Just a comment, your addNode() function doesn't really need that if-check. If you delete the first condition completely and just use the code from the 'else' condition, it will always work. If head is NULL, it gets updated the same as if head is pointing to a valid node. So the 'next' value can always be assigned the value in 'head' and then update head. (and since 'head' has either NULL or a valid pointer, you don't really need to initialize new->next to NULL before executing the rest of the code).
@FreshSmog
@FreshSmog Жыл бұрын
What is the issue at 8:36 that you need to move node * x = NULL, before malloc?
@igorthelight
@igorthelight Жыл бұрын
The issue is that you can't "return new;" because it's out of scope. Try and you will se by yourself ;-)
@Yupppi
@Yupppi 7 ай бұрын
This was cool. This all manual pointer handling in C is very confusing compared to the simplicity of use of C++.
@Panure
@Panure Жыл бұрын
My favorite data structure is the hashtable 😳
@felipebaquero9975
@felipebaquero9975 5 ай бұрын
@LowLevelLearning Thank you very much for all the amazing content you make. I would like to point out that the insertNode function in your example does not work as intended, below is the corrected implementation: Node* insertNode(int value, int position){ Node* new = malloc(sizeof(Node)); if (new == NULL) { printf("Memory allocation failed "); return NULL; } new->value = value; new->next = NULL; if (position == 0) { new->next = head; head = new; return new; } Node* current = head; Node* previous = NULL; while (current != NULL && position > 0) { previous = current; current = current->next; position--; } if (position > 0) { printf("Requested position too far into the list "); free(new); return NULL; } new->next = current; previous->next = new; return new; }
@nikitablack1568
@nikitablack1568 Жыл бұрын
What's the point of the 'while' loop in the 'insertNode' function? It just decreases the position until it reaches 0, you never modify the 'current' pointer and you don't cover this in your test. Also, the signed integer is not a right choice here - passing '-1', for example, can be very bad.
@petevenuti7355
@petevenuti7355 Жыл бұрын
What does the double asterisk mean in the second parameter of main and why does main need parameters here?
@janb.9425
@janb.9425 Жыл бұрын
That is a pointer to a pointer to a char. Meaning it stores the address of a pointer to char which itself stores the address of a char. It is used to store an array of strings that can be accessed using only a single variable. The ammount of strings is stored in the first argument. char *argv[] would be equivalent (since the compiler turns it into the other version automatically), but shows better what is happening. In case you don't know those strings are usually what you write behind the name of the executable which looks about like this: executable arg1 arg2 arg3 ... argN The name and path of the executable are usually given as the first argument automatically.
@petevenuti7355
@petevenuti7355 Жыл бұрын
@@janb.9425 Well I can't believe I never knew that, there's always more than one way to skin a cat...
@HeWhoProclaims
@HeWhoProclaims Жыл бұрын
When trying to see if you can get your code to run the first time, you get an error and say, "Go ahead and include standard libs." Then you copy the text . Then you open a new terminal and are able to run the command again but without the errors. What are you doing here? I don't know how you got it running without an error and that's where I'm stuck at.
@chielvoswijk9482
@chielvoswijk9482 Жыл бұрын
(A bit late, but for those curious) He used: #include This command tells the compiler to include another file in compilation. The one in question being stdlib.h. often called the "Standard Library". Without it you don't have easy access to commonly used stuff like memory allocation, random numbers and converting variables. There are also other libraries like which gives you mathmatical functions like cos, sin, floor, log, etc. Libraries are an important element of coding stuff you don't know how to do from scratch yourself and provide many shortcuts. Especially in embedded systems do we use libraries a LOT to make interacting with certain things a lot less headache inducing!
@4115steve
@4115steve 10 ай бұрын
I want to see all the most popular data structures used
@dodgeclub7162
@dodgeclub7162 Ай бұрын
Do he created stack instead of linked list
@YasserCherfaoui
@YasserCherfaoui Жыл бұрын
I remember this topic was an exercise in my C programming class exam. there were like 11.5/20 points for this exercise, I had 16.5/20 final mark. I don't remember how did I do it, but you refreshed my memory, thank you sir!
you need to stop using print debugging (do THIS instead)
7:07
Low Level Learning
Рет қаралды 404 М.
why do void* pointers even exist?
8:17
Low Level Learning
Рет қаралды 318 М.
КАРМАНЧИК 2 СЕЗОН 6 СЕРИЯ
21:57
Inter Production
Рет қаралды 505 М.
Cute Barbie Gadget 🥰 #gadgets
01:00
FLIP FLOP Hacks
Рет қаралды 37 МЛН
Заметили?
00:11
Double Bubble
Рет қаралды 3,4 МЛН
10 Key Data Structures We Use Every Day
8:43
ByteByteGo
Рет қаралды 323 М.
3 Types of Algorithms Every Programmer Needs to Know
13:12
ForrestKnight
Рет қаралды 440 М.
Native JSON in OTP 27! (Elixir, Erlang, Gleam)
2:03
Code & Stuff
Рет қаралды 1 М.
How principled coders outperform the competition
11:11
Coderized
Рет қаралды 1,5 МЛН
microsoft's new AI feature is an absolute dumpster fire
9:34
Low Level Learning
Рет қаралды 59 М.
Why Linked Lists vs Arrays isn’t a real choice
9:15
SimonDev
Рет қаралды 306 М.
everyone codes faster when they stop using their mouse
10:32
Low Level Learning
Рет қаралды 191 М.
8 Design Patterns EVERY Developer Should Know
9:47
NeetCode
Рет қаралды 1 МЛН
you will never ask about pointers again after watching this video
8:03
Low Level Learning
Рет қаралды 2 МЛН
Pratik Cat6 kablo soyma
0:15
Elektrik-Elektronik
Рет қаралды 8 МЛН
#miniphone
0:16
Miniphone
Рет қаралды 918 М.
Дени против умной колонки😁
0:40
Deni & Mani
Рет қаралды 10 МЛН
Will the battery emit smoke if it rotates rapidly?
0:11
Meaningful Cartoons 183
Рет қаралды 4,5 МЛН