implementing shell sort for linked lists? - c

I'm trying to implement shell sort on singly-linked lists. What I have tried to do is get the respective elements based on the inc value and sort them. However, I'm only familiar with shell sort implementation on arrays and not linked lists. Any help is appreciated.
struct node
{ int data;
struct node *next;
};
typedef struct node n;
void add(int a);
void shellsort(int size);
void display();
void moveptr(n*a, int distance);
n* head=NULL;
void main()
{ int i,x,size;
printf("How many elements do you want to enter: ");
scanf("%d",&size);
printf("Enter the data: ");
for(i=0;i<size;i++)
{ scanf("%d",&x);
add(x);
}
printf("List currently is: ");
display();
shellsort(size);
printf("\nafter sorting list is: ");
display();
}
void add(int a)
{ n *temp = (n*)malloc(sizeof(n));
temp->data=a;
temp->next=head;
head=temp;
}
void display()
{ n* temp=head;
while(temp!=NULL)
{ printf("%d-->",temp->data);
temp=temp->next;
}
}
void moveptr(n *ptr, int distance) // this moves a temp pointer to required location
{ int i=0;
while(i<distance)
{
ptr=ptr->next;
i=i+1;
}
}
void shellsort(int size)
{ int i,j,temp,inc=size/2;
n *a=head,*b=head;
do{
for(i=0;i<size;i++)
{
for(j=i+inc;j<size;j+=inc)
{ b=head;
moveptr(b,j);
if(a->data > b->data)
{ temp=b->data;
b->data=a->data;
a->data=temp;
}
}
a=a->next;
}
inc=inc/2;
}while(inc>=1);
}

If you insist on using shell sort:
allocate an array of pointers to list items,
initialize this array to point to the individual items in the list
sort the array using shell sort
relink the list in the order of the array elements
free the list.

Related

Finding path between nodes using BFS in C language

I'm new to C language and it's been harder for me to work with pointers after working in JavašŸ˜„
I was trying to write a code of finding a path (not necessary minimum) between two nodes in a graph using breadth-first-search.
Here is my code :
#include<stdio.h>
#include<stdlib.h>
#define MAXSIZE 200
void push(int a);
int pop(void);
void bfs(int a,int b,int len);
int nextnode(int a);
typedef struct node{
int data;
struct node* next;
}node;
int res[MAXSIZE];
int visited[MAXSIZE];
int rear,front;
node* graph[MAXSIZE];
int len;
int path[MAXSIZE];
int nextnode(int a)
{
if(graph[a]==NULL)
return -1;
else
{
struct node* c=graph[a];
while(visited[c->data]!=1 && c!=NULL)
{
c=c->next;
}
if(c==NULL)
return -1;
else
return c->data;
}
}
void push(int a)
{
path[rear]=a;
rear++;
}
int pop()
{
if(front==rear)
return -1;
int num=path[front];
front++;
return num;
}
int main()
{
rear=0;
len=0;
front=0;
int n,e;
int i,a,b;
printf("%s\n%s", "Inputting Graph... ","Enter number of nodes and edges: ");
scanf("%d %d",&n,&e);
printf("%s %d %s\n", "Graph Created with",n,"nodes without any edge.");
printf("%s\n","Enter the edges in 1 2 format if an edge exist from Node 1 to Node 2" );
for(i=1;i<=n;i++)
{
graph[i]=NULL;
visited[i]=0;
}
struct node* new = (struct node*)malloc(sizeof(struct node));
for(i=0;i<e;i++)
{
scanf("%d %d",&a,&b);
new->data=b;
new->next=NULL;
struct node* curr=graph[a];
if(curr==NULL)
{
graph[a]=new;
}
else
{
while(curr->next!=NULL)
{
curr=curr->next;
}
curr->next=new;
}
}
printf("%s\n", "Graph Created Successfully.");
printf("%s", "Enter the node numbers between which the path is to be found between: ");
scanf("%d %d",&a,&b);
bfs(a,b,0);
printf("Length is %d\n",len);
for(i=1;i<=len;i++)
{
printf("%d\n",res[len]);
}
}
void bfs(int a,int b,int len)
{
int c;
visited[a]=1;
int flag=0;
while(a!=-1)
{
c=nextnode(a);
while(c!=-1)
{
c=nextnode(a);
if(c==b)
{
flag=1;
break;
}
push(c);
visited[c]=1;
}
len++;
res[len]=a;
if(flag==1)
{
res[len]=b;
break;
}
a=pop();
}
}
I know it's huge, but please mind going through it once. The problem I'm getting is Segmentation Fault after I input all the values, and before dfs() function call! Please Help.
For understanding: I have used array of Lists. Each array index denotes a node and the list denotes all the edges it is connected to. eg: if my Graph has 1->2, 1->3, 2-3 edges;
graph[1] will have a list 2->3->NULL. And graph[2] will have 3->NULL.
Thank you.
EDIT
As pointed out by Aditi, the error was in the line where nextnode function ran the while loop. After changing the code to
while(c != NULL && visited[c->data] == 1 )
the program ran flawlessly.
Thanks!
I think what you are trying to do is not graph[i] = NULL but graph[i]->next = NULL

Converting a Binary tree to a Binary Search Tree

So here I'm converting a Binary Tree to a Binary Search Tree by copying the elements of the tree to an array.
Then,I'm sorting the array(bubble sort) and then traversing the tree using inorder traversal and copying the elements of the array to the tree.
Everything is working fine but the function void inr(Node *root) is not copying the elements as in a binary search tree I should get elements in the increasing order(inorder traversal) but I'm not getting a proper output.
#include<stdio.h>
#include<stdlib.h>
int x=0;
int l=0;
typedef struct node
{
int data;
struct node *rlink;
struct node *llink;
} Node;
Node *getnode()
{
Node *temp=(Node *)malloc(sizeof(Node));
return temp;
}
int a[10];
int i=0;
Node *create(Node *root,int key)
{
int c;
if(root==NULL)
{
root=getnode();
root->rlink=root->llink=NULL;
root->data=key;
}
else
{
printf("Enter where you want to enter 1.RIGHT 2.LEFT");
scanf("%d",&c);
switch(c)
{
case 1:root->rlink=create(root->rlink,key);
break;
case 2:root->llink=create(root->llink,key);
break;
default:printf("Wrong choice");
break;
}
}
return root;
}
void inorder(Node *root) //to copy the contents of the tree in the array
{
if(root!=NULL)
{
inorder(root->rlink);
if(root->data>0) a[i++]=root->data;
inorder(root->llink);
}
}
void utu(Node *h) //For inorder traversal
{
if(h!=NULL)
{
utu(h->rlink);
printf("%d",h->data);
utu(h->llink);
}
}
void inr(Node *root) //to copy the elements of sorted array in the tree to make it a BST
{
if(root==NULL) return;
else if(root!=NULL)
{
inr(root->llink);
root->data=a[l++];
inr(root->rlink);
}
}
void main()
{
int j=0;
int temp=0;
Node *h=NULL;
h=create(h,5);
h=create(h,6);
h=create(h,7);
h=create(h,8);
inorder(h);
count(h);
printf("%d \n",x);
printf("\n \n \n");
for(j=0;j<x;j++)
{
printf("%d \n",a[j]);
}
for(int i=0;i<x;i++) //bubble sorting of the array obtained by copying the nodes data in the array
{
for(j=i+1;j<x;j++)
{
if(a[i]>a[j])
{
temp=a[i];
a[i]=a[j];
a[j]=temp;
}
}
}
utu(h);
//for(j=0;j<x;j++)
//{
// printf("\n %d \n",a[j]);
//}
printf("\n \n");
//j=maxd(h);
//printf("%d",j);
inr(h);
utu(h);
}

Single linkedlist creation in C

#include<stdio.h>
#include<stdlib.h>
struct list
{
int a;
int b;
int c;
struct list *next;
};
struct list* addlistele(struct list*,int,int,int);
/* List c element */
void listc()
{
printf(" soon...\n");
}
void printlist(list)
{
struct list* temp;
temp=list;
while(temp!=NULL)
{
printf("a:%d,b;%d,c:%d\n",temp->a,temp->b,temp->c);
temp=temp->next;
}
}
/* List element */
struct list* addlistele(struct list* listadd,int b,int d,int m)
{
int i;
struct list* temp;
struct list* addelement=(struct list*)malloc(sizeof(struct list));
addelement->a=b;
addelement->b=d;
addelement->c=m;
addelement->next=NULL;
if(listadd==NULL)
{
printf("entering");
return addelement;
}
else
{
temp=listadd;
while(temp->next!=NULL)
{
temp=temp->next;
}
temp->next=addelement;
}
return listadd;
}
int main()
{
int ch,i,a,b,c;
struct list *element,*list;
element=(struct list*)malloc(sizeof(struct list));
printf("Choose any one of the option \n");
printf("1.List All \n 2.List c \n");
scanf("%d",&ch);
switch(ch)
{
case 1:printf("Enter values \n");
for(i=0;i<2;i++)
{
scanf("%d %d %d \n",&a,&b,&c);
list=addlistele(element,a,b,c);
}
printlist(list);
break;
case 2:listc(); break;
default:break;
}
}
Hi all, i have written the code like the above one.In that when i gave inputs
> Choose any one of the option
> 1.List All
> 2.List c 1 Enter values 2 3 4 1 2 3
The output is
a:0,b;0,c:0
a:2,b;3,c:4
a:1,b;2,c:3
and also it is not adding the element first i mean it is not entering into this loop
if(listadd==NULL)
{
printf("entering");
return addelement;
}
how to make the head element to be NULL and also i don't know how 0 is coming first.Could anybody can tell me what will be the issue?
In main() you create head element and pass it to the addlistele() function.
element=(struct list*)malloc(sizeof(struct list));
...
list=addlistele(element,a,b,c);
You are seeing this first element which does not have valid values that you expected.
Solution would be you malloc() the element in the function rather than in main() and do not allocate element in main().
replace
struct list *element,*list;
element=(struct list*)malloc(sizeof(struct list));
with
struct list *list=NULL;
then
replace
list=addlistele(element,a,b,c);
with
list=addlistele(list,a,b,c);
Also
replace
void printlist(list)
with
void printlist(struct list *list)
and
replace scanf("%d %d %d \n",&a,&b,&c); with scanf("%d %d %d",&a,&b,&c);

Depth first search using adjacency list

I m trying to unterstand the code below but thereĀ“s something not clear in DFS function
enter code here
#include<stdio.h>
typedef struct node
{
struct node *next;
int vertex;
}node;
node *G[20];
int visited[20];
int n;
void read_graph();
void insert(int,int);
void DFS(int);
void main()
{
int i;
read_graph();
//initialised visited to 0
for(i=0;i<n;i++)
visited[i]=0;
DFS(0);
}
void DFS(int i)
{
node *p;
printf("\n%d",i);
p=G[i];
visited[i]=1;
while(p!=NULL)
{
i=p->vertex;
if(!visited[i])
DFS(i);
p=p->next;
}
}
void read_graph()
{
int i,vi,vj,no_of_edges;
printf("Enter number of vertices:");
scanf("%d",&n);
//initialise G[] with a null
for(i=0;i<n;i++)
{
G[i]=NULL;
//read edges and insert them in G[]
printf("Enter number of edges:");
scanf("%d",&no_of_edges);
for(i=0;i<no_of_edges;i++)
{
printf("Enter an edge(u,v):");
scanf("%d%d",&vi,&vj);
insert(vi,vj);
}
}
}
void insert(int vi,int vj)
{
node *p,*q;
//acquire memory for the new node
q=(node*)malloc(sizeof(node));
q->vertex=vj;
q->next=NULL;
//insert the node in the linked list number vi
if(G[vi]==NULL)
G[vi]=q;
else
{
//go to end of the linked list
p=G[vi];
while(p->next!=NULL)
p=p->next;
p->next=q;
}
}
how does the backtracking happen after terminating the while loop in the function DFS() ? i donĀ“t get it
Thx
Well, this is not a DFS (Depth First Search), as nothing is searched for. All that your DFS function does is traverse all edges, marking their nodes as visited. Once done, you only know if this is a connected graph - if there are any edges that have not been visited, then they have not been marked, and so cannot be reached from G[0].
the original code is not mine .. i just found it on this website : http://www.thecrazyprogrammer.com/2014/03/depth-first-search-dfs-traversal-of-a-graph.html

can my code for reversing link list be further enhanced

Here is my program which creates a link list and also reverses it.
#include<stdio.h>
#include<stdlib.h>
struct node {
int data;
struct node *next;
};
struct node *list=NULL;
struct node *root=NULL;
static int count=0;
struct node *create_node(int);//function to create node
void travel_list(void);
void create_list(int);
void reverse_list(void);
int main()
{
int i, j, choice;
printf("Enter a number this will be root of tree\n");
scanf("%d", &i);
create_list(i);
printf("Enter 1 to enter more numbers \n 0 to quit\n");
scanf("%d", &choice);
while (choice!=0){
printf("Enter a no for link list\n");
scanf("%d",&i);
// printf("going to create list in while\n");
create_list(i);
travel_list();
printf("Enter 1 to enter more numbers \n 0 to quit\n");
scanf("%d", &choice);
}
printf("reversing list\n");
reverse_list();
travel_list();
}
// end of function main
void create_list (int data)
{
struct node *t1,*t2;
//printf("in function create_list\n");
t1=create_node(data);
t2=list;
if( count!=0)
{
while(t2->next!=NULL)
{
t2=t2->next;
}
t2->next=t1;
count++;
}
else
{
root=t1;
list=t1;
count++;
}
}
struct node *create_node(int data)
{
struct node *temp;
temp = (struct node *)malloc(sizeof(struct node));
temp->data=data;
temp->next=NULL;
// printf("create node temp->data=%d\n",temp->data);
// printf("the adress of node created %p\n",temp);
return temp;
}
void travel_list(void )
{
struct node *t1;
t1=list;
printf("in travel list\n");
while(t1!=NULL)
{
printf("%d-->",t1->data);
t1=t1->next;
}
printf("\n");
}
void reverse_list(void)
{
struct node *t1,*t2,*t3;
t1=list;
t2=list->next;
t3=list->next->next;
int reverse=0;
if(reverse==0)
{
t1->next=NULL;
t2->next=t1;
t1=t2;
t2=t3;
t3=t3->next;
reverse++;
}
while(t3!=NULL)
{
t2->next=t1;
t1=t2;
t2=t3;
list=t1;
travel_list();
t3=t3->next;
}
t2->next=t1;
list=t2;
}
Above is a fully working code.
I want to know if there can be further enhancement to the above code?
Make your indentation and whitespace usage consistent
Use meaningful identifiers rather than t1, t2 and t3
Make the data member a generic type, for example void * rather than int.
Don't use global variables, pass struct node * pointers to your functions.

Resources