#include<dos.h>
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
#define ESC 27
#define DISPOFFX 50
#define DISPOFFY 2
#define ENDOFX 80
#define ENDOFY 25
#define SPACING 1
#define INTLENGHT 6
#define MIN 0
#define MAX 1
#define TRUE 1
#define FALSE 0
#define ASCENDING 1
#define DESCENDING 2
struct linked_list
{
int data;
struct linked_list *link;
}*start;
typedef struct linked_list node;
int count=0,*posa=NULL;
struct display_flags
{
unsigned int disp_list:1;
unsigned int anim:1;
unsigned int delay_time:12;
unsigned int spacing:2;
}flag;
int srch(int);
int check(int);
int bubble(void);
int selection(void);
int insertion(void);
int posof(int,int);
void add(void);
void del(void);
void sort(int);
void swap(int);
void disp(void);
void move(void);
void flush(int);
void rotate(void);
void options(void);
void reverse(void);
node * gotopos(int);
void main(void)
{
char choice;
flag.disp_list = TRUE;
flag.anim = TRUE;
flag.delay_time = 0;
flag.spacing = 1;
while(1)
{
clrscr();
fflush(stdin);
posa = (int *) realloc(posa,count * sizeof(int));
flush(0);
disp();
printf("\n 1. Add Element");
printf("\n 2. Delete Element");
printf("\n 3. Search Element");
printf("\n 4. Swap Elements");
printf("\n 5. Sort the list");
printf("\n 6. Reverse the list");
printf("\n 7. Rotate list");
printf("\n 8. Move element");
printf("\n 9. List display options");
printf("\n\n Enter your choice.\n Press ESC to exit.");
switch(getch())
{
case '1': add(); getch(); continue;
case '2':
{
if(start==NULL)
{
printf("\n\n List already empty.");
}
else if(start->link == NULL)
{
printf("\n\n Element %d was deleted from position %d.",start->data,1);
free(start);
start = NULL;
count--;
disp();
}
else
{
printf("\n\n 1. Specify element");
printf("\n 2. Specify positions");
printf("\n 3. Discard duplicates");
printf("\n 4. Delete list");
printf("\n ESC to cancel.\n Enter your choice.");
switch(getch())
{
case '1': if(srch(1)) del(); break;
case '2': del(); break;
case '3': if(srch(2)) del(); getch(); break;
case '4': flush(1); del(); break;
case ESC: continue;
default : printf("\n Invalid choice."); getch(); break;
}
}
disp();
getch();
continue;
}
case '3': srch(0); getch(); continue;
case '4':
{
if(start==NULL) printf("\n\n List is empty!");
else if(start->link == NULL) printf("\n\n There exists only one element in the list.");
else if((start->link)->link == NULL)
{
posa[0] = 2;
posa[1] = 1;
posa[2] = 0;
swap(0);
}
else
{
printf("\n\n 1. Specify elements");
printf("\n 2. Specify positions");
printf("\n Enter your choice.\n ESC to cancel.");
switch(getch())
{
case '1':
{
if(srch(3))
{
if(srch(4)) swap(0);
}
break;
}
case '2': flush(2); swap(0); break;
case ESC: continue;
default : printf("\n Invalid choice!"); getch(); break;
}
}
getch();
continue;
}
case '5':
{
if(start == NULL) printf("\n\n List is empty!");
else if(start->link == NULL) printf("\n\n There exists only one element in the list.");
else
{
printf("\n\n 1. Bubble sort");
printf("\n 2. Selection sort");
printf("\n 3. Insertion sort");
printf("\n Enter yor choice.\n ESC to cancel.");
switch(getch())
{
case '1': if(!bubble()) continue; break;
case '2': if(!selection()) continue; break;
case '3': if(!insertion()) continue; break;
case ESC: continue;
default : printf("\n\n Invalid choice!"); break;
}
}
getch();
break;
}
case '6': reverse(); getch(); continue;
case '7': rotate(); getch(); continue;
case '8':
{
if(start == NULL) printf("\n\n List is empty!");
else if(start->link == NULL) printf("\n\n There exists only one element in the list.");
else if((start->link)->link == NULL)
{
posa[0] = 2;
posa[1] = 1;
posa[2] = 0;
swap(3);
printf("\n\n Elements moved.");
}
else
{
printf("\n\n 1. Specify element");
printf("\n 2. Specify position");
printf("\n Enter your choice.\n ESC to cancel.");
switch(getch())
{
case '1':
{
if(srch(5))
{
move();
printf(" Element moved.");
}
break;
}
case '2':
{
flush(4);
move();
printf(" Element moved.");
break;
}
case ESC: continue;
default : printf("\n\n Invalid choice!"); break;
}
}
disp();
getch();
continue;
}
case '9': options(); continue;
case ESC: exit(0);
default : printf("\n\n Invalid choice!"); getch(); continue;
}
}
}
void add(void)
{
int n,pos;
node *next,*temp,*temp2;
next = (node *) malloc(sizeof(node));
if(next==NULL) printf("\n\n No free space left!\n Close some running applications and try again.");
else
{
printf("\n\n Enter element: ");
scanf("%d",&next->data);
next->link = NULL;
fflush(stdin);
if(start==NULL)
{
start=next;
pos=1;
count++;
}
else
{
printf(" Enter the position of element to be added\n (Max: %d, '0' to add to end,\n -ve value to add to end): ",count+1);
scanf("%d",&pos);
while(pos>count+1)
{
if(count>1) printf(" Invalid position.\n Enter a number between 1 - %d\n '0' to cancel: ",count+1);
else if(count==1) printf(" Invalid position.\n Enter 1 or 2\n '0' to cancel: ");
scanf("%d",&pos);
}
if(pos==0) pos=count+1;
for(n=2,temp=start ; temp != NULL ; temp = temp->link,n++)
{
if(pos<0)
{
free(next);
break;
}
else if(pos==1)
{
next->link = start;
start = next;
count++;
break;
}
else if(pos==n)
{
temp2 = temp->link;
temp->link = next;
next->link = temp2;
count++;
break;
}
}
}
if(pos>0) printf(" Element %d was added successfully\n at position %d.",next->data,pos);
else printf(" Addition of element cancelled.");
disp();
}
}
int srch(int f)
{
int dat,dat2,i,j,cnt=0;
node *next;
if(start==NULL) printf("\n\n List's already empty!");
else if(start->link ==NULL) printf("\n\n There exist's only one element in the list.");
else
{
if(f==0) printf("\n\n Enter element to be searched: ");
else if(f==1) printf("\n\n Enter element to be deleted: ");
else if(f==2) printf("\n\n Enter element of which duplicates\n are to be removed: ");
else if(f==3) printf("\n\n Enter the first element to be swapped: ");
else if(f==4) printf("\n\n Enter the second element to be swapped: ");
else if(f==5) printf("\n\n Enter the element to be moved: ");
scanf("%d",&dat);
for(i=1,next=start ; next!=NULL ; next = next->link,i++)
{
if(dat == next->data)
{
posa[cnt++] = i;
printf("\n Element %d was found at position %d.",dat,i);
}
}
posa[cnt]=0;
if(f==5)
{
if(cnt==1)
{
printf("\n Enter the position to which the element is to be moved: ");
scanf("%d",&posa[1]);
posa[1] = check(posa[1]);
}
else
{
printf("Enter the position of element to be moved: ");
scanf("%d",&dat);
posa[0] = check(posa[0]);
printf("\n Enter the position to which the element is to be moved: ");
scanf("%d",&posa[1]);
posa[1] = check(posa[1]);
}
}
else if(f==3 || f==4)
{
if(cnt==1)
{
if(f==3) dat2 = posa[0];
else if(f==4)
{
posa[1] = dat2;
posa[2] = 0;
sort(0);
}
}
else
{
printf("\n Enter the position to be swapped: ");
scanf("%d",&dat);
if(f==3) dat2 = check(dat);
else if(f==4) dat = check(dat);
posa[0] = dat2;
posa[1] = dat;
posa[2] = 0;
sort(0);
}
}
else if(cnt==0) printf("\n Element %d was not found.",dat);
else if(f==1)
{
printf("\n %d element(s) found.",cnt);
if(cnt>1)
{
printf("\n Press Enter to delete all %ds.",dat);
printf("\n Any other key to select specific elements.");
if(getch() != 13) flush(0);
}
}
else if(f==2)
{
sort(1);
if(--cnt == 0) printf("\n No duplicates were found.");
else printf("\n %d duplicate(s) found.",cnt);
}
}
return(cnt);
}
void del(void)
{
int dat,i,f=0,delf=0,j,cnt;
node *next,*temp,*temp2;
cnt = count;
for(i=0;i<count;i++)
{
if( posa[i] != 0 )
{
delf=1;
break;
}
}
if(delf == 0) flush(3);
sort(0);
putchar('\n');
for(j=0;j<cnt;j++)
{
if(posa[j]==0) break;
for(i=1,next=start ; next!=NULL ; i++)
{
if(posa[j] == i)
{
f=1;
dat = next->data;
temp2 = next;
if(start == next) start = next->link;
else temp->link = next->link;
next = next->link;
free(temp2);
printf("\n Element %d was deleted from position %d.",dat,i);
count--;
if(flag.anim==TRUE)
{
disp();
delay(flag.delay_time);
}
break;
}
else
{
temp = next;
next = next->link;
}
}
}
if(f==0) printf("\n No element was deleted.");
disp();
}
void flush(int f)
{
int i=0;
if(f==1 || f==0)
{
while(i<count)
{
if(f==0) posa[i++] = 0;
else posa[i++] = i+1;
}
}
else if(f==2)
{
printf("\n\n Enter the positions of two elements\n to swap: ");
scanf("%d %d",&posa[0],&posa[1]);
while(posa[0] < 1 || posa[0] > count)
{
printf("\n Invalid position - %d. Try again: ",posa[0]);
scanf("%d",&posa[0]);
}
while(posa[1] < 1 || posa[1] > count)
{
printf("\n Invalid position - %d. Try again: ",posa[1]);
scanf("%d",&posa[1]);
}
posa[2]=0;
sort(0);
}
else if(f==3)
{
printf("\n\n Enter position of elements to delete\n (Zero to stop): ");
i=0;
do
{
scanf("%d",&posa[i++]);
while(posa[i-1]>count || posa[i-1]<0)
{
printf("\n %d - Invalid position! ",posa[i-1]);
scanf("%d",posa[i-1]);
}
}
while( (posa[i-1] != 0) && (i!=count) );
}
else if(f==4)
{
printf("\n\n Enter the position of element\n to be moved: ");
scanf("%d",&posa[0]);
while(posa[0]<1 || posa[0]>count)
{
printf("\n Invalid position! Try again: ");
scanf("%d",&posa[0]);
}
printf("\n Enter position to which element\n is to be moved: ");
scanf("%d",&posa[1]);
while(posa[1]<1 || posa[0]>count || posa[0]==posa[1])
{
if(posa[0]==posa[1]) printf("\n No effect of moving an element to its own position.");
else printf("\n Invalid position! Try again: ");
scanf("%d",&posa[1]);
}
}
}
int check(int dat)
{
int i,f=0;
while(f==0)
{
for(i=0;i<count;i++)
{
if(dat == posa[i])
{
f=1;
break;
}
}
if(f==0)
{
printf("\n Invalid Position! Try again: ");
scanf("%d",&dat);
}
}
return(dat);
}
void sort(int f)
{
int lp,ep,ci,i,temp;
ep = count-1;
for(i=0;i<count;i++)
{
if(posa[i] == 0) ep=i-1;
}
if(f==0)
{
for(ci=0;ci<ep;ci++)
{
lp=ci;
for(i=ci+1;i<=ep;i++) if(posa[lp] < posa[i]) lp=i;
temp = posa[ci];
posa[ci] = posa[lp];
posa[lp] = temp;
}
for(i=0 ; i<=ep ; i++)
{
for(ci=0;ci<i;ci++)
{
if(posa[ci] == posa[i])
{
for(lp=i;lp<ep;lp++) posa[lp] = posa[lp+1];
break;
}
}
}
}
else if(f==1) for(i=1;i<=ep;i++) posa[i] = posa[i+1];
}
void swap(int f)
{
int i;
node *t1,*t2,*pt1,*pt2,*next,*temp;
t1 = t2 = pt1 = pt2 = NULL;
if(posa[1] == 0) printf("\n No effect of swapping an element with itself.");
else
{
for(i=1,next=start ; next != NULL ; next = next->link, i++)
{
if(i == posa[0]) t1 = next;
if(i == posa[1]) t2 = next;
if(t1 == NULL) pt1 = next;
if(t2 == NULL) pt2 = next;
if((t1 != NULL) && (t2 != NULL)) break;
}
if( ((f == ASCENDING) && (t1->data < t2->data)) || ((f==DESCENDING) && (t1->data > t2->data)) || (f==0) || (f==3) )
{
if(posa[1] != 1)
{
temp = pt1->link;
pt1->link = pt2->link;
pt2->link = temp;
temp = t1->link;
t1->link = t2->link;
t2->link = temp;
}
else
{
temp = start;
start = pt1->link;
pt1->link = temp;
temp = t1->link;
t1->link = t2->link;
t2->link = temp;
}
if(flag.anim==TRUE)
{
disp();
delay(flag.delay_time);
}
if(f==0)
{
printf("\n The elements %d & %d have been swapped.\n",t1->data,t2->data);
printf("\n Elements | %*d | %*d",INTLENGHT,t1->data,INTLENGHT,t2->data);
printf("\n -------------------------------");
printf("\n Old positions | %*d | %*d",INTLENGHT,posa[0],INTLENGHT,posa[1]);
printf("\n New positions | %*d | %*d",INTLENGHT,posa[1],INTLENGHT,posa[0]);
disp();
}
}
}
}
void reverse(void)
{
int lb,m;
if(start == NULL) printf("\n\n List is empty!");
else if(start->link == NULL) printf("\n\n There exists only one element in the list.");
else
{
printf("\n\n Processing...");
for(m=count/2,lb=1 ; lb <= m ; lb++)
{
posa[0] = count - lb+1;
posa[1] = lb;
posa[2] = 0;
swap(3);
}
printf("Done!");
disp();
printf("\n\n The list has been reversed.");
}
}
int bubble(void)
{
char c;
int i,j;
printf("\n\n Bubble Sort the list in:");
printf("\n 1. Ascending order");
printf("\n 2. Descending order");
printf("\n Enter your choice.\n ESC to cancel.");
switch(c=getch(),c)
{
case '1':
case '2':
{
printf("\n\n Processing...");
for(i=count;i>=1;i--)
{
for(j=1;j<i;j++)
{
posa[0] = j+1;
posa[1] = j;
posa[2] = 0;
if(c=='1') swap(ASCENDING);
else if(c=='2') swap(DESCENDING);
}
}
printf("Done!");
if(c=='1') printf("\n\n The list has been sorted in\n ascending order using bubble sort.");
else if(c=='2') printf("\n\n The list has been sorted in\n descending order using bubble sort.");
break;
}
case ESC: break;
default : printf("\n\n Invalid choice!"); break;
}
disp();
return(ESC-c);
}
int selection(void)
{
char c;
int i;
printf("\n\n Selection Sort the list in:");
printf("\n 1. Ascending order");
printf("\n 2. Descending order");
printf("\n Enter your choice.\n ESC to cancel.");
switch(c=getch(),c)
{
case '1':
case '2':
{
printf("\n\n Processing...");
for(i=1;i<count;i++)
{
if(c=='1') posa[0] = posof(MIN,i);
else if(c=='2') posa[0] = posof(MAX,i);
posa[1] = i;
posa[2] = 0;
if(posa[0]!=posa[1]) swap(3);
}
printf("Done!");
if(c=='1') printf("\n\n The list has been sorted in\n ascending order using selection sort.");
else if(c=='2') printf("\n\n The list has been sorted in\n descending order using selection sort.");
break;
}
case ESC: break;
default : printf("\n\n Invalid choice!"); break;
}
disp();
return(ESC-c);
}
int insertion(void)
{
char c;
int i,j;
printf("\n\n Insertion Sort the list in:");
printf("\n 1. Ascending order");
printf("\n 2. Descending order");
printf("\n Enter your choice.\n ESC to cancel.");
switch(c=getch(),c)
{
case '1':
case '2':
{
printf("\n\n Processing...");
for(i=2;i<=count;i++)
{
for(j=i;j>1;j--)
{
posa[0] = j;
posa[1] = j-1;
posa[2] = 0;
if(c=='1') swap(ASCENDING);
else if(c=='2') swap(DESCENDING);
}
}
printf("Done!");
if(c=='1') printf("\n\n The list has been sorted in\n ascending order using insertion sort.");
else if(c=='2') printf("\n\n The list has been sorted in\n descending order using insertion sort.");
break;
}
case ESC: break;
default : printf("\n\n Invalid choice!"); break;
}
disp();
return(ESC-c);
}
int posof(int f,int lb)
{
int pos=0,i,element;
node *next;
if(start != NULL)
{
for(i=1,next = start ; next != NULL ; next = next->link,i++)
{
if(i==lb)
{
element = next->data;
pos=i;
}
if( (((element > next->data) && f==MIN) || ((element < next->data) && f==MAX)) && i>lb )
{
element = next->data;
pos = i;
}
}
}
return(pos);
}
void rotate(void)
{
int i,amt;
node *next;
if(start == NULL) printf("\n\n List is empty!");
else if(start->link == NULL) printf("\n\n There exists only one element in the list.");
else
{
printf("\n\n Rotate by how many elements?\n (+ve=right, -ve=left, 0=no effect): ");
scanf("%d",&amt);
amt %= count;
if(amt > 0)
{
for(i=1;i<=amt;i++)
{
posa[0] = count;
posa[1] = 1;
move();
}
printf("\n\n The list has been rotated in right\n direction by %d",amt);
}
else if(amt < 0)
{
for(i=1;i<=-amt;i++)
{
posa[0] = 1;
posa[1] = count;
move();
}
printf("\n\n The list has been rotated in left\n direction by %d",-amt);
}
else printf("\n The list has not been affected.");
}
disp();
}
node * gotopos(int pos)
{
int i;
node * next=NULL;
for(i=1,next=start ; next != NULL ; next = next->link,i++) if(pos == i) break;
return(next);
}
void move(void)
{
node *e1,*e2,*temp;
if(posa[0] == 1)
{
e2 = gotopos(posa[1]);
temp = start;
start = start->link;
e1 = e2->link;
e2->link = temp;
(e2->link)->link = e1;
}
else if(posa[1] == 1)
{
e2 = gotopos(posa[0]-1);
e1 = e2->link;
e2->link = (e2->link)->link;
temp = start;
start = e1;
e1->link = temp;
}
else
{
e1 = gotopos(posa[0]-1);
e2 = gotopos(posa[1]);
temp = e1->link;
e1->link = (e1->link)->link;
e1 = e2->link;
e2->link = temp;
temp->link = e1;
}
if(flag.anim==TRUE)
{
disp();
delay(flag.delay_time);
}
}
void options(void)
{
static int last;
unsigned int temp;
while(1)
{
clrscr();
if(flag.disp_list==TRUE) printf("\n\n\n D : [X] Display list");
else printf("\n\n\n D : [ ] Display list");
if(flag.anim==TRUE) printf("\n\n A : [X] Animate while processing (does slower processing)");
else printf("\n\n A : [ ] Animate while processing (does slower processing)");
printf("\n\n T : Animation scale = %-5u (Recommended range: 0-100)",flag.delay_time);
printf("\n\n S : Element Spacing in list = %-5u",flag.spacing);
printf("\n\n ESC : Back to main menu...");
switch(getch())
{
case 'd':
case 'D':
{
flag.disp_list = !flag.disp_list;
if(flag.disp_list==FALSE)
{
last = flag.anim;
flag.anim = FALSE;
}
else flag.anim = last;
continue;
}
case 'a':
case 'A': if(flag.disp_list==TRUE) flag.anim = !flag.anim; continue;
case 't':
case 'T':
{
gotoxy(28,8);
printf(" \b\b\b\b\b");
scanf("%u",&temp);
flag.delay_time = temp;
continue;
}
case 's':
case 'S':
{
gotoxy(36,10);
printf(" \b\b\b\b\b");
scanf("%u",&temp);
flag.spacing = temp;
continue;
}
case ESC: return;
}
}
}
void disp(void)
{
int i,j,x,y,n;
node *next;
x = wherex();
y = wherey();
for(i=DISPOFFX;i<=ENDOFX && flag.disp_list==TRUE;i++)
{
for(j=DISPOFFY;j<=ENDOFY-1;j++)
{
gotoxy(i,j);
putchar(' ');
}
}
gotoxy(DISPOFFX,DISPOFFY);
printf("Element Count: %-5d",count);
if(flag.disp_list==FALSE)
{
gotoxy(DISPOFFX,DISPOFFY+(1*SPACING));
printf("List Hidden!");
}
else if(flag.disp_list==TRUE)
{
gotoxy(DISPOFFX,DISPOFFY+(1*SPACING));
printf("START = 0x%04X",start);
if(start==NULL) printf(" (List Empty!)");
else
{
gotoxy(DISPOFFX,DISPOFFY+(2*SPACING));
printf("SR. | NODE | DATA ( LINK )");
gotoxy(DISPOFFX,DISPOFFY+(2*SPACING)+1);
printf("NO. | ADDR. | IN NODE ");
gotoxy(DISPOFFX,DISPOFFY+(2*SPACING)+2);
printf("------------------------------");
for(n=1,next=start ; next!=NULL ; next = next->link,n++)
{
gotoxy(DISPOFFX,DISPOFFY+(2*SPACING)+3+((n-1)*flag.spacing));
printf("%2d. | 0x%04X | %*d (0x%04X)",n,next,INTLENGHT,next->data,next->link);
}
}
}
gotoxy(x,y);
}