Creating a Node for Linked List/Self Referential Structures - c

I'm trying to create a node to create a linked list, but I'm getting the error
"IntelliSense: a value of type "void *" cannot be assigned to an entity of type "C""
Isn't the value of C which is a synonym for B: NULL not void?
Therefore shouldn't the initial node be created with NULL and then manipulation of the linked list will occur?
I haven't continued the insert function because the creation of the node is not working
#include <stdio.h>
#include <stdlib.h>
struct A
{
char data;
struct A *nextPtr;
};
typedef struct A B;
typedef B *C;
void insert(C *sPtr, char value);
void print(C cPtr);
void menu(void);
int main (void)
{
menu();
C startPtr = NULL;
char c;
int x;
for (x = 0; x <6; x++)
{
insert(&startPtr, c);
print(startPtr);
}
}
void menu(void)
{
puts("Enter 1 to Add: \nEnter 2 to Remove \nEnter 3 to quit");
}
void print (C cPtr)
{
puts("Names in the List");
printf("%c ->",cPtr->data);
}
void insert(C *sPtr, char value)
{
C nPtr;
C pPtr;
C cPtr;
nPtr = malloc( sizeof (B));
}

Related

find function in linked list in c programming

I wanna write a program about linked list that gets a number and if the number was equal to the one of the nodes' data , gives the number of that node .
like the datas in 3 nodes are
123
56
78
and it gets a number like 56 and its equal to the second node's data so the output should be 2.
#include<stdio.h>
#include<stdlib.h>
struct node{
int data;
node *next;
};
node* cnode();
void find(node *first,int i,int d);
int main()
{
node *first,*last;
int n,i,x,d;
printf(" How many nodes ?\t");
scanf("%d",&x);
for(i=1;i<=x;i++){
last=cnode();
last->next=first;
first=last;
}
printf("\n enter a particular data:\t");
scanf("%d",&d);
printf("\n number of the particular node:\t");
find(first,i,d);
}
void find(node *first,int i,int d){
int count=0;
while (first != NULL)
{
if (first->data == d)
count++;
first = first->next;
}
if(count != 0){
printf("%d",count);
}
if(count == 0){
printf("\n NOT FOUND ! ");
}
}
According to the C Standard the function main without parameters shall be declared like
int main( void )
Secondly this declaration of the structure
struct node{
int data;
node *next;
};
is not a valid C declaration.
You should write
struct node{
int data;
struct node *next;
};
typedef struct node node;
or
typedef struct node{
int data;
struct node *next;
} node;
You have to initialize at least node first with NULL. Otherwise the program will have undefined behavior.
node *first = NULL,*last;
The parameter i is not used within the function find. So it may be removed.
void find(node *first, int d);
The function definition can look at least like
void find( node *first, int d )
{
int count = 0;
while ( first != NULL && first->data != d )
{
first = first->next;
++count;
}
if ( first != NULL )
{
printf("%d",count);
}
else
{
printf("\n NOT FOUND ! ");
}
}

Inserting nodes in a linked list in decreasing order - C

I have to make a list that arrange the people in decreasing order of their number('no' for my program). I tryed to make it by modifying the addNode function but I got no result(peoples do not arrange by their number). This is my code:
Header code:
#ifndef __EX__
#define __EX__
typedef struct Person{
char name[10];
float no;
struct Person *pNext;
} NODE, *pNODE, **ppNODE;
void addNode(ppNODE, pNODE);
void travers(pNODE, unsigned int*);
#endif
Functions folder:
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <math.h>
#include <string.h>
#include "EX.h"
void addNode (ppNODE ppPrim, pNODE p){
pNODE q = (pNODE)malloc(sizeof(NODE));
assert(q!=NULL);
printf("Add name: \n");
scanf("%s", &q->name);
printf("\nAdd no: ");
scanf("%f", &q->no);
if (p == NULL || q->no < p->no) {
q->pNext = *ppPrim;
*ppPrim = q;
} else {
q->pNext = p->pNext;
p->pNext = q;
}
return;
}
void travers(pNODE pPrim, unsigned int *pLen){
*pLen = 0;
pNODE tmp = pPrim;
while (tmp != NULL){
puts (tmp->name);
fprintf(stdout, " no %.2f\n", tmp->no);
tmp = tmp->pNext;
(*pLen)++;
}
return;
}
Main folder:
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <math.h>
#include <string.h>
#include "EX.h"
int main(){
unsigned int len;
pNODE prim = NULL;
int i;
for (i=0; i<=1; i++){
addNode(&prim, prim);
addNode(&prim, prim->pNext);
}
travers(prim, &len);
return 0;
}
When you insert a new node to the list, you must traverse the list until you find a suitable place to insert it. Your code takes a second argument, which isn't really needed and causes confusion, and only looks at that.
The code to insert a code q at the end of a list that is defined by its head is:
Node *prev = NULL;
Node *p = *head;
while (p) {
prev = p;
p = p->pNext;
}
q->pNext = p;
if (prev == NULL) {
*head = q;
} else {
prev->pNext = q;
}
You can get rid of keeping track of the previous node and the distinction between inserting at the head and inserting after that by traversing the list with a pointer to node pointer:
Node **p = &head;
while (*p && (*p)->no < q->no) {
p = &(*p)->pNext;
}
q->pNext = *p;
*p = q;
In this concise code, p holds the address of the head at first and the address of the pNext pointer of the previous node. Both can be updated via *p.
You can now use this code to traverse only as far as the numbers associated with each node are smaller than the one of the node to insert. here's a complete program:
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
typedef struct Node Node;
void addNode(Node **p, const char *name, float no);
void travers(Node *pPrim, unsigned int *pLen);
struct Node {
char name[10];
float no;
Node *pNext;
};
void addNode(Node **p, const char *name, float no)
{
Node *q = malloc(sizeof(*q));
assert(q != NULL);
snprintf(q->name, sizeof(q->name), "%s", name);
q->no = no;
while (*p && (*p)->no < q->no) {
p = &(*p)->pNext;
}
q->pNext = *p;
*p = q;
}
void traverse(const Node *pPrim, unsigned int *pLen)
{
*pLen = 0;
while (pPrim != NULL) {
fprintf(stdout, "%-12s%.2f\n", pPrim->name, pPrim->no);
pPrim = pPrim->pNext;
(*pLen)++;
}
}
int main()
{
unsigned int len;
Node *prim = NULL;
addNode(&prim, "Alice", 0.23);
addNode(&prim, "Bob", 0.08);
addNode(&prim, "Charlie", 0.64);
addNode(&prim, "Dora", 0.82);
traverse(prim, &len);
printf("\n%u entries.\n", len);
return 0;
}
Things to node:
I've used Node * and Node ** instead of the typedeffed pNODE and ppNODE. In my opinion using the C pointer syntax is clearer.
You should separate taking user input from adding a node.
In your code you shouldn't pass the address of the char array when scanning a string, just the char array. (It happens to work, but it isn't correct. The compiler should warn you about that.)

something about binary tree

This code is about binary tree.
It can work well.
But after I press the enter key and get the correct answer,it turns out stopping working.WHY?
This is the answer
source code:
#include <stdio.h>
#include <stdlib.h>
typedef struct BiTNode
{
char data;
struct BiTNode* rchild;
struct BiTNode* lchild;
}BiTNode;
typedef BiTNode* BiTree;
int CreateBiTree(BiTree *T);
void Visit(BiTree T);
void PreOrder(BiTree T);
void InOrder(BiTree T);
void PostOrder(BiTree T);
int main(void)
{
BiTree T;
CreateBiTree(&T);
PreOrder(T);
return 0;
}
int CreateBiTree(BiTree *T)
{
char data;
scanf("%c",&data);
if(data=='#')
{
*T==NULL;
}
else
{
*T=(BiTree)malloc(sizeof(BiTNode));
(*T)->data=data;
CreateBiTree(&(*T)->lchild);
CreateBiTree(&(*T)->rchild);
}
return 0;
}
void Visit(BiTree T)
{
printf("%c",T);
}
void PreOrder(BiTree T)
{
if(T!=NULL)
{
Visit(T);
PreOrder(T->lchild);
PreOrder(T->rchild);
}
}
In your Code you have many issues :-
In CreateBiTree(BiTree *T) function, you only modified single pointer for root, rchild and lchild. you should define Bitree *T locally in this function.
what is *T==NULL? Are you initializing or comparing?
scanf("%c",&data); this statement will also create a problem in character case. this statement will wait for '\n' also. so you should write scanf(" %c",&data).
*T=(BiTree)malloc(sizeof(BiTNode)); this statement is also wrong, malloc return pointer, so you should do correct type casting. *T=(BiTree *)malloc(sizeof(BiTNode));
i have modified you source code for your reference, have look
//it can work
#include<stdio.h>
#include<stdlib.h>
using namespace std;
typedef struct BiTNode
{
char data;
struct BiTNode* rchild;
struct BiTNode* lchild;
}BiTNode;
typedef BiTNode BiTree;
BiTree *CreateBiTree();
void Visit(BiTree **T);
void PreOrder(BiTree *T);
void InOrder(BiTree T);
void PostOrder(BiTree T);
int main(void)
{
BiTree *T;
T=CreateBiTree();
PreOrder(T);
return 0;
}
BiTree *CreateBiTree()
{
BiTree *T;
char data;
scanf(" %c",&data);
printf("............%c\n",data);
if(data=='#')
return NULL;
T=(BiTree *)malloc(sizeof(BiTree));
T->data=data;
printf("Enter left child of %c:\n",data);
T->lchild=CreateBiTree();
printf("Enter right child of %c:\n",data);
T->rchild=CreateBiTree();
return T;
}
void Visit(BiTree **T)
{
printf("%c",(*T)->data);
}
void PreOrder(BiTree *T)
{
if(T!=NULL)
{
Visit(&T);
PreOrder(T->lchild);
PreOrder(T->rchild);
}
}

String input by linked list

Is there any way to take a string input(as like we take for any integer) by linked list??
For example:This code is showing run time error:
struct node
{
char c;
struct node *link;
};
while(1)
{
val=getch();
if(val!=10)
add(&a[i],val);
else
break;
}
and I want to take any input string like - "asdfghj", of which string length was not known?
Given that you have a LinkedList-class that acts as an interface to the linked list and that it has the function addNode() that adds a node in a correct manner to the list.
I also assume that what you want to know is how to make every char in the inputted string a node in the linked list and that you know how to manage a linked list.
And assuming you're using C++11
int main()
{
LinkedList list;
string input;
cin >> input;
for(auto i: input)
{
list.addNode(i);
}
}
example for C
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
char c;
struct node *link;
} Node;
typedef struct s_ {
Node *top;
Node *curr;
} String;
Node *Node_new(char ch){
Node *p = calloc(1, sizeof *p);
p->c = ch;
return p;
}
String *String_new(void){
String *p = calloc(1, sizeof *p);
return p;
}
void String_drop(String *s){
Node *p = s->top;
while(p){
s->curr = p;
p = p->link;
free(s->curr);
}
//s->top = s->curr = NULL;
free(s);
}
void String_add(String *s, char c){
if(s->top == NULL){
s->curr = s->top = Node_new(c);
} else {
s->curr = s->curr->link = Node_new(c);
}
}
String *get_string(FILE *fp){
String *s = String_new();
int ch;
while(EOF!=(ch=fgetc(fp)) && ch !='\n'){
String_add(s, (char)ch);
}
return s;
}
void put_string(String *s){
Node *p;
for(p = s->top; p ; p = p->link)
putchar(p->c);
putchar('\n');
}
int main(void) {
String *s = get_string(stdin);
put_string(s);
String_drop(s);
return 0;
}
You can think easily. As You just can declare a string variable instead of char. And after that You can take input normally by creating a struct variable. For example:
#include <bits/stdc++.h>
using namespace std;
struct node
{
string s;
struct node *link;
};
int main(){
node ob;
cin>>ob.s;
cout<<ob.s;
}

hash table - linked lists - segmentation fault

I am trying to implement a hash table with linked list chaining. The following code below works -
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define TABSIZ 200
struct record {
struct record *next;
char name[BUFSIZ];
int data;
};
static struct record *htable[TABSIZ];
unsigned hash(char *s)
{
unsigned h;
for (h = 0; *s; s++)
h = *s;
//printf("%d", h%TABSIZ);
//I know its not a good hash function but i wanted to check chaining
return h % TABSIZ;
}
struct record *find(char *name)
{
struct record *item;
for (item = htable[hash(name)]; item; item = item->next)
{
if (strcmp(name, item->name) == 0)
return item;
}
return NULL;
}
struct record *insert(char *name,int value)
{
struct record *item;
unsigned h;
if ((item = find(name)) == NULL)
{
if ((item = malloc(sizeof (*item))) == NULL)
return NULL;
strcpy(item->name, name);
item->data=value;
h = hash(name);
item->next = htable[h];
htable[h] = item;
}
return item;
}
void printTable()
{
int i=0;
struct record *temp;
for(i=0;i<=TABSIZ;i++)
{
temp=htable[i];
while(temp!=NULL)
{
printf("\n%d - %s - %d\n", i,temp->name, temp->data);
temp=temp->next;
}
}
}
int main(void)
{
char buf[BUFSIZ];int value;
struct record *item;
do{
printf("Enter the name of the student:\n");
scanf("%s", buf);
if(strcmp(buf,"stop")==0) break;
printf("Enter the marks of the student:\n");
scanf("%d", &value);
if(insert(buf, value)==NULL)
{
break;
}
}while((strcmp(buf,"stop"))!=0);
printf("Enter a name to find: ");
scanf("%s", buf);
if((item=find(buf))!=NULL)
printf("The marks of the student is %d\n", item->data);
else printf("\n Not Found\n");
printTable();
return 0;
}
Now I am trying to remove the global variable and use local variable for the array of structures. I removed the global declaration of htable and declared it in main as
struct record *htable[TABSIZ];
and changed the functions to
struct record *find(struct record *htable, char *name);
struct record *insert(struct record *htable, char *name,int value);
and I'm calling the functions as
find(htable, name);
insert(htable,name,value);
but now my program is segfaulting. Am i passing the array of structures right? and have I declared it correctly. Any help would be greatly appreciated.
I was going down the wrong path with my earlier answer.
When it's a global, it's automatically initialized to 0.
When it's declared on the stack of main, it's not initialized.
Add a memset( htable, 0, sizeof(htable)) in main(), and that should return it to the previous behavior.
In printTable():
for(i=0;i<=TABSIZ;i++)
looks suspect. You prabably want:
void printTable()
{
unsigned int i;
struct record *temp;
for(i=0; i < TABSIZ;i++)
{
for (temp=htable[i]; temp!=NULL; temp=temp->next )
{
printf("\n%d - %s - %d\n", i,temp->name, temp->data);
}
}
}

Resources