Linked List in C - c

Although not requirement of my course, I am trying to implement single and double linked list to ensure I understand the concepts. I have worked out most of the issues I think except for one that I have tried to debug and printf my way out of. Although I have read different posts I cannot find out why they are not working similarly.
One my insert function when the while(h != NULL) kicks out I have to check the last item one more time because it would skip it. I thought about a do/while loop but that would not work.
I have the exact same loop for the search function and it finds the last item in the list using while(h != NULL) instead of kicking me before processing it.
Here is the loop that works from the search function,
while(h != NULL) //check list
if(h->val == s)
return true;
else
h = h->next;
Here is the loop that does not from the insert function, this one does not end up using the final value in the linked list before exiting the loop. If you read in the full code before I had to check if if (t->next == NULL && t->val > n) to get it to search the last item.
while(t->next != NULL) //assigns it in the middle
{
if(t->val < n)
t = t->next;
else
{
node* tt = t->prev;
tt->next = a;
a->next = t;
a->prev = t->prev;
t->prev = a;
return h; //returns original
}
}
Thanks in advance and hopefully I am explaining it. Difficult as I am attempting to learn what I do not know.
#include <stdio.h>
#include <stdlib.h> //for rand();
#include <stdbool.h> //bool function
typedef struct _node
{
int val;
struct _node* next;
struct _node* prev;
} node;
node* create(int n, node* h);
node* insert(int n, node* h);
bool search(int s, node* h);
void print(node* h);
void del(node* h);
int main()
{
node* h = NULL;
for(int i = 0; i < 15; i++)
{
int n = rand() % 15;
h = create(n, h);
}
print(h);
int s = 10; //number to search for
if(search(s, h))
printf("Found Item\n");
else
printf("Item not found\n");
del(h);
}
bool search(int s, node* h)
{
if(h == NULL)
printf("No nodes created to search.\n");
while(h != NULL) //check list
if(h->val == s)
return true;
else
h = h->next;
return false;
}
void del(node* h)
{
node* t = h;
while (h->next != NULL)
{
t = h->next;
h->next = NULL;
free(h);
h = t;
}
free(h);
}
node* insert(int n, node* h)
{
node* a = malloc(sizeof(node));
node* t = h;
if(a == NULL)
{
printf("Failed to create new node\n");
return NULL;
}
a->val = n; //sets new node to have value of n
if(h->val >= n) //assigns the integer to the beginning
{
a->next = t;
t->prev = a;
a->prev = NULL;
h = a; //assigns a new head since it appended the item to the beginning
return h;
}
while(t->next != NULL) //assigns it in the middle
{
if(t->val < n)
t = t->next;
else
{
node* tt = t->prev;
tt->next = a;
a->next = t;
a->prev = t->prev;
t->prev = a;
return h; //returns original
}
}
if (t->next == NULL && t->val > n) //check to see if second to last
{
node* tt = t->prev;
tt->next = a;
a->next = t;
a->prev = t->prev;
t->prev = a;
}
else
{
a->next = NULL;
a->prev = t;
t->next = a;
}
return h;
}
node* create(int n, node* h)
{
if(h == NULL) //create first node in the list
{
h = malloc(sizeof(node));
if(h == NULL)
{
printf("Failed to create first node\n");
return NULL;
}
h->val = n;
h->next = NULL;
h->prev = NULL;
}
else //create additional nodes in the list
h = insert(n, h);
return h;
}
void print(node* h)
{
if(h == NULL)
printf("List is empty\n");
else
while(h != NULL)
{
printf("%i\n", h->val);
h = h->next;
}
}

If I understand your question correctly, you are asking about these lines:
while(t->next != NULL) //assigns it in the middle
{
if(t->val < n)
t = t->next;
else
{
node* tt = t->prev;
tt->next = a;
a->next = t;
a->prev = t->prev;
t->prev = a;
return h; //returns original
}
}
if (t->next == NULL && t->val > n) //check to see if second to last
{
node* tt = t->prev;
tt->next = a;
a->next = t;
a->prev = t->prev;
t->prev = a;
}
else
{
a->next = NULL;
a->prev = t;
t->next = a;
}
and the question is: "How can to avoid repeating the code block from inside the while after the while"
Maybe something like this:
while(1)
{
if(t->val < n)
{
if (t->next == NULL) break;
t = t->next;
}
else
{
//assigns it in the middle
node* tt = t->prev;
tt->next = a;
a->next = t;
a->prev = t->prev;
t->prev = a;
return h; //returns original
}
}
// Add new node at the end
a->next = NULL;
a->prev = t;
t->next = a;

Related

Singly Linked List head of 0

I got problem with Singly Linked List problem.
When i inserted something in front of head. head is always have 0 of data.
I think init_list() function is something wrong. I think head of 0 is from randomly initialized data.
anything is fine without head 0 problem.
I'm sure that initializing method is wrong. But I don't know how to solve it..
Here is my I/0 and Desired Output
Input
2
insert 0 1
size
Output I got
1->0->NULL
2
1->0->NULL
Desired Output
1->NULL
1
1->NULL
Here is My Code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef int Element;
typedef struct LinkedNode {
Element data;
struct LinkedNode* link;
} Node;
Node* head;
void init_list() {
head = (Node*)malloc(sizeof(Node));
head->link = NULL;
}
int is_empty() {
if (head == NULL) return 1;
else return 0;
}
Node* get_entry(int pos)
{
Node* p = head;
int i;
for (i = 0; i < pos; i++, p=p->link){
if (p == NULL) return NULL;
}
return p;
}
int size()
{
Node* p;
int count = 0;
for (p = head; p != NULL; p = p->link)
count++;
return count;
}
void replace(int pos, Element val)
{
Node* node = get_entry(pos);
if (node != NULL)
node->data = val; // replace
}
Node* search_list(Element val)
{
Node* p;
for (p = head; p != NULL; p = p->link)
if (p->data == val) return p;
return NULL;
}
void insert_next(Node * before, Node * node)
{
if (node != NULL) {
node->link = before->link;
before->link = node;
}
}
void insert(int pos, Element val)
{
Node* new_node, * prev;
new_node = (Node*)malloc(sizeof(Node));
new_node->data = val;
if (pos == 0) {
new_node->link = head;
head = new_node;
}
else {
prev = get_entry(pos-1);
if (prev != NULL)
insert_next(prev, new_node);
else free(new_node);
}
}
Node * remove_next(Node * prev)
{
Node* removed = prev->link;
if (removed != NULL) {
prev->link = removed->link;
}
return removed;
}
void delete(int pos)
{
Node* prev, * removed;
if (pos == 0 && is_empty() == 0) {
removed = get_entry(pos);
head = head->link;
free(removed);
}
else {
prev = get_entry(pos-1);
if (prev != NULL) {
remove_next(prev);
free(removed);
}
}
}
void clear_list()
{
while (is_empty() == 0)
delete(0);
}
void print_list()
{
Node* p;
for (p = head; p != NULL; p = p->link)
printf("%d->", p->data);
printf("NULL\n");
}
Node * concat_list(Node * new_node)
{
if(is_empty()) return new_node;
else if(new_node == NULL) return new_node;
else{
Node* p;
p = head;
while (p->link != NULL) {
p = p->link;
}
p->link = new_node;
return head;
}
}
int main(void)
{
Element num;
int pos;
int n, i, j, len;
char c[15];
Node* tmp_head= NULL;
Node* new_head= NULL;
init_list();
scanf("%d", &n);
for (i = 0; i < n; i++)
{
scanf("%s", c);
if (strcmp(c, "insert") == 0) { scanf("%d %d\n",&pos, &num); insert(pos,num); print_list();}
else if (strcmp(c, "delete") == 0) { scanf("%d\n", &pos); delete(pos); print_list();}
else if (strcmp(c, "size") == 0) {printf("%d\n", size()); print_list();}
else if (strcmp(c, "empty") == 0) {printf("%d\n", is_empty()); print_list();}
else if (strcmp(c, "getEntry") == 0) { scanf("%d\n", &pos); printf("%d\n", get_entry(pos)->data); print_list();}
else if (strcmp(c, "search_list") == 0) { scanf("%d\n", &num); printf("%d\n", search_list(num)->data); print_list();}
else if (strcmp(c, "replace") == 0) { scanf("%d %d\n", &pos, &num); replace(pos,num); print_list();}
else if (strcmp(c, "concat_list") == 0) {
tmp_head = head;
init_list();
scanf("%d", &len);
for (j = 0; j < len; j++)
{
scanf("%d %d\n",&pos, &num); insert(pos,num);
}
printf("new_node: ");
print_list();
new_head = head;
head = tmp_head;
head = concat_list(new_head);
print_list();
}
else printf("error\n");
}
return 0;
}
The basic problem is that within init_list, the code only initializes link but not data. I'd suggest instead that you initialize head to NULL and simply use insert to create nodes.

Trying to build a linked-list with strings as its entries

I'm trying to create a linked-list with strings as it data, and I have to do some opperations with them, but the opperations are cleared for integers only.
Those are the functions I've done the past weeks:
struct node {
int data;
char* s;
struct node* next;
};
typedef struct node node;
int remove_by_data(node** L, int data) {
if (*L == NULL) {
return 0;
}
node* p = *L;
if (p->data == data) {
*L = p->next;
free(p);
return 1;
}
else {
while (p->next != NULL && p->next->data != data) {
p = p->next;
}
if (p->next == NULL) {
return 0;
}
else {
node* q = p->next;
p->next = p->next->next;
free(q);
return 1;
}
}
}
node* search(node* L, int data) {
node* p = L;
while (p != NULL) {
if (p->data == data)
return p;
p = p->next;
}
return NULL;
}
int insert_end(node** L, int data) {
node* aux = malloc(sizeof(node));
if (!aux)
return 0;
aux->data = data;
aux->next = NULL;
node* p = *L;
if (p == NULL) {
*L = aux;
}
else {
while (p->next) {
p = p->next;
}
p->next = aux;
}
return 1;
}
int insert_begin(node** L, int data) {
node* aux = malloc(sizeof(node));
if (!aux)
return 0;
aux->data = data;
aux->next = *L;
*L = aux;
return 1;
}
void print_data(node* L) {
node* p = L;
while (p != NULL) { // while (p) {
printf("%d ",p->data);
p = p->next;
}
printf("\n");
}
int cont(node* L, int N){
int cont=1;
node* atual= L;
while (atual != search(L, N)){
cont++;
atual = atual->next;
}
return cont;
}
void swap_node(node** L, int m, int n){
int i, t;
node* p;
node* q;
p = q = *L;
for(i=1; i<m; i++)
p = p->next;
for(i=1; i<n; i++)
q = q->next;
t = p->data;
p->data = q->data;
q->data = t;
}
I just don't know how to "convert" those functions to strings, and how can I store a string into a list

delete element from a list

#include <stdio.h>
#include <malloc.h>
struct el {
int info;
struct el* next;
};
struct el* create_el(struct el* Li)
{
int num;
printf("\n\nInsert number:\n\n");
scanf("%d", &num);
Li = (struct el*)malloc(sizeof(struct el));
if (Li != NULL) {
Li->info = num;
Li->next = NULL;
}
return (Li);
}
struct el* push(struct el* L, struct el* e)
{ //inserts the elements from the head of the list
if (L == NULL)
return (e);
else {
e->next = L;
L = e;
return (L);
}
}
void visualize(struct el* primo)
{
printf("\n\nList-->");
while (primo->next != NULL) {
printf("%d", primo->info);
printf("-->");
primo = primo->next;
}
if (primo->next == NULL)
printf("%d-->NULL", primo->info);
}
struct el* cancel(struct el** P, int val)
{ //delete element
struct el* prec = NULL;
struct el* curr = (*P);
if (P == NULL) //case empty list
return NULL;
else if (prec == NULL) {
if (curr->info == val) { //case 2 : if the element is the head
(*P)->next = curr->next;
free(curr);
curr = NULL;
}
}
else {
while ((curr != NULL) && (curr->info != val)) {
prec = curr;
curr = curr->next;
}
if (curr->next == NULL && curr->info == val) { // case 3: the elemnt is the last one
prec->next = NULL;
free(curr);
curr = NULL;
return (prec);
}
else {
if (curr->info == val) { //other cases
prec->next = curr->next;
free(curr);
curr = NULL;
return (prec);
}
}
}
}
int main()
{
struct el* head = NULL;
struct el* element;
struct el* list = NULL;
int i, n;
int elem;
printf("Insert the number of elements for the list:\n\n");
scanf("%d", &n);
for (i = 0; i <= n; i++) {
element = create_el(head);
if (element != NULL) {
list = push(list, element);
}
}
visualize(list);
printf("\n\nInsert the element that you want to cancel:");
elem = scanf("%d", &elem);
cancel(&list, elem);
visualize(list);
}
All I've wanted to do was delete an element from a listr, but after all the procediment the list is printed without any modification.
Can anyone see whats wrong in the function cancel(which is meant to delete an element by including any possible position of it)?
In your function cancel, P is definitely not NULL (assuming OS has assigned it an address initially).
prec is NULL the before execution enters if loop.
So, execution executes the line
if(curr->info==val)
Now, if the value, val, you have provided doesn't match curr->info then execution exits the function without deleting any node.

huffman tree in c prints memory address instead of values?

Here is a program to create huffman tree,
written by my junior.
what's error? perhaps it is printing memory addresses.
#include <stdio.h>
#include <stdlib.h>
struct link
{
int data;
struct link *next, *left, *right;
};
typedef struct link node;
node *curr = NULL, *head = NULL, *nnode = NULL;
void createheap();
void main()
{
node* i;
int k1, k2;
int ch;
int x;
printf("create node\nadd nodes\ntraverse node\nmake heap\n");
do
{
printf("enter the choice\n");
scanf("%d", &ch);
switch (ch)
{
case 1:
nnode = (node*)malloc(sizeof(node));
printf("enter number please\n");
scanf("%d", &x);
nnode->data = x;
nnode->next = NULL;
nnode->left = NULL;
nnode->right = NULL;
head = nnode;
curr = nnode;
break;
case 2:
nnode = (node*)malloc(sizeof(node));
printf("enter number please\n");
scanf("%d", &x);
nnode->data = x;
nnode->next = NULL;
nnode->left = NULL;
nnode->right = NULL;
curr->next = nnode;
curr = nnode;
break;
case 3:
printf("traverse\n");
for (i = head; i != NULL; i = i->next)
{
printf("%d\n", i->data);
}
break;
case 4:
createheap();
break;
default:
printf("this is wrong number\n");
}
} while (ch <= 5);
}
void createheap()
{
node* l;
node *t1, *t2, *t;
node *np, *r1;
int k1, k2, k3;
node* i;
// void traverse(node*);
l = head;
while (head->next != NULL)
{
l = head;
t = l;
nnode = (node*)malloc(sizeof(node));
t1 = t->next;
t2 = t->next->next;
k1 = t->data;
k2 = t1->data;
k3 = k1 + k2;
if (t2 == NULL)
{
nnode->left = t;
nnode->right = t1;
nnode->data = k3;
nnode->next = NULL;
curr = nnode;
head = nnode;
}
else if (k3 <= t2->data)
{
nnode->next = t2;
nnode->left = t;
nnode->right = t1;
nnode->data = k3;
head = nnode;
}
else if (k3 > t2->data)
{
nnode->left = t;
nnode->right = t1;
nnode->data = k3;
if (k3 <= curr->data)
{
for (i = t2; i != NULL; i = i->next)
{
if (i->data >= k3)
{
break;
}
else
{
np = i;
}
}
r1 = np->next;
nnode->next = r1;
np->next = nnode;
}
else if (k3 > curr->data)
{
nnode->next = NULL;
curr->next = nnode;
curr = nnode;
}
head = t2;
}
free(t);
free(t1);
printf("l %d\n", nnode->left);
printf("r %d\n", nnode->right);
printf("d %d\n", nnode->data);
}
// traverse(l);
// printf("\n%d",l->left->data);
// printf("\n%d",l->right->left->data);*/
}
void traverse(node* t)
{
if (t != NULL)
{
traverse(t->left);
printf("\n%d\n", t->data);
traverse(t->right);
}
}
"create node" means initialise the list and enter first value.
"add nodes" means add second, third and so on.. values. (please provided sorted values only for now)
"make heap" means create heap out of provided list, AND print left(l), right(r) and root values(d), from bottom of tree (as it gets made).
So, problem is root is printing correct value. but left and right are printing like.. 31298384, 31298323.

Binary tree implementation C

The 't' pointer in the insert() function is set to NULL every time I call the insert function. Is it something to do with messing up of pointers?
int main() {
int num, i;
tree *t;
t = NULL;
for(i = 0; i < 5; i++) {
scanf("%d", &num);
insert(t, num);
}
//inorder(t);
return 0;
}
The insert function is as follows:
void insert(tree *t, int num) {
int flag;
tree *p, *q;
tree *temp = (tree *)malloc(sizeof(tree));
temp->data = num;
temp->left = NULL;
temp->right = NULL;
if(t == NULL) {
t = temp;
printf("Hello");
return;
}
printf("%d", t->data);
p = t;
while(p) {
q = p;
if(p->data <= num) {
p = p->right;
flag = 1;
}
else {
p = p->left;
flag = 0;
}
if(flag == 1)
q->right = temp;
else
q->left = temp;
}
}
My tree structure is as follows :
typedef struct tree {
int data;
struct tree *left, *right;
}tree;

Resources