Double linked List functions - Driver program failure - c

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
typedef struct node_t{
int value;
struct node_t *prev;
struct node_t *next;
} Node;
typedef struct LinkedList{
Node *head;
Node *tail;
} LinkedList;
void clearing_space_for_LinkedList(LinkedList *ll){
ll->head = NULL;
ll->tail = NULL;
}
int empty_check(LinkedList *ll){
if(ll->head == NULL){
return 1;
}
else{
return 0;
}
}
void add_element_at_the_beginning(LinkedList *ll, int new_value){
Node *temporary = calloc(1,sizeof(Node));
temporary->value = new_value;
if (empty_check(ll)){
temporary->next = NULL;
temporary->prev = NULL;
ll->head = temporary;
ll->tail = temporary;
}
else{
temporary->next = ll->head;
temporary->prev = NULL;
ll->head->prev = temporary;
ll->head = temporary;
}
}
void add_element_at_the_end(LinkedList *ll, int new_value){
Node *temporary = calloc(1,sizeof(Node));
temporary->value = new_value;
if (empty_check(ll)){
temporary->next = NULL;
temporary->prev = NULL;
ll->head = temporary;
ll->tail = temporary;
}
else{
temporary->next = NULL;
temporary->prev = ll->tail;
ll->tail->next = temporary;
ll->tail = temporary;
}
}
int eliminate_the_first_element(LinkedList *ll){
Node *temporary = ll->head;
ll->head = ll->head->next;
ll->head->prev = NULL;
int result = temporary->value;
free(temporary);
return result;
}
int eliminate_the_last_element(LinkedList *ll){
Node *temporary = ll->tail;
ll->tail = ll->tail->prev;
ll->tail->next = NULL;
free(temporary);
return temporary->value;
}
void eliminate_the_single_element(LinkedList *ll){
Node *temporary = ll->head;
ll->head = NULL;
ll->tail = NULL;
free(temporary);
}
int add_element_on_another_spot(LinkedList *ll, int new_val){
int position = 0;
scanf("%d", &position);
Node *new_node = calloc(1,sizeof(Node));
new_node->value = new_val;
Node *iterator = ll->head;
for(int i = 0; i < position; ++i){
iterator = iterator->prev;
}
new_node->next = iterator;
new_node->prev = iterator->prev;
iterator->prev->next = new_node;
iterator->prev = new_node;
}
void print_the_linked_list(LinkedList *ll){
Node *curr = ll->head;
while (curr){
printf("%d, ", curr->value);
curr = curr->next;
}
printf("\n");
}
LinkedList * ll;
int main(){
clearing_space_for_LinkedList(ll);
add_element_at_the_beginning(ll, 10);
print_the_linked_list(ll);
}
When i try to run it i get Segmentation fault (core dumped)
Can someone explain why am i getting this message ?
And is my algorithm of creating and using double linked list rightly done ?
Also i am having hard time realizing really how to remove element?
Is the used function above correct for creating space for the list or this:
void clearing_space_for_LinkedList(LinkedList *linkedList) {
linkedList = (LinkedList*)calloc(1, sizeof(LinkedList));
linkedList->head = (Node*)calloc(1, sizeof(Node));
linkedList->tail = (Node*)calloc(1, sizeof(Node));
linkedList->head = NULL;
linkedList->tail = NULL;
}
Is it possible to create double linked list with arrays and if yes, how ?
Will just creating array for value in the typdef structure will work ?

Code has at least these problems:
No NULL check
clearing_space_for_LinkedList(LinkedList *ll) attempts ll->head even when ll == NULL which happens on OP's first call.
Code fails on last node elimination
eliminate_the_first_element() makes no provision for setting ll->tail to NULL should the last node get eliminated.
Similar problem with eliminate_the_last_element().

Related

I get an error when I initialize a string in a structure

I want to initialize a string with every char of it '\0'.(Because I will use gets() later, the first char being not '\0' is OK.)
So I use assign the string with "a".
Here is my code:
typedef struct node
{
char name[12] = "a";
struct node* next;
struct node* prev;
struct node* lead;
} node;
However,
if I change char name[12] = "a"; tochar name[12]; , it will be OK,
if I don't change, it will give an error message:
C:\UsersDesktop\exp1-2\main.c|7|error: expected ':', ',', ';', '}' or '__attribute__' before '=' token| and C:\Users\Desktop\exp1-2\main.c|25|error: 'node' {aka 'struct node'} has no member named 'name'|
Thank you in advance!
Above shows my part of code, if you wanna see a complete one, HRER are my complete code:
#include <stdio.h>
#include <string.h>
#include <malloc.h>
typedef struct node
{
char name[12] = "a";
struct node* next;
struct node* prev;
struct node* lead;
} node;
node* init()
{
node* huzong = (node*)malloc(sizeof(node));
node* wangzong = (node*)malloc(sizeof(node));
node* zhangzong = (node*)malloc(sizeof(node));
node* lizong = (node*)malloc(sizeof(node));
node* zhangsan = (node*)malloc(sizeof(node));
node* lisi = (node*)malloc(sizeof(node));
node* laoliu = (node*)malloc(sizeof(node));
node* xiaopeng = (node*)malloc(sizeof(node));
node* xiaochen = (node*)malloc(sizeof(node));
strcpy(huzong->name, "胡总");
huzong->lead = NULL;
huzong->prev = NULL;
huzong->next = wangzong;
strcpy(huzong->name, "王总");
wangzong->lead = zhangsan;
wangzong->prev = huzong;
wangzong->next = zhangzong;
strcpy(huzong->name, "张总");
zhangzong->lead = NULL;
zhangzong->prev = wangzong;
zhangzong->next = lizong;
strcpy(huzong->name, "黎总");
lizong->lead = NULL;
lizong->prev = zhangzong;
lizong->next = NULL;
strcpy(huzong->name, "张三");
zhangsan->lead = NULL;
zhangsan->prev = NULL;
zhangsan->next = lisi;
strcpy(huzong->name, "李四");
lisi->lead = xiaopeng;
lisi->prev = zhangsan;
lisi->next = laoliu;
strcpy(huzong->name, "老刘");
laoliu->lead = NULL;
laoliu->prev = lisi;
laoliu->next = NULL;
strcpy(huzong->name, "小彭");
xiaopeng->lead = NULL;
xiaopeng->prev = NULL;
xiaopeng->next = xiaochen;
strcpy(huzong->name, "小陈");
xiaochen->lead = NULL;
xiaochen->prev = xiaopeng;
xiaochen->next = NULL;
return huzong;
}
void list(node* head)
{
printf("%s", head->name);
list(head->lead);
list(head->next);
}
node* find(node* head, char* ex_name)
{
int i = 1;
i = strcmp((head->name), *ex_name);
if(i==0)
{
return head;
}
find(head->lead, ex_name);
find(head->next, ex_name);
return NULL;
}
void lead(node* new_node, node* existing)
{
existing->lead = new_node;
new_node->lead = NULL;
new_node->next = NULL;
new_node->prev = NULL;
}
void follow(node* new_node, node* existing)
{
existing->next = new_node;
new_node->prev = NULL;
new_node->lead = NULL;
new_node->next = NULL;
}
int main()
{
char input[60]="a";
char new_name[12]="a";
char ex_name[12]="a";
while(1)
{
node* head;
node* temp = NULL;
head = init();
gets(input);
for(int i = 0; i < 50; i++)
{
//init初始化实现
if(input[i]=='i'&&input[i+1]=='n'&&input[i+2]=='i'
&&input[i+3]=='t')
{
init();
printf("链表构造完成,现有9名员工");
}
//list遍历功能实现
if(input[i]=='l'&&input[i+1]=='i'&&input[i+2]=='s'
&&input[i+3]=='t')
{
list(head);
}
//lead功能实现
if(input[i]=='l'&&input[i+1]=='e'&&input[i+2]=='a'
&&input[i+3]=='d')
{
for(int j=0; j<=i-2; j++)
{
new_name[j] = input[j];
}
printf("%s", new_name);
for(int k=i+8; k<=i+20; k++)
{
ex_name[k-i-8] = input[k];
}
printf("%s", ex_name);
node* new_node = (node*)malloc(sizeof(node));
strcpy(new_node->name, new_name);
printf("strcpy完成");
temp = find(head, ex_name); //问题在此
printf("find完成");
temp->lead = new_node;
}
}
}
}
Your code is not valid C, as you cannot initialize struct fields in this manner.
char name[12] = "a";
Were you allocating the memory for name dynamically, I'd suggest using calloc which sets all bytes to zero.
For instance:
typedef struct node {
char *name;
...
} node;
node *new_node(char *name) {
node *n = malloc(sizeof(node));
n->name = calloc(12);
strncpy(n->name, name, 11);
return n;
}

making a copy of a single linked liked list

So what im trying to do is copying a linked list that, i made and to do so i know i need to transverse the list.
The problem is if i make a 1st copy it works but if i make a copy of the copy or another copy it gives segmentation fault and i dont understand why.
Program:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct Node {
int v;
struct Node* next;
}link;
link* insert(link* head,int data)
{
link* x;
if (head == NULL)
{
link *new = (link*) malloc(sizeof(struct Node));
new->v = data;
new->next = NULL;
return new;
}
for(x = head; x->next != NULL; x = x->next);
link *new = (link*) malloc(sizeof(struct Node));
new->v = data;
new->next = NULL;
x->next = new;
return head;
}
void print_lst(link* head)
{
link* t;
for (t = head; t != NULL; t = t->next)
printf("* %d\n",t->v);
}
link* copy_lst(const link* head)
{
const link* x;
link *copy;
if (head == NULL)
{
return NULL;
}
for(x = head; x->next != NULL; x = x->next)
{
copy->v = x->v;
copy->next = x->next;
}
return copy;
}
int main()
{
link *head = NULL;
head = insert(head,5);
head = insert(head,6);
link *head2 = NULL;
head2 = copy_lst(head);
print_lst(head2);
link *head3 = copy_lst(head2);
return 0;
}

linked list c programming error by inserting new element

I am trying to insert an element but it get the error "Process finished with exit code 11"
struct node {
int key;
struct node *next;
};
struct node* init(){
struct node *head =NULL;
return head;
}
void create(struct node * head,int num) {
struct node * tmp = head;
struct node * prev = NULL;
struct node* new = malloc(sizeof(struct node));
new->key = num;
prev = tmp;
tmp = tmp->next;
while(tmp!= NULL && tmp->key < num){
prev = tmp;
tmp = tmp->next;
}
new->next = tmp;
prev->next = new;
if (tmp== NULL)
head=tmp;
}
int main() {
int num;
struct node* head;
head=init()
printf("Enter data:");
scanf("%d",&num);
create(head,num);
}
i am trying to insert an element into a linked list and the element should be sorted and entered at the same time.can someone tell me that the error is ? i cannot seem to find out the error.
It's not clear what your function create()
void create(struct node * head, int num) {
struct node * tmp = head;
struct node * prev = NULL;
struct node* new = malloc(sizeof(struct node));
new->key = num;
prev = tmp;
tmp = tmp->next;
while (tmp != NULL && tmp->key < num) {
prev = tmp;
tmp = tmp->next;
}
new->next = tmp;
prev->next = new;
if (tmp == NULL)
head = tmp;
}
is supposed to do. You effectively pass it a NULL pointer and return void, so everything it does is meaningless to the outside world.
Thetm starting point for every no bs linked list implementation:
#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>
typedef struct node_tag {
int value;
struct node_tag *next;
} node_t;
// write functions to encapsulate the data and provide a stable interface:
node_t* node_create_value(int value)
{
node_t *new_node = calloc(1, sizeof *new_node);
if(new_node) new_node->value = value;
return new_node;
}
node_t* node_advance(node_t const *node) { return node->next; }
typedef struct list_tag { // a list usually consists of
node_t *head; // a pointer to the first and
node_t *tail; // a pointer to the last element
// size_t size; // one might want to add that.
} list_t;
list_t list_create(void)
{
list_t list = { NULL, NULL };
return list;
}
// make code based on these functions "speak" for itself:
node_t* list_begin(list_t const *list) { return list->head; }
node_t* list_end (list_t const *list) { return list->tail; }
bool list_is_empty(list_t const *list) { return !list_begin(list); }
// common operations for lists:
node_t* list_push_front(list_t *list, int value)
{
node_t *new_node = node_create_value(value);
if (!new_node)
return NULL;
new_node->next = list->head;
return list->head = new_node;
}
node_t* list_push_back(list_t *list, int value)
{
// push_back on an empty list is push_front:
if (list_is_empty(list))
return list->tail = list_push_front(list, value);
node_t *new_node = node_create_value(value);
if (!new_node)
return NULL;
list->tail->next = new_node;
return list->tail = new_node;
}
node_t* list_insert_after(list_t *list, node_t *node, int value)
{
if (list_end(list) == node)
return list_push_back(list, value);
node_t *new_node = node_create_value(value);
if (!new_node)
return NULL;
new_node->next = node->next;
return node->next = new_node;
}
node_t* list_insert_sorted(list_t *list, int value)
{
// first handle the special cases that don't require iterating the whole list:
if (list_is_empty(list) || value < list_begin(list)->value)
return list_push_front(list, value);
if (value > list_end(list)->value)
return list_push_back(list, value);
// the general (worst) case:
for (node_t *current_node = list_begin(list); node_advance(current_node); current_node = node_advance(current_node))
if (value < node_advance(current_node)->value)
return list_insert_after(list, current_node, value);
return NULL; // should never happen
}
void list_print(list_t const *list)
{
for (node_t *current_node = list_begin(list); current_node; current_node = node_advance(current_node))
printf("%d\n", current_node->value);
}
void list_free(list_t *list)
{
for(node_t *current_node = list_begin(list), *next_node; current_node; current_node = next_node) {
next_node = current_node->next;
free(current_node);
}
}
// user code should not be required to know anything about the inner workings
// of our list:
int main(void)
{
list_t list = list_create();
for (int i = 1; i < 10; i += 2) {
if (!list_push_back(&list, i)) {
list_free(&list);
fputs("Not enough memory :(\n\n", stderr);
return EXIT_FAILURE;
}
}
list_print(&list);
putchar('\n');
for (int i = 0; i < 11; i += 2) {
if (!list_insert_sorted(&list, i)) {
list_free(&list);
fputs("Not enough memory :(\n\n", stderr);
return EXIT_FAILURE;
}
}
list_print(&list);
list_free(&list);
}
Output:
1
3
5
7
9
0
1
2
3
4
5
6
7
8
9
10

Linked list reverse function leads to infinite printing loop

I was writing a C code to reverse a link list. I got into one problem.
If I do not make my next pointer NULL my reverse function works fine, but if I make it null the linked list always keeps printing in the while loop.
Below is the correct program, which works fine.
But if I make *next = NULL, the display function will keep printing in the while loop.
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node *next;
} *head;
/*************************************************************/
/* */
/* create - Function to create Nodes and add them at last */
/* */
/*************************************************************/
int create(int data)
{
struct node *temp,*ptr = NULL;
//int data = 0;
ptr = head;
//Printf(" Enter the Data for Node : ");
//scanf(" %d ", data);
temp = (struct node *)malloc(sizeof(struct node));
if (ptr == NULL) {
// this is the first node
temp->next = NULL;
temp->data = data;
head = temp;
} else {
// this is not the first node
while (ptr != NULL) {
if (ptr->next == NULL) {
temp->next = NULL;
temp->data = data;
ptr->next = temp;
break;
}
ptr = ptr->next;
}
}
return 0;
}
/*************************************************************/
/* */
/* create_in_front - Function to add Node in Front */
/* */
/*************************************************************/
int create_in_front(int data)
{
struct node *temp,*ptr = NULL;
ptr = head;
temp = (struct node *)malloc(sizeof(struct node));
if (ptr == NULL) {
// this is the first node
temp->next = NULL;
temp->data = data;
head = temp;
} else {
// this is not the first node
temp->next = ptr->next;
temp->data = data;
head = temp;
}
return 0;
}
/*************************************************************/
/* */
/* create_in_between - Function to add Node in between nodes*/
/* */
/*************************************************************/
int create_in_between(int data,int pos)
{
struct node *temp, *ptr = NULL;
int i = 0;
ptr = head;
temp = (struct node *)malloc(sizeof(struct node));
temp->data = data;
for (i = 0; i < pos; i++) {
if (i == pos-1) {
temp->next = ptr->next;
ptr->next = temp;
}
ptr = ptr->next;
}
return 0;
}
/*************************************************************/
/* */
/* delete_in_between - Function to add Node in between nodes*/
/* */
/*************************************************************/
delete_in_between(int pos)
{
struct node *ptr, *prev = NULL;
ptr = head;
int i = 0;
for (i = 0; i < pos; i++) {
if (i == pos-1) {
prev = ptr->next;
free(ptr);
break;
}
prev = ptr;
ptr = ptr->next;
}
return 0;
}
/*************************************************************/
/* */
/* reverse - Function to reverse link list */
/* */
/*************************************************************/
int reverse()
{
struct node *prev = NULL;
struct node *curr = head;
struct node *next = NULL;
curr = head;
while (curr != NULL) {
next = curr->next;
curr->next = prev;
prev = curr;
curr = next;
}
head = prev;
return 0;
}
/*************************************************************/
/* */
/* display - Function to diplay link list */
/* */
/*************************************************************/
// Function to display Link List
int display()
{
struct node *temp = head;
while (temp != NULL) {
printf("%d->",temp->data);
temp = temp->next;
}
return 0;
}
int main()
{
create(10);
create(20);
create(30);
create(40);
create(50);
create_in_front(34);
create_in_between(55,2);
//delete_in_between(4);
reverse();
display();
return 0;
}
Let me know the logic behind this.
Function create_in_front() is bogus: temp->next = ptr->next; should be changed to temp->next = ptr;
create_in_between() does not handle the case of pos==0.
delete_in_between() is completely dysfunctional: the node is frees but its predecessor still points to it.
reverse() seems correct to me, it could be simplified this way:
int reverse() {
struct node *prev = NULL;
struct node *curr = head;
while (curr != NULL) {
struct node *next = curr->next;
curr->next = prev;
prev = curr;
curr = next;
}
head = prev;
return 0;
}
The problem seems unrelated to your modifying the reverse() function, maybe a side effect of bugs in the other functions.
Your reverse() function seems correct, but the rest of the code is somewhat overcomplicated. Try something like this:
void create(int data) {
struct node *temp = malloc(sizeof(struct node));
if (temp != NULL) {
temp->next = NULL;
temp->data = data;
if (head == NULL) { // this is the first node
head = temp;
} else {
// this is not the first node
struct node *last = head;
while (last->next)
last = last->next;
last->next = temp;
}
}
}
void create_in_front(int data) {
struct node *temp = malloc(sizeof(struct node));
if (temp != NULL) {
temp->next = head;
temp->data = data;
head = temp;
}
}

How to dequeue en element from my custom queue

As an exercise, I'm trying to create a basic queue. I've got a problem in my deQueue method.
#include<stdio.h>
typedef int Task;
typedef struct QueueNode_ QueueNode;
typedef struct TQueue_ TQueue;
struct QueueNode_ {
QueueNode* next;
Task task;
};
struct TQueue_ {
QueueNode* first;
QueueNode* last;
};
TQueue* initializeQueue(){
TQueue* queue = NULL;
queue = malloc(sizeof(TQueue));
queue->first = NULL;
queue->last = NULL;
return queue;
}
void enQueue(TQueue* q, Task t){
if(q->first == NULL){
q->first = malloc(sizeof(QueueNode));
q->first->task = t;
q->first->next = NULL;
q->last = q->first;
} else {
QueueNode* node = malloc(sizeof(QueueNode));
node->next = q->last;
node->task = t;
q->last = node;
}
}
void printQueue(TQueue* q){
QueueNode* node = q->last;
printf("LAST->");
while(node != NULL){
printf("%d->", node->task);
node = node->next;
}
printf("FIRST\n");
}
QueueNode* deQueue(TQueue* q){
QueueNode* temp = q->first;
QueueNode* newFirst = q->last;
q->first = NULL;
while(newFirst != NULL){
newFirst = newFirst->next;
}
q->first = newFirst;
return temp;
}
int main(){
TQueue* queue = initializeQueue();
enQueue(queue, 1);
enQueue(queue, 2);
printQueue(queue);
QueueNode* node = deQueue(queue);
printf("%d\n", node->task);
printQueue(queue);
return 0;
}
I expected my deQueue method to remove the head of my queue. But that's not the case apparently.
Here's the output:
LAST->2->1->FIRST
1
LAST->2->1->FIRST
I suspect my deQueue method to not replace the head of the queue with the second element but I though I was doing this with q->first = newFirst;, so I'm a bit stuck.
Just if it's not clear I would expect it to print:
LAST->2->1->FIRST
1
LAST->2->FIRST
You might could do it like this:
QueueNode* deQueue(TQueue* q){
QueueNode *tmp = q->last;
while(tmp->next != q->first) {
tmp = tmp->next;
}
// new first is now the old second element
q->first = tmp;
// new firsts' next still points at
// old first so we free that memory here
free(q->first->next);
q->first->next = NULL;
return tmp;
}
Don't forget to free your memory.
You can test it here: http://www.compileonline.com/compile_c_online.php

Resources