double linked list with c - c

ok, now i have to make double linked list on c.
there are 7 functions which act on main.
append.
insertAt.
deleteAt.
print.
print_revers.
newnode.
newDLL.
i can amend only 5 functions
append, insertAt, deleteAt, print, print_reverse
finally i can make append,print,print_reverse
however, i can't make insertAt,deleteAt, because of index.
1. i can't understand why the code
else {
while (index-- >= 0) {
temp = temp->next;
}
make memory collide. for using index, i need to move node to collect position and connect to newnode. but it doesn't work...
2. also what's return; 's role? i have not seen such type of return.
3. how can i make deleteAt using index? i think deleteAt and insertAt have quiet similar algoritum. so i try to make insertAt first and deleteAt last. but what i write doesn't work well..
i can find a lot of data of doublelinkedlist on internet. but i can't find using index.... i have been listening c language lecture on only two month, so sorry about the spagettii code...
#include <stdio.h>
#include <stdlib.h>
typedef struct Node {
int val;
struct Node *prev;
struct Node *next;
} Node;
typedef struct {
Node *head;
int size;
} DLL;
Node *newnode(int n)
{
Node *temp = (Node *)malloc(sizeof(Node));
temp->val = n;
temp->prev = NULL;
temp->next = NULL;
return temp;
}
DLL *newDLL() {
DLL *temp = (DLL *)malloc(sizeof(DLL));
temp->head = NULL;
temp->size = 0;
return temp;
}
void append(DLL *list, Node *newnode) {
struct Node* temp = list->head;
struct Node* newNode = newnode;
if (list->head == NULL) {
list->head = newNode;
list->size++;
return;
}
while (temp->next != NULL) {
temp = temp->next;
}
list->size++;
temp->next = newNode;
newNode->prev = temp;
}
void insertAt(DLL *list, int index, Node *newnode) {
struct Node* temp = (Node *)malloc(sizeof(Node));
if (index < 0 || index >= list->size + 1) {
printf("out of range\n");
}
else if (index == 0) {
newnode->next = list->head;
list->head->prev = newnode;
list->head = newnode;
}
else {
while (index-- >= 0) {
temp = temp->next;
}
temp->val = newnode->val;
temp->next = list->head->next;
list->head->next = temp;
temp->prev = list->head;
if (temp->next != NULL)
temp->next->prev = temp;
}
}
void deleteAt(DLL *list, int index) {
//save reference to first link
struct Node* temp = (Node *)malloc(sizeof(Node));
//if only one link
if (list->head->next == NULL) {
list->head->prev = NULL;
}
else {
list->head->next->prev = NULL;
}
list->head = list->head->next;
//return the deleted link
return;
}
void print(DLL *list) {
struct Node* temp = list->head;
printf("Forward: ");
while (temp != NULL) {
printf("[%d] ", temp->val);
temp = temp->next;
}
printf("\n");
}
void print_reverse(DLL *list) {
struct Node* temp = list->head;
if (temp == NULL) return; // empty list, exit
// Going to last Node
while (temp->next != NULL) {
temp = temp->next;
}
// Traversing backward using prev pointer
printf("Reverse: ");
while (temp != NULL) {
printf("[%d] ", temp->val);
temp = temp->prev;
}
printf("\n");
}
int main() {
DLL *list = newDLL();
int i;
for (i = 1; i < 6; i++) {
append(list, newnode(i));
}
print(list);
deleteAt(list, -1);
deleteAt(list, 5);
deleteAt(list, 0);
print(list);
deleteAt(list, 2);
print(list);
deleteAt(list, 2);
print(list);
insertAt(list, -1, newnode(6));
insertAt(list, 3, newnode(6));
insertAt(list, 0, newnode(7));
print(list);
insertAt(list, 1, newnode(8));
print(list);
insertAt(list, 4, newnode(9));
print(list);
print_reverse(list);
return 0;
}

The part where you insert at index has problems:
temp = malloc is wrong, it should start with temp = head.
in the insertion:
temp->val = newnode->val;
temp->next = list->head->next;
list->head->next = temp;
temp->prev = list->head;
temp->next should not be head->next, it should be newnode. newnode->next should be temp->next etc.

Related

Deleting elements with largest values from linked list

I have a problem with deleting elements with greatest values from doubly linked list. It seems that my program works fine with only one greatest number in the list. However, if the list contains two greatest numbers (as an example, last two list's elements are greatest numbers), the program crashes. I am sure my management of nodes' adresses is not correct.
EDIT: I was ment to say the "greatest" values just in case if the word "largest" mistakens.
Here's my code:
#include <stdio.h>
#include <stdlib.h>
typedef struct node
{
struct node* prev;
int value;
struct node* next;
} node;
node* allocateNode(int value);
node* addToEnd(node* head, int value);
node* makeList(node* head, int n);
node* deleteMaxElement(node* head);
void freeMemory(node* head);
int main()
{
node* head = NULL;
int n = 0;
printf("Enter number of elements: ");
if (!(scanf("%d", &n) == 1))
return 0;
head = makeList(head, n);
head = deleteMaxElement(head);
if (n > 1)
{
node* element = head;
printf("%d ", element->value);
while(element->next != NULL)
{
element = element->next;
printf("%d ", element->value);
}
printf("\n");
freeMemory(head);
}
return 0;
}
node* makeList(node* head, int n)
{
int value = 0;
if (n == 0)
return head;
printf("Enter value of 1 node: ");
if (scanf("%d", &value) == 1)
{
head = allocateNode(value);
for (int i = 1; i < n; i++)
{
printf("Enter value of %d node: ", i + 1);
if(scanf("%d", &value) == 1)
head = addToEnd(head, value);
}
}
return head;
}
node* allocateNode(int value)
{
node* newNode = (node*)malloc(sizeof(node));
newNode->prev = NULL;
newNode->next = NULL;
newNode->value = value;
return newNode;
}
node* addToEnd(node* head, int value)
{
node* newNode = allocateNode(value);
node* element = head;
while (element->next != NULL)
element = element->next;
element->next = newNode;
newNode->prev = element;
return head;
}
node* deleteMaxElement(node* head)
{
int max = head->value;
node* element = head;
// finds max element in list
while (element->next != NULL)
{
element = element->next;
if (element->value > max)
max = element->value;
}
// max element is in the list head
int firstElementDeleted = 0;
if (head->value == max)
{
node* temp = head->next;
free(head);
head = temp;
firstElementDeleted = 1;
}
// max elements is not in the list head
element = head;
while (element->next != NULL)
{
node* temp = NULL;
if (element->value == max)
{
if (!firstElementDeleted)
(element->prev)->next = element->next;
else
head = element->next;
temp = element->next;
free(element);
element = temp;
continue;
}
element = element->next;
}
// max elements is in the last node
if (element->value == max)
{
(element->prev)->next = NULL;
free(element);
}
return head;
}
void freeMemory(node* head)
{
node* next;
while (head != NULL)
{
next = head->next;
free(head);
head = next;
}
}
Previous pointer points to nowhere
You do not set the previous node pointer of the next element when you delete the element in the deleteMaxElement function. Add this one line to your function and it should work as intended. ;)
while (element->next != NULL)
{
node* temp = NULL;
if (element->value == max)
{
if (!firstElementDeleted) {
(element->prev)->next = element->next;
(element->next)->prev = element->prev;
}
else
head = element->next;
temp = element->next;
free(element);
element = temp;
continue;
}
element = element->next;
}

Multiple data inside a single linked list node

Is it possible to have multiple data inside a single linked list node in C? And how do you input and access data with this?
#include <stdio.h>
#include <stdlib.h>
struct node{
int data;
char name[30];
struct node *next;
};
struct node *head, *tail = NULL;
void addNode(int data, char string) {
struct node *newNode = (struct node*)malloc(sizeof(struct node));
newNode->data = data;
newNode->name[30] = string;
newNode->next = NULL;
if(head == NULL) {
head = newNode;
tail = newNode;
}
else {
tail->next = newNode;
tail = newNode;
}
}
void sortList() {
struct node *current = head, *index = NULL;
int temp;
if(head == NULL) {
return;
}
else {
while(current != NULL) {
index = current->next;
while(index != NULL) {
if(current->data > index->data) {
temp = current->data;
current->data = index->data;
index->data = temp;
}
index = index->next;
}
current = current->next;
}
}
}
void display() {
struct node *current = head;
if(head == NULL) {
printf("List is empty \n");
return;
}
while(current != NULL) {
printf("%d - %s", current->data, current->name);
current = current->next;
}
printf("\n");
}
int main()
{
char string1[10] = "Aaron";
char string2[10] = "Baron";
char string3[10] = "Carla";
addNode(9, string1);
addNode(7, string2);
addNode(2, string3);
printf("Original list: \n");
display();
sortList();
printf("Sorted list: \n");
display();
return 0;
}
I don't understand why my code didn't work. I was trying to make use of single linked list where it can accept/input and print/output the number and the name at the same time.
What I want it to happen is to print the number and the name.
The output should be:
Carla - 2
Baron - 7
Aaron - 9
Please read my comments marked as // CHANGE HERE.
// CHANGE HERE: accept a character array as argument
void addNode(int data, char string[]) {
struct node *newNode = (struct node*)malloc(sizeof(struct node));
newNode->data = data;
// CHANGE HERE: copy char array argument to name
strncpy(newNode->name, string, 30);
newNode->next = NULL;
if(head == NULL) {
head = newNode;
tail = newNode;
}
else {
tail->next = newNode;
tail = newNode;
}
}
void sortList() {
struct node *current = head, *index = NULL;
int temp;
char temp1[30];
if(head == NULL) {
return;
}
else {
while(current != NULL) {
index = current->next;
while(index != NULL) {
if(current->data > index->data) {
temp = current->data;
current->data = index->data;
index->data = temp;
// CHANGE HERE: swap the name along with data
strncpy(temp1, current->name, 30);
strncpy(current->name, index->name, 30);
strncpy(index->name, temp1, 30);
}
index = index->next;
}
current = current->next;
}
}
}
void display() {
struct node *current = head;
if(head == NULL) {
printf("List is empty \n");
return;
}
while(current != NULL) {
printf("%d - %s\n", current->data, current->name);
current = current->next;
}
printf("\n");
}

Circular doubly linked list in C delete function

I have a circular doubly linked list.
The deletefront() function is not working: the output is wrong. What is the mistake?
The other functions are working. But I get a wrong output after displaying after calling deletefront function. The 100 value which should be deleted is still appearing. Please correct it.
I have included the C source code:
// circular doubly linked list
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int data;
struct node *rlink;
struct node *llink;
} node;
node *head = NULL;
node *getnode(int ele) {
node *ptr;
ptr = (node *)malloc(sizeof(node));
if (ptr == NULL) {
printf("memory not alloc");
exit(0);
}
if (ptr != NULL) {
ptr->data = ele;
ptr->rlink = NULL;
ptr->llink = NULL;
}
return ptr;
}
void insertfront(int ele) {
node *newnode;
newnode = getnode(ele);
if (head == NULL) {
head = newnode;
head->rlink = head;
head->llink = head;
} else {
head->llink = newnode;
newnode->rlink = head;
head = newnode;
}
}
void insertend(int ele) {
node *newnode;
newnode = getnode(ele);
if (head == NULL) {
head = newnode;
head->rlink = head;
head->llink = head;
} else {
node *temp = head;
do {
temp = temp->rlink;
} while (temp != head->llink);
newnode->rlink = temp->rlink;
temp->rlink = newnode;
newnode->llink = temp;
}
}
int lenlist() {
node *temp;
int count = 0;
temp = head;
do {
temp = temp->rlink;
count++;
} while (temp != head);
return count;
}
void insertatpos(int ele,int pos) {
if (pos == 1) {
insertfront(ele);
} else
if (pos == (lenlist() + 1)) {
insertend(ele);
} else
if (pos > 1 && pos <= (lenlist() + 1)) {
node *prev, *curr;
node *newnode = getnode(ele);
int count = 1;
curr = head;//curr points to 1st node
do {
prev = curr;
count++;
curr = curr->rlink;
if (count == pos) {
prev->rlink = newnode;
newnode->llink = prev;
newnode->rlink = curr;
curr->llink = newnode;
}
} while (curr != head);
} else {
printf("invalid position");
}
}
void delfront() {
if (head == NULL)
printf("empty list");
node *aux;
node *lastnode, *secondnode;
aux = head;
lastnode = head->llink;
secondnode = head->rlink;
secondnode->llink = lastnode;
lastnode->rlink = secondnode;
free(aux);
head = secondnode;
}
void display() {
node *aux = head;
do {
printf("%d->", aux->data);
aux = aux->rlink;
} while (aux != head);
printf("\n");
}
int main() {
insertfront(100);
insertend(20);
printf("\n%d\n", lenlist());
insertatpos(45, 2);
display();
delfront();
display();
}
The problem is not in the deletefront() function, instead, you have missed updating a few links in the insertfront() and insertend() functions.
I have updated the code here and also added the comment where I made the changes. Try to visualise it using an example.
However, I suggest that you solve such issues using a debugger or go through the code with a sample test case. It will improve you debugging as well as coding skills!
Your code have a lot of mistakes.
// circular doubly linked list
#include <stdio.h>
#include <stdlib.h>
/*i changed the names of your pointers here*/
typedef struct node {
int data;
struct node *prev, *next;
} node;
/*
node *head = NULL;
This will be removed.
Avoid using globals as much as you can.
*/
/*
This function is unecessary.
node *createNode(int ele) {
node *ptr;
ptr = (node *)malloc(sizeof(node));
if (ptr == NULL) {
printf("memory not alloc");
exit(0);
}
if (ptr != NULL) {
ptr->data = ele;
ptr->rlink = NULL;
ptr->llink = NULL;
}
return ptr;
}
*/
char insertFront(node **head, int ele) {
node *newNode=malloc(sizeof(node));
If (newNode==NULL) return 0;
newNode->data=ele;
if (*head){
newNode->next=*head;
newNode->prev=(*head)->prev;
(*head)->prev->next=newNode;
(*head)->prev=newNode;
} else {
newNode->next=newNode;
newNode->prev=newNode;
}
*head=newNode;
return 1;
}
char insertEnd(node **head, int ele) {
node *newNode=malloc(sizeof(node));
If (newNode==NULL) return 0;
newNode->data=ele;
if (*head){
newNode->next=*head;
newNode->prev=(*head)->prev;
(*head)->prev->next=newNode;
(*head)->prev=newNode;
} else {
newNode->next=newNode;
newNode->prev=newNode;
*head=newNode;
}
return 1;
}
/*You could simple create a struct list that would have as members
the head of your list and its height to avoid calculating it each time
you want it but anyway. I will fix that.
int lenList(node *head) {
if (*head==NULL) return 0;
node *temp=head;
int count = 0;
do {
temp = temp->next;
count++;
} while (temp != head);
return count;
}
*/
char insertNatP(node **head, int ele, int pos) {
If (pos<1 || pos>lenList(head)){
printf("Invalid Position\n");
return 0;
}
int i;
for(i=0; i<pos-1; head=&head->next, i++);
node *newNode=malloc(sizeof(node));
If (newNode==NULL){
printf("Memory could not be allocated\n");
return 0;
}
newNode->data=ele;
If (*head!=NULL){
newNode->prev=(*head)->prev;
(*head)->prev->next=newNode;
(*head)->prev=newNode
newNode->next=*head;
} else {
newNode->prev=newNode;
newNode->next=newNode;
}
*head=newNode;
return 1;
}
char delFront(node **head) {
if (*head == NULL) return 0;
node garbage=*head;
*head=(*head)->next;
if (*head==garbage) *head=NULL; else{
(*head)->prev=garbage->prev;
garbage->prev->next=*head;
}
free(garbage);
return 1;
}
void printList(node *list) {
if (list==NULL) return;
node *sentinel=list->prev;
while (list!=sentinel) {
printf("%d->", list->data);
list=list->next;
}
printf("%d\n", list->data);
}
int main() {
node *l1=NULL;
insertFront(&l1, 100);
insertEnd(&l1, 20);
printf("\n%d\n", lenList(l1));
insertNatP(&l1, 45, 2);
printList(l1);
delFront(&l1);
printList(l1);
}
Try this

Why variables in local function does not disappear? (insert function for linked list)

I wonder why newNode in this function does not disappear?
#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
typedef struct node {
float hs;
float sm;
struct node *next;
}Node;
Node* InsertNode(Node* head, int index, float hs, float sm){
if(index < 0) return NULL;
int currIndex = 1;
Node* currNode = head;
while (currNode && index > currIndex) {
currNode = currNode->next;
currIndex++;
}
if (index > 0 && currNode == NULL) return NULL;
Node* newNode = (Node*) malloc(sizeof(Node));
newNode->hs = hs;
newNode->sm = sm;
if(index == 0){
newNode->next = head;
head = newNode;
}
else {
newNode->next = currNode->next;
currNode->next = newNode;
}
return head;
}
void Display(Node* head) {
Node* currNode = head;
while(currNode != NULL){
printf("(%.2f, %.2f ) ", currNode->hs, currNode->sm);
currNode = currNode->next;
}
}
int main(){
Node* poly1 = NULL;
Node* poly2 = NULL;
poly1 = InsertNode(poly1, 0, 5, 4);
poly1 = InsertNode(poly1, 1, 6, 3);
poly1 = InsertNode(poly1, 2, 7, 0);
Display(poly1);
getch();
return 0;
}
I tried to code a function for inserting an element. I know that local variables will disappear after called-function end but it's still work?
Please help me solve this problem.
when you call -> poly1 = InsertNode(poly1, 1, 6, 3);, poly1 is already head and head->next is NULL, hence in these lines:
Node* currNode = head;
while (currNode && index > currIndex) {
currNode = currNode->next;
currIndex++;
}
You are making currNode point to NULL which later results into:
if (index > 0 && currNode == NULL) return NULL;

Linked List output not showing correctly

I can't figure out where is the problem in my code:
typedef struct list List;
struct list {
int data;
List* next;
};
void insert_sorted(List** head, int value);
int main() {
List* head = NULL;
/*
insert_sorted(&head, 20);
insert_sorted(&head, 10);
insert_sorted(&head, 5);
*/
insert_sorted(&head, 3);
insert_sorted(&head, 2);
insert_sorted(&head, 40);
insert_sorted(&head, 10);
//insert_sorted(&head, 40);
List* temp = head;
while (temp != NULL) {
printf("%d\t", temp->data);
temp = temp->next;
}
printf("\n\n");
return 0;
}
void insert_sorted(List** head, int value) {
List* temp = NULL;
List* node = (List*)malloc(sizeof(List));
node->data = value;
node->next = NULL;
if (*head == NULL || (*head)->data >= value) {
node->next = *head;
*head = node;
} else {
temp = *head;
while (temp->next != NULL) {
if (temp->data < value && (temp->next)->data > value) {
node->next = temp->next;
temp->next = node;
} else
temp = temp->next;
}
temp->next = node;
}
}
1:
Run the code and see results. (Running and running...) after sorting data it is repeating some values forever.
2:
Go to
//insert_sorted(&head, 40);
this line an remove comment symbols.
Run the code and mark the result.(Time limit exceeded)
3:
Find this and remove comments:
/*
insert_sorted(&head, 20);
insert_sorted(&head, 10);
insert_sorted(&head, 5);
*/
Run and see results; (Again some problems)
Finally:
Remove all comments symbols and run it, this time it is working without any error but not as expected (List is not sorted correctly);
But why this is happening? Any help will be appreciated, and I am not at home at this but a learner.
Your void insert_sorted(List** head, int value) function is doing too much work.
void insert_sorted(List** head, int value) {
List* node = malloc(sizeof *node);
node->data = value;
for( ; *head ; head = &(*head)->next) {
if ((*head)->data > value) break; // we should insert before *head
}
// When we get here *head points to the pointer that needs to get node's value
// This can either be the original head (as supplied as argument tothe function)
// or some of the -> next pointers, or even the last ->next pointer.
node->next = *head;
*head = node;
}
The problem can be fixed as follows. If the node is inserted in the middle, the function can return and does not need to append the value at the end.
void insert_sorted(List** head, int value) {
List* temp = NULL;
List* node = (List*)malloc(sizeof(List));
node->data = value;
node->next = NULL;
if (*head == NULL || (*head)->data >= value) { // <-- fix
node->next = *head;
*head = node;
}
else {
temp = *head;
while (temp->next != NULL) {
if ( (temp->next)->data > value ) {
node->next = temp->next;
temp->next = node;
return; // <-- fix
}
else
temp = temp->next;
}
temp->next = node;
}
}
Your code sometimes inserted value twice (when value was not placed at the end of the list). This should fix the problem:
while(temp->next != NULL)
{
if(temp->data < value && (temp->next)->data > value)
{
node->next = temp->next;
temp->next = node;
break;
}
else
temp = temp->next;
}
if(temp->next == NULL)
temp->next = node;

Resources