C. Linked lists. Inserting an element before another - c

Right now I have a program (shown below) that inserts an element (E) after (F). For example if we input n = 4 and then insert 4 elements 2 3 3 4, followed by our 'F' value which is 3 and E value which is 6, the program will edit the list inserting E (6) after F (3), resulting in a list edition from 2 3 3 4 into 2 3 6 3 4
I am looking for a way to insert a value 'E' BEFORE an F, not after. Could anyone explain what changes may be required to this code to achieve the same?
#include <stdio.h>
#include <stdlib.h>
struct sarasas { int duomuo; struct sarasas *next, *prev; };
typedef struct sarasas Sarasas;
typedef Sarasas *SarasasPtr;
int main()
{
int d,i,n,j,e,f;
SarasasPtr Sar,x,temp,prev=NULL;
SarasasPtr head= NULL;
printf("Insert 'n' \n");
scanf("%d",&n);
for (i=0; i<n; i++) {
printf("Insert an element: \n");
scanf("%d",&d);
x=(SarasasPtr) malloc(sizeof( Sarasas ));
x->duomuo = d;
x->next = NULL;
if(head == NULL) {
head = x;
} else {
temp = head;
while(temp!=NULL) {
prev = temp;
temp = temp->next;
}
prev->next = x;
}
}
printf("Insert an element after which one you want another element to be inserted\n");
scanf("%d",&e);
printf("Insert element which you want to insert\n");
scanf("%d",&f);
temp = head;
int pakeista = 0;
while(temp!=NULL) {
//printf("%d",temp->duomuo);
if (temp->duomuo == e) {
if (changed == 0) {
x=(SarasasPtr) malloc(sizeof( Sarasas ));
x->duomuo=f;
x->next=temp->next;
temp->next=x;
n++;
changed = 1;
}
}
temp=temp->next;
}
Sar = head;
for (i=0; i<n; i++) {
printf("Sk Nr. %i: %d\n",i+1,Sar->duomuo);
Sar = Sar->next;
}
}

You simply need to check temp->next->duomuo instead of temp->duomuo
while(temp->next!=NULL) {
if (temp->next->duomuo == e) {
if (changed == 0) {
x=(SarasasPtr) malloc(sizeof( Sarasas ));
x->duomuo=f;
x->next=temp->next;
temp->next=x;
n++;
changed = 1;
}
}
temp=temp->next;
}
I would also suggest that instead of this changed thing that you are doing, just break from the loop after you replace. This way your loop won't run more times than it needs to.
while(temp->next!=NULL) {
if (temp->next->duomuo == e) {
x=(SarasasPtr) malloc(sizeof( Sarasas ));
x->duomuo=f;
x->next=temp->next;
temp->next=x;
n++;
break;
}
temp=temp->next;
}

Related

Split a single linked list into 2 SIngly linked lists -one containing nodes with even data and other containing nodes with odd data

I tried coding the above problem but I'm getting a segmentation error.Below is the code that I've written :
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
struct oddeven
{
int data;
struct oddeven *link;
};
typedef struct oddeven m;
int main()
{
int z;
m *head=NULL,*ptr,*current;
m *x,*y,*q,*head1=NULL,*current1,*head2=NULL,*current2;
while(1)
{
int ch;
ptr=(m*)malloc(sizeof(m));
printf("Enter the data: ");
scanf("%d",&ptr->data);
ptr->link=NULL;
if(head==NULL)
{
head=ptr;
current=ptr;
}
else
{
current->link=ptr;
current=ptr;
}
printf("Do you want to continue?Y=1/N=0");
scanf("%d",&ch);
if(ch!=1)
break;
}
x=head;
while(x!=NULL)
{
z=x->data;
if(z%2==0)
{
ptr=(m*)malloc(sizeof(m));
ptr->data=z;
ptr->link=NULL;
if(head1==NULL)
{
head1=ptr;
current1=ptr;
}
else
{
current1->link=ptr;
current1=ptr;
}
}
else
{
ptr=(m*)malloc(sizeof(m));
ptr->data=z;
ptr->link=NULL;
if(head2=NULL)
{
head2=ptr;
current2=ptr;
}
else
{
current2->link=ptr;
current2=ptr;
}
}
x=x->link;
}
y=head1;
q=head2;
while (y!=NULL)
{
printf("%d\t",y->data);
y=y->link;
}
printf("\n");
while (q!=NULL)
{
printf("%d\t",q->data);
q=q->link;
}
}
I can't figure out where am I going wrong. Any help would be much appreciated.
It takes the inputs but after that it says segmentation error. Split the given single linked list into two where I can store the odd vales and even values separately .I tried different methods but couldn't get it to work.
#VladfromMoscow mentions one reason why your program faults, but it is too complicated anyway. Here is a simpler version. With a singly linked list, you don't need a separate operation for the first element, when head == NULL. You don't need any new nodes when splitting, just relink.
#include <stdio.h>
#include <stdlib.h>
struct oddeven {
int data;
struct oddeven *link;
};
typedef struct oddeven m;
int main(void) {
int num;
m *head = NULL, *ptr;
// read the list and end it with any letter or non-digit
while(scanf("%d", &num) == 1) {
ptr = malloc(sizeof *ptr);
if(ptr == NULL) {
exit(1);
}
ptr->data = num;
ptr->link = head;
head = ptr;
}
// split the list
m *x, *odd = NULL, *even = NULL, *next;
x = head;
while(x != NULL) {
next = x->link; // remember what the link was
if(x->data % 2 == 0) {
x->link = even;
even = x;
}
else {
x->link = odd;
odd = x;
}
x = next;
}
// output the odds
m *y = odd;
while (y != NULL) {
printf("%d\t", y->data);
y = y->link;
}
printf("\n");
// output the evens
m *q = even;
while (q != NULL) {
printf("%d\t", q->data);
q = q->link;
}
printf("\n");
}
Program session:
1 5 8 3 44 9 0 1 4 3 6 77 3 42 q
1 5 3 9 1 3 77 3
8 44 0 4 6 42

hashtable printing slightly out of order

I'm trying to create a basic hash table in c that takes in integers. I'm trying to get it to print the numbers 1-10, in order. Everything compiles and seems fine when I input integers, but when I use the printlist function I made, it print 10,1,2,3,4,5,6,7,8,9. I've tried for hours but I can't figure out what's causing it.
#include <stdlib.h>
#include <stdio.h>
typedef struct node {
struct node* next;
int data;
}node;
void printlist(node *ht[]);
node* insert_node(node *ht[]);
int main() {
int index = 0;
int input;
int option;
node* ht[10] = { NULL };
do {
printf("Press 1 to input a node\n");
printf("Press 2 to print the list\n");
printf("Press 3 to exit:\n");
printf("Select Option: ");
scanf("%i", &option);
if (option == 1) {
insert_node(ht);
continue;
}
if (option == 2) {
printlist(ht);
}
} while (option != 3);
}
void printlist(node* ht[]) {
node *prvptr;
node *curptr;
int j = 9;
int index = 0;
for (index = 0; j >= index; index++) {
curptr = ht[index];
curptr = curptr->next;
while (curptr != NULL) {
printf("%i\n", curptr->data);
curptr = curptr->next;
break;
}
}
}
node* insert_node(node* ht[]) {
node *newptr;
node *curptr;
node *prvptr;
node *head;
int count = 0;
int choice;
int index = 0;
int input = 0;
printf("Input negative 1 to cancel\n");
printf("What number would you like to add to the list?: ");
scanf("%i", &input);
index = input % 10;
while (input != -1) {
newptr = (node*)malloc(sizeof(node)); // creates a node for the input data
newptr->data = input;
newptr->next = NULL;
if (ht[index] == NULL) { // if there is no head
ht[index] = (node*)malloc(sizeof(node));
ht[index]->data = NULL;
ht[index]->next = newptr;
count++;
}
else {
curptr = ht[index];
while (curptr->next != NULL) {
prvptr = curptr;
curptr = curptr->next;
if (curptr->data > input) { // if in-between two nodes
prvptr->next = newptr;
newptr->next = curptr;
break;
}
else if (curptr->next == NULL) { // if at the end of the list
curptr->next = newptr;
break;
}
}
}
printf("Input negative 1 to cancel\n");
printf("What number would you like to add to the list?: ");
scanf("%i", &input);
index = input % 10;
}
return ht;
}
Your index calculation is index = input % 10;. The number 10, mod 10, is 0, so it goes in the first index (index 0) of your table, before 1-9 (which would go in indices 1 through 9). Since your printer prints the buckets in order from index 0 to 9 inclusive, 10 is output first.
The nature of hash tables is to have limited ordering (most languages and hash table libraries give no guarantees at all on the iteration order of a hash table); I wouldn't be bothered by 10 happening to appear first in the output.
Just as #ShadowRanger mentioned, it is not wrong for the 10 to come out first.
Instead, I see another error in your printlist code :
while (curptr != NULL) {
printf("%i\n", curptr->data);
curptr = curptr->next;
break;
}
the break statement should not be there, you will end up printing just one of your elements per hash value.

How do I Bubble Sort a linked list?

I am trying to create a linked list and sort it by Bubble Sort. I succeeded to create the linked list, but when I am trying to Bubble Sort it, some accidents occur and I do not know the problem. What is the problem?
#include <stdio.h>
#include <stdlib.h>
//the struct of LinkedList
typedef struct Node
{
int data;
struct Node * pNext;
}NODE,*PNODE;
PNODE createList();//Creat one LinkedList
int lengthList(PNODE pHead);//get the length of LinkedList
void sortList(PNODE);//bubble sort
int main()
{
int length;
PNODE pHead=NULL;
pHead=createList();
sortList(pHead);
return 0;
}
//Create LinkedList
PNODE createList()
{
int i,n;
int val;
PNODE pHead=(PNODE)malloc(sizeof(NODE));
if(pHead==NULL)
{
printf("failed to create!\n");
exit(-1);
}
pHead->pNext=NULL;
PNODE pTail=pHead;
printf("please input the length of the LinkedList:");
scanf("%d",&n);
for(i=0;i<n;i++)
{
printf("number %d is:\n",i+1);
scanf("%d",&val);
PNODE pNew=(PNODE)malloc(sizeof(NODE));
if(pNew==NULL)
{
printf("failed to create\n");
exit(-1);
}
pNew->data=val;
pTail->pNext=pNew;
pNew->pNext=NULL;
pTail=pNew;
}
return pHead;
}
//get the length of LinkedList
int lengthList(PNODE pHead)
{
int i=0;
PNODE p=pHead->pNext;
while(p!=NULL)
{
i++;
p=p->pNext;
}
return i;
}
//bubble sort
void sortList(PNODE pHead)
{
int i,j,t,len;
PNODE p,q;
len=lengthList(pHead);
p=pHead->pNext;
for(i=0;i<len-1;i++)
{
for(j=0;j<len-i;j++)
{
q=p->pNext;
if( p->data > q->data)
{
t=p->data;
p->data=q->data;
q->data=t;
}
p=q;//here may be the error
}
}
return;
}
You are running off the end of your list in sortList
p=pHead->pNext;
for(i=0;i<len-1;i++)
{
for(j=0;j<len-i;j++)
{
q=p->pNext;
....
p=q;//here may be the error
}
}
Bug 1) Your list is only len long but you are attempting to advance p to p->pNext far more then len times.
Bug 2) pHead does not need to be a full NODE - it's just a PNODE pointer. You never use its data field. You should have pHead point to the first node in the list, and then start your iteration at pHead rather than pHead->pNext.
Bug 3) You never clean up your memory allocations.
As #Airsource pointed out the bugs, keep in mind most of them are caused because of poor designing choice of your program. Try to do it like below & you will run into less errors
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
typedef struct _Node{
int data;
struct _Node* next;
}Node;
typedef struct {
Node* headPtr;
Node* tailPtr;
unsigned size;
}List;
static void create_node(List* list, int element) {
if (list->headPtr == NULL) {
// List is empty
list->headPtr = (Node* )malloc(sizeof(Node));
list->headPtr->data = element;
list->headPtr->next = 0;
list->tailPtr = list->headPtr;
list->size++;
}else{
// List was already populated
Node* temp = (Node* )malloc(sizeof(Node));
temp->data = element;
temp->next = 0;
list->tailPtr->next = temp;
list->tailPtr = temp;
list->size++;
}
}
void create_list(List* list, int length){
int ele;
int i;
list->headPtr = list->tailPtr = 0;
list->size = 0;
for (i = 0; i < length; i++) {
scanf("%d", &ele);
create_node(list, ele);
}
}
void print_list(List* list){
Node* loop = list->headPtr;
while(loop){
printf("%d ", loop->data);
loop = loop->next;
}
printf("\n");
}
int main(){
List* list;
int n;
printf("Enter the length of the list: ");
scanf("%d", &n);
create_list(list, n);
print_list(list);
bubble_sort(list);
print_list(list);
if (cleanup(list))
printf("Memory rescued!!\n");
else
printf("OOPS!! Error\n");
return 0;
}
Moreover, you can get the size anytime just by list->size. No need for separate function to do that.
Finally to sort it using bubble sort you could do something like this below
void bubble_sort(List* list) {
int i, j;
Node* first, *second;
int temp;
first = list->headPtr;
second = list->headPtr->next;
for (i = 0; i < list->size - 1; i++) {
for (j = 0; j < list->size - i - 1; j++) {
if (first->data > second->data){
temp = first->data;
first->data = second->data;
second->data = temp;
}
first = second;
second = second->next;
}
first = list->headPtr;
second = list->headPtr->next;
}
}
and for cleanup you do this
bool cleanup(List* list) {
Node* curr = list->headPtr;
Node* nxt = list->headPtr->next;
while(nxt){
free(curr);
curr = nxt;
nxt = curr->next;
}
list->headPtr = list->tailPtr = 0;
list->size = 0;
return !nxt ? true: false;
}
There are couple of bugs in your program. I will address them one by one:
Line 28 PNODE pHead=(PNODE)malloc(sizeof(NODE));
Here you are allocating a memory and creating a node before checking if n>0 or not.
Line 36 printf("please input the length of the LinkedList:");
Now up to this point you have created a one node, head node which has no value in it (so contains garbage)
In effect your createList() creates a linked list with n+1 nodes instead of n and the head->value contains garbage.
Solution:
printf("please input the length of the LinkedList:");
scanf("%d", &n);
for(i=0; i<n; i++)
{
PNODE pNew = (PNODE)malloc(sizeof(NODE));
if(pNew == NULL)
{
printf("failed to create!\n");
exit(-1);
}
scanf("%d", &val);
pNew->data = val;
pNew->pNext = NULL;
if (!i)
pHead = pNew;
else
pTail->pNext = pNew;
pTail = pNew;
}
return pHead;
Line 59 PNODE p=pHead->pNext;
Here you are counting nodes starting from the second node (leaving out head). No wonder you will get length as n as you have created a linked list of length n+1 in your createList()
Imagine what if n = 0 and thus pHead = NULL?
Then this line will result in SegFault.
Solution:
change PNODE p=pHead->pNext; to PNODE p = pHead;
Line 73 p=pHead->pNext;
Here you will start sorting excluding the first node, head node.
Also this should be inside the outter for and outside of the inner for to reset the p to first node for each pass.
Line 76 for(j=0;j<len-i;j++)
Here j must be less than len - 1 - i as in pass 1 (i = 0) in the worst case j will be equal to len-1 for j < len-i, where p will point to the last node of linked list and q will be NULL as q = p -> pNext. Which will make q->data to result in SegFault.
To summarise, your sort routine is producing SegFault in the very first Pass and even if it didn't (by properly adjusting the loop-terminating expression in inner for) the outer for loop is contributing nothing towards the sorting except increasing the time complexity.
Solution:
for(i = 0; i < len - 1; i++)
{
p = pHead;
for(j = 0; j < len - 1 - i; j++)
{
q = p -> pNext;
if(p->data > q->data)
{
t = p -> data;
p -> data = q -> data;
q -> data = t;
}
p = q;
}
}
A question:
How are you checking whether element have been sorted or not?
A printList() routine would have been helpful in spotting the above bugs.
"Always verify whether you correctly stored the input or not by explicitly printing the same before processing it!"

linked linked insertion function

Hello I am trying to create n number of lists. Each list is ordered linked list with a new instance. However, I also need a combined ordered linked list. Following is the code for the same. When it comes to each independent list I do not have any problems. However, when I am trying to insert every node into a globally declared linked list nodes, I am getting error(The input crashes with iteration of one node value.) Please have a look at the function and call highlighted to make things clear where I am exactly getting the error. Please make a note of global declarations. Thanks in advance.
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
struct node{
int number;
struct node*next;
};
typedef struct node NODE;
NODE*createlist(int),*rel_strt,*new_entry[100];
NODE *start1=NULL,*rear1,*m1,*temp11;
NODE *insert_in_end(NODE*node1);
int i,num,n2,j,v,u;
int main() {
v=0;u=0;
printf("\n Enter the number of lists:");
scanf("%d",&n2);
for(j=0;j<n2;j++) {
printf("\n\n Enter the number of inputs to the list %d: \n ",j+1);
scanf("%d",&num);
new_entry[v]=createlist(num);
display(new_entry[v]);
v++;
}
printf("\nThe final List is:");
display(start1);
return 0;
}
NODE*insert_in_end(NODE *node11) { //problem in this function
int inf1=node11->number;
if(start1==NULL) {
start1=rear1=node11;
} else {
m1=start1;
if(m1->number>inf1) {
node11->next=m1;
start1=node11;
} else {
while(m1->next) {
if(m1->next->number < inf1)
m1=m1->next;
else
break;
}
temp11=m1->next;
m1->next=node11;
node11->next=temp11;
}
}
return start1;
}
void display(NODE*nodex) {
while(nodex!=NULL) {
printf("%d ->",nodex->number);
nodex=nodex->next;
}
}
NODE *createlist(int n1) {
NODE *node1,*start,*rear,*m,*temp1;
start=NULL;
for(i=0;i<n1;i++) {
node1=(NODE*) malloc(sizeof(NODE));
int inf;
printf("Enter node value %d:",i+1);
scanf("%d",&inf);
node1->number=inf;
node1->next=NULL;
insert_in_end(node1); // error during second fuction call check function definition
if(start==NULL) {
start=rear=node1;
} else {
m=start;
if(m->number>inf) {
node1->next=m;
start=node1;
} else {
while(m->next) {
if(m->next->number < inf)
m=m->next;
else
break;
}
temp1=m->next;
m->next=node1;
node1->next=temp1;
}
}
}
return start;
}
I suggest you define a function insertValue that would make it much more convenient for you. It will also make your code much more readable.
The function is below and you should see that it is very close to what you have.
// Returns the new start of the list after inserting value in increasing order
Node* insertValue(Node * list, int value)
{
Node *newNode, *m;
newNode = malloc(sizeof(NODE));
newNode->number = value; // added this
newNode->next = NULL; // added this
if(list == NULL)
return newNode;
if(value < list->number)
{
newNode->next = list;
return newNode;
}
m = list;
while(m->next)
{
if(value < m->next->number)
break;
m = m->next;
}
newNode->next = m->next;
m->next = newNode;
return list;
}
Your main function should now iterate over reading the numbers for the different short lists as below. As you see, variable names are more explicit than yours. They are limited to the minimum and there are no global variables.
int main(int argc, char* argv[])
{
NODE *globalList = NULL, *lists[100];
int nbrOfLists, listNo, nbrOfVal, valNo, val;
printf("\n Enter the number of lists:");
scanf("%d", &nbrOfLists);
if(nbrOfLists < 0 || nbrOfLists > 100)
return -1;
for(listNo = 0; listNo < nbrOfLists; listNo++)
{
printf("\n\n Enter the number of inputs to the list %d: \n ",listNo+1);
scanf("%d", &nbrOfVal);
lists[listNo] = NULL;
for(valNo = 0; valNo < nbrOfVal; valNo++)
{
printf("Enter node value %d:", valNo+1);
scanf("%d", &val);
// Here we insert the value in both lists
lists[listNo] = insertValue(lists[listNo], val);
globalList = insertValue(globalList, val);
}
display(lists[listNo]);
}
display(globalList);
return 0;
}
Your display function is correct. I provide it below, but it's the same as yours. The problem you encountered was because I forgot to initialize the fields of the node after I malloc it.
void display(NODE * list)
{
while(list)
{
printf("%d ->", list->number);
list = list->next;
}
}

Sorting the numbers in a list / C

I need to sort the numbers that are entered in a list, but I am doing something wrong and it's sorting all of them except the first one.Any ideas how to fix this?
Here's my code:
#include <stdio.h>
#include <stdlib.h>
struct node
{
int data;
struct node *next;
};
struct node* List;
void Add (struct node* p, int d)
{
struct node* q;
q=malloc(sizeof(struct node));
if (q==NULL)
printf("Not enaugh memory!");
else
{
q->data=d;
if(List==NULL)
{
q->next=NULL;
List=q;
}
else
{
struct node *ptr=List;
while((ptr->next!=NULL)&&(ptr->next->data>d))
{
ptr=ptr->next;
}
q->next=ptr->next;
ptr->next=q;
}
}
}
int main()
{
int n,i,a;
printf("How much numbers are you going to enter? ");
scanf("%d",&n);
for (i=1; i<=n; i++)
{
printf("\nEnter a number: ");
scanf("%d",&a);
Add(List,a);
}
printf("\nThe sorted numbers are: ");
struct node *ptr=List;
while(ptr!=NULL)
{
printf("%d\t",ptr->data);
ptr=ptr->next;
}
printf("\n\n");
system("PAUSE");
return 0;
}
Thanks for the help in advance :-)
in add() function,
if(List==p)
this statement is true for all elements you insert to list since the call to add is,
Add(List,a);
so p=List. therefore the sorting code written in else part is not executed.
Also add statements to check for empty initial list.
You can use code similar to this,
void Add (int d)
{
struct node* q;
q=malloc(sizeof(struct node));
if (q==NULL)
printf("Not enaugh memory!");
else
{
q->data=d;
if(List==NULL)
{
q->next=NULL;
List=q;
}
else
{
struct node *ptr=List;
while((ptr->next!=NULL)&&(ptr->next->data>d))
{
ptr=ptr->next;
}
q->next=ptr->next;
ptr->next=q;
}
}
}
Since list is a global variable you dont need to pass it to Add() function. change the function call to
Add(a);
void Add (struct node* p, int d){
struct node* q;
q=malloc(sizeof(struct node));
if (q==NULL)
printf("Not enaugh memory!");
else{
q->data=d;
if(List==NULL || List->data < d){//modify this line
q->next= List;//and change NULL to List
List=q;
} else {
struct node *ptr=List;
while((ptr->next!=NULL)&&(ptr->next->data>d)){
ptr=ptr->next;
}
q->next=ptr->next;
ptr->next=q;
}
}
}
You always call Add with List as the first parameter, so it's alway true inside Add that (List==p). Consequently each new item is just inserted at the front of the list and there is no sorting at all.
EDIT 1
A good practice would be sending a list to the Add routine as a parameter. Or, if you want to keep it external, just don't give it to Add at all and test if(List == NULL)
void Add( int d)
{
// ... alloc 'q' and fill q->d here, then:
if(List == NULL)
{
q->next = NULL;
List = q;
}
else
{
struct node *b; // put q after b
for( b = List; b->next != NULL; b = b->next)
if( b->next->data >= d)
break;
q->next = b->next;
b->next = q;
}
}
EDIT 2
Example of transferring the list to a function by parameter
void Add( struct node **n, int d)
{
// ... alloc 'q' and fill q->d here, then:
while( *n != NULL && (*n)->data < d)
n = & (*n)->next;
q->next = *n;
*n = q;
}
int main()
{
// ...
Add( &List, a);
// ...
}

Resources