From 2d02da3e2e2fd957d7453d1fe0655925b06534ad Mon Sep 17 00:00:00 2001 From: mustakimur khandaker Date: Mon, 7 Feb 2022 22:01:52 -0500 Subject: [PATCH] new exercise to practice struct and ownership --- exercises/doubly_linked_list/README.md | 281 +++++++++++++++++++++++++ exercises/doubly_linked_list/dlist.rs | 83 ++++++++ info.toml | 6 + 3 files changed, 370 insertions(+) create mode 100644 exercises/doubly_linked_list/README.md create mode 100644 exercises/doubly_linked_list/dlist.rs diff --git a/exercises/doubly_linked_list/README.md b/exercises/doubly_linked_list/README.md new file mode 100644 index 00000000..efdea746 --- /dev/null +++ b/exercises/doubly_linked_list/README.md @@ -0,0 +1,281 @@ +Implement a doubly linked list similar to the following: + +```c +#include +#include +#include +#include + +struct node { + int data; + int key; + + struct node *next; + struct node *prev; +}; + +//this link always point to first Link +struct node *head = NULL; + +//this link always point to last Link +struct node *last = NULL; + +struct node *current = NULL; + +//is list empty +bool isEmpty() { + return head == NULL; +} + +int length() { + int length = 0; + struct node *current; + + for(current = head; current != NULL; current = current->next){ + length++; + } + + return length; +} + +//display the list in from first to last +void displayForward() { + + //start from the beginning + struct node *ptr = head; + + //navigate till the end of the list + printf("\n[ "); + + while(ptr != NULL) { + printf("(%d,%d) ",ptr->key,ptr->data); + ptr = ptr->next; + } + + printf(" ]"); +} + +//display the list from last to first +void displayBackward() { + + //start from the last + struct node *ptr = last; + + //navigate till the start of the list + printf("\n[ "); + + while(ptr != NULL) { + + //print data + printf("(%d,%d) ",ptr->key,ptr->data); + + //move to next item + ptr = ptr ->prev; + + } + +} + +//insert link at the first location +void insertFirst(int key, int data) { + + //create a link + struct node *link = (struct node*) malloc(sizeof(struct node)); + link->key = key; + link->data = data; + + if(isEmpty()) { + //make it the last link + last = link; + } else { + //update first prev link + head->prev = link; + } + + //point it to old first link + link->next = head; + + //point first to new first link + head = link; +} + +//insert link at the last location +void insertLast(int key, int data) { + + //create a link + struct node *link = (struct node*) malloc(sizeof(struct node)); + link->key = key; + link->data = data; + + if(isEmpty()) { + //make it the last link + last = link; + } else { + //make link a new last link + last->next = link; + + //mark old last node as prev of new link + link->prev = last; + } + + //point last to new last node + last = link; +} + +//delete first item +struct node* deleteFirst() { + + //save reference to first link + struct node *tempLink = head; + + //if only one link + if(head->next == NULL){ + last = NULL; + } else { + head->next->prev = NULL; + } + + head = head->next; + //return the deleted link + return tempLink; +} + +//delete link at the last location + +struct node* deleteLast() { + //save reference to last link + struct node *tempLink = last; + + //if only one link + if(head->next == NULL) { + head = NULL; + } else { + last->prev->next = NULL; + } + + last = last->prev; + + //return the deleted link + return tempLink; +} + +//delete a link with given key + +struct node* delete(int key) { + + //start from the first link + struct node* current = head; + struct node* previous = NULL; + + //if list is empty + if(head == NULL) { + return NULL; + } + + //navigate through list + while(current->key != key) { + //if it is last node + + if(current->next == NULL) { + return NULL; + } else { + //store reference to current link + previous = current; + + //move to next link + current = current->next; + } + } + + //found a match, update the link + if(current == head) { + //change first to point to next link + head = head->next; + } else { + //bypass the current link + current->prev->next = current->next; + } + + if(current == last) { + //change last to point to prev link + last = current->prev; + } else { + current->next->prev = current->prev; + } + + return current; +} + +bool insertAfter(int key, int newKey, int data) { + //start from the first link + struct node *current = head; + + //if list is empty + if(head == NULL) { + return false; + } + + //navigate through list + while(current->key != key) { + + //if it is last node + if(current->next == NULL) { + return false; + } else { + //move to next link + current = current->next; + } + } + + //create a link + struct node *newLink = (struct node*) malloc(sizeof(struct node)); + newLink->key = newKey; + newLink->data = data; + + if(current == last) { + newLink->next = NULL; + last = newLink; + } else { + newLink->next = current->next; + current->next->prev = newLink; + } + + newLink->prev = current; + current->next = newLink; + return true; +} + +void main() { + insertFirst(1,10); + insertFirst(2,20); + insertFirst(3,30); + insertFirst(4,1); + insertFirst(5,40); + insertFirst(6,56); + + printf("\nList (First to Last): "); + displayForward(); + + printf("\n"); + printf("\nList (Last to first): "); + displayBackward(); + + printf("\nList , after deleting first record: "); + deleteFirst(); + displayForward(); + + printf("\nList , after deleting last record: "); + deleteLast(); + displayForward(); + + printf("\nList , insert after key(4) : "); + insertAfter(4,7, 13); + displayForward(); + + printf("\nList , after delete key(4) : "); + delete(4); + displayForward(); +} +``` + +Instead of maintaining head, last, and current in the global; maintain them inside main() and send them as reference to the functions, as required. Feel free to change function arguments as required. \ No newline at end of file diff --git a/exercises/doubly_linked_list/dlist.rs b/exercises/doubly_linked_list/dlist.rs new file mode 100644 index 00000000..be371bd9 --- /dev/null +++ b/exercises/doubly_linked_list/dlist.rs @@ -0,0 +1,83 @@ +/* define your structure here + + +*/ + +fn isEmpty(???) -> bool { + +} + +fn length(???, ???) -> i32 { + +} + + +fn displayForward(???) { + +} + +fn displayBackward(???) { + +} + +fn insertFirst(???, key: i32, data: i32) { + +} + +fn insertLast(???, key: i32, data: i32) { + +} + +fn deleteFirst(???, ???) -> ???{ + +} + + +fn deleteLast(???, ???) -> ??? { + +} + +fn delete(???, ???, ???, key: i32) -> ??? { + +} + +fn insertAfter(???, ???, ???, key: i32, newKey: i32, data: i32) -> bool{ + +} + +void main() { + /* declare your nodes here for head, last, and current + + + */ + + insertFirst(???, 1, 10); + insertFirst(???, 2, 20); + insertFirst(???, 3, 30); + insertFirst(???, 4, 1); + insertFirst(???, 5, 40); + insertFirst(???, 6, 56); + + println!("\nList (First to Last): "); + displayForward(???); + + println!("\n"); + println!("\nList (Last to first): "); + displayBackward(???); + + println!("\nList , after deleting first record: "); + deleteFirst(???, ???); + displayForward(???); + + println!("\nList , after deleting last record: "); + deleteLast(???, ???); + displayForward(???); + + println!("\nList , insert after key(4) : "); + insertAfter(???, ???, ???, 4, 7, 13); + displayForward(???); + + println!("\nList , after delete key(4) : "); + delete(???, ???, ???, 4); + displayForward(???); +} \ No newline at end of file diff --git a/info.toml b/info.toml index 10a1aec1..0a9bce6f 100644 --- a/info.toml +++ b/info.toml @@ -1053,4 +1053,10 @@ hint = "" name = "palindrome" path = "exercises/palindrome/palindrome.rs" mode = "compile" +hint = "" + +[[exercises]] +name = "doubly-linked-list" +path = "exercises/doubly_linked_list/dlist.rs" +mode = "compile" hint = "" \ No newline at end of file