I have to read data from file countries.txt. The file contains countries name and their ID, insert them in a linked list (sorted insert alph.). Linked list node contains name of country, ID of country and pointer to root of binary tree which contains cities of that country. I have to insert cities from other file (cities.txt).
I insert countries successfully but I cant insert cities.
Here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct CITY{
char *name;
struct CITY *left;
struct CITY *right;
}nodeCity;
typedef struct COUNTRY{
char *name;
int id;
struct CITY *root;
struct COUNTRY *next;
}nodeCountry;
int listInsert(nodeCountry**, char*, int);
int printList(nodeCountry*);
nodeCity* findCity(nodeCountry*, int);
nodeCity* treeInsert(nodeCity*, char*);
int inorderPrint(nodeCity*);
int main()
{
nodeCountry *head;
int result, ID, k;
FILE *cities, *countries;
char buffer[1024];
nodeCity *root;
head = NULL;
countries = fopen("countries.txt", "r");
while(fscanf(countries, "%s %d", buffer, &ID) == 2)
result = listInsert(&head, buffer, ID);
cities = fopen("cities.txt", "r");
while(fscanf(cities, "%s %d", buffer, &ID) == 2)
{
root = findCity(head, ID);
root = treeInsert(root, buffer);
}
//result = printList(head);
scanf("%d", &k);
root = findCity(head, k);
result = inorderPrint(root);
return 0;
}
int inorderPrint(nodeCity *root)
{
int result;
if(root == NULL)
return NULL;
result = inorderPrint(root->left);
printf("%s\n", root->name);
result = inorderPrint(root->right);
return 1;
}
nodeCity* treeInsert(nodeCity *root, char *buffer)
{
printf("K");
if(root == NULL){
root = (nodeCity*)malloc(sizeof(nodeCity));
root->name = strdup(buffer);
root->left = NULL;
root->right = NULL;
}
else if(strcmp(buffer, root->name) > 0)
root->right = treeInsert(root->right, buffer);
else if(strcmp(buffer, root->name) < 0)
root->left = treeInsert(root->left, buffer);
return root;
}
nodeCity* findCity(nodeCountry *head, int ID)
{
while(head->id != ID)
head = head->next;
return head->root;
}
int listInsert(nodeCountry **head, char *buffer, int ID)
{
nodeCountry *current, *new_node;
if((*head) == NULL)
{
(*head) =
(nodeCountry*)malloc(sizeof(nodeCountry));
(*head)->name = strdup(buffer);
(*head)->id = ID;
(*head)->root = NULL;
(*head)->next = NULL;
return 1;
}
if(strcmp(buffer, (*head)->name) < 0)
{
new_node =
(nodeCountry*)malloc(sizeof(nodeCountry));
new_node->name = strdup(buffer);
new_node->id = ID;
new_node->root = NULL;
new_node->next = (*head);
(*head) = new_node;
return 1;
}
current = (*head);
while(current->next != NULL && strcmp(buffer, current->next->name) > 0)
current = current->next;
new_node = (nodeCountry*)malloc(sizeof(nodeCountry));
new_node->name = strdup(buffer);
new_node->id = ID;
new_node->next = current->next;
current->next = new_node;
new_node->root = NULL;
return 1;
}
int printList(nodeCountry *current)
{
while(current != NULL)
{
printf("%s\n", current->name);
current = current->next;
}
return 1;
}
Related
I am new to C programming and When I asked user to input a number for some reason my whole program gives this error
Program received signal SIGSEGV, Segmentation fault.
0x0000555555555753 in addData (word=0x7fffffffeb70 "", mode=2) at main.c:202
202 if (temp->next == NULL) {
(gdb)
HERE IS MY CODE
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#define MEMORY 6
#define MAX_word_LENGTH 11
int numberOfwords;
char words[MEMORY][MAX_word_LENGTH];
struct Node{
int data;
char *word;
struct Node *next, *prev;
};
struct Node *head, *tail;
struct Node* DlListDeleteLastNode(struct Node *head);
void addData(char *word, int mode);
void DisplayForward();
struct Node* deletePos(struct Node *head, int pos);
int getPostion(char *targetWord);
bool search(char *targetWord);
//struct Node* deletePos(struct Node *head, int pos);
int countWord(char *wording);
void insert_specified(char *wording, int pos);
int countNodes();
//void init(){
// head = NULL;
// tail = NULL;
//}
int main()
{
char name[100];
//char searchName[] = "barr";
printf("Enter number of words to be stored in the word stream: ");
int input;
scanf("%d", &input);
int i;
int count = 0;
for (i=0; i<input;i++){
count++;
printf("\nEnter name %d : ",count);
scanf ("%[^\n]%*c", name);
//scanf("%s[^\n]",words[i]);
addData(name, 2);
}
//for (int i = 0; i <4; i++) {
// strcpy(words[i],
//}
//insert_specified(searchName, 0);
//printf("%d\n", numberOfwords);
//DlListDeleteLastNode();
DisplayForward();
//int num = countNodes();
//printf("count %d", num);
//deletePos(head, 3);
//bool x = search(searchName);
//printf("%d\n", x);
//printf("%d\n", numberOfwords);
//DisplayForward();
//fflush(stdin);
printf("\nEntered names are:\n");
for(i=0;i<6;i++)
puts(words[i]);
}
int isEmpty(struct Node *h){
if(h==NULL)
return 1;
else
return 0;
}
void addData(char *word, int mode){
if (mode == 1) {
for (int i=0; i<5; i++) {
if (strcmp(words[i],word) == 0) {
//printf("found\n");
//printf("FOUND%s\n", word);
int x = getPostion(word);
//printf("index found %d/n", x);
//deletePos(head, x);
struct Node* temp = head;
struct Node* temp2 = NULL;
while (x > 1) {
temp = temp->next;
x--;
}
if (temp->next == NULL) {
head = DlListDeleteLastNode(head);
}
else {
temp2 = temp->prev;
temp2->next = temp->next;
temp->next->prev = temp2;
free(temp);
temp = NULL;
}
break;
}
//x index = getPostion()
}
if (numberOfwords >= 5) {
DlListDeleteLastNode(head);
struct Node *ptr;
ptr= malloc(sizeof *ptr);
ptr->word = malloc(sizeof(char) * 12);
//char nimI[20];
//baru->nim = malloc(12 * sizeof(char));
//strcpy(ptr->word, word);
if(head==NULL)
{
ptr->next = NULL;
ptr->prev=NULL;
strcpy(ptr->word, word);
//ptr->word= word;
head=ptr;
//head = ptr;
//tail = ptr;
}
else
{
//ptr->word=word;
strcpy(ptr->word, word);
ptr->prev=NULL;
ptr->next = head;
head->prev=ptr;
head=ptr;
}
numberOfwords++;
}
else {
struct Node *ptr;
ptr= malloc(sizeof *ptr);
ptr->word = malloc(sizeof(char) * 12);
//char nimI[20];
//baru->nim = malloc(12 * sizeof(char));
//strcpy(ptr->word, word);
if(head==NULL)
{
ptr->next = NULL;
ptr->prev=NULL;
strcpy(ptr->word, word);
//ptr->word= word;
head=ptr;
//head = ptr;
//tail = ptr;
}
else
{
//ptr->word=word;
strcpy(ptr->word, word);
ptr->prev=NULL;
ptr->next = head;
head->prev=ptr;
head=ptr;
}
numberOfwords++;
strcpy(words[numberOfwords], word);
}
}
else {
int flag = 0;
//int numWords = countNodes();
for (int i=0; i<8; i++) {
if (strcmp(words[i],word) == 0) {
//printf("found\n");
//printf("FOUND%s\n", word);
int x = getPostion(word);
//printf("index found %d/n", x);
//deletePos(head, x); //
struct Node* temp = head;
struct Node* temp2 = NULL;
while (x > 1) {
temp = temp->next;
x--;
}
if (temp->next == NULL) {
head = DlListDeleteLastNode(head);
}
else {
temp2 = temp->prev;
temp2->next = temp->next;
temp->next->prev = temp2;
free(temp);
temp = NULL;
}
flag = 1;
//DisplayForward();
//numberOfwords--;
break;
}
//x index = getPostion()
}
printf("\nflag num-> %d\n", flag);
//numberOfwords++;
int numWords = countNodes();
if (numWords >= 5 && flag==0) {
//printf("activated");
int max = 0;
char maxWord[50];
for (int i = 0; i < 8; i++) {
int num = countWord(words[i]);
if (num > max) {
max = num;
//printf("%d", max);
strcpy(maxWord, words[i]);
//printf("word %s\n", maxWord);
}
}
printf("most occured word: %s\n", maxWord);
int mostOccuredWordIndex = getPostion(maxWord);
printf("index: %d\n", mostOccuredWordIndex);
mostOccuredWordIndex--;
insert_specified(word, mostOccuredWordIndex);
DlListDeleteLastNode(head);
}
else if (numWords >= 5) {
//DlListDeleteLastNode(head);
//struct Node *ptr;
//ptr= malloc(sizeof *ptr);
//ptr->word = malloc(sizeof(char) * 12);
//char nimI[20];
//baru->nim = malloc(12 * sizeof(char));
//strcpy(ptr->word, word);
//Get most occured word in words array
//find the position of the most occured word
//int mostOccuredWordIndex = getPostion(maxWord);
//remove last element and insert new word into that position
//if position is in the last index then remove word and replace with the word
//if (mostOccuredWordIndex == 5) {
// printf("occurred");
//}
//
DlListDeleteLastNode(head);
numberOfwords = numberOfwords + 1;
struct Node *ptr;
ptr= malloc(sizeof *ptr);
ptr->word = malloc(sizeof(char) * 12);
if(head==NULL)
{
ptr->next = NULL;
ptr->prev=NULL;
strcpy(ptr->word, word);
//ptr->word= word;
head=ptr;
//head = ptr;
//tail = ptr;
}
else
{
//ptr->word=word;
strcpy(ptr->word, word);
ptr->prev=NULL;
ptr->next = head;
head->prev=ptr;
head=ptr;
}
}
else {
struct Node *ptr;
ptr= malloc(sizeof *ptr);
ptr->word = malloc(sizeof(char) * 12);
//char nimI[20];
//baru->nim = malloc(12 * sizeof(char));
//strcpy(ptr->word, word);
if(head==NULL)
{
ptr->next = NULL;
ptr->prev=NULL;
strcpy(ptr->word, word);
//ptr->word= word;
head=ptr;
//head = ptr;
//tail = ptr;
}
else
{
//ptr->word=word;
strcpy(ptr->word, word);
ptr->prev=NULL;
ptr->next = head;
head->prev=ptr;
head=ptr;
}
numberOfwords = numberOfwords + 1;
strcpy(words[numberOfwords], word);
}
DisplayForward();
numWords = countNodes();
printf("\nnumber of words%d \n", numWords);
}
}
struct Node* DlListDeleteLastNode(struct Node *head) {
struct Node *temp = head;
struct Node* temp2;
while (temp->next != NULL) {
temp = temp->next;
}
temp2 = temp->prev;
temp2->next = NULL;
free(temp);
numberOfwords--;
return head;
}
void DisplayForward() {
//Node current will point to head
struct Node *current = head;
if(head == NULL) {
printf("List is empty\n");
return;
}
printf("[");
int count = numberOfwords;
// while current->next != Null
while(current!=NULL) {
//Prints each node by incrementing pointer.
printf("%s, ", current->word);
current = current->next;
count--;
}
//current = current->next;
//printf("%s]\n", current->word);
//printf("%d", numberOfwords);
}
bool search(char *targetWord) {
int pos = 0;
if(head==NULL) {
printf("Linked List not initialized");
return;
}
struct Node *current = head;
//current = head;
while(current!=NULL) {
pos++;
if(strcmp(current->word, targetWord) == 0) {
printf("%s found at position %d\n", targetWord, pos);
return true;
}
if(current->next != NULL)
current = current->next;
else
break;
}
return false;
//printf("%s does not exist in the list\n", targetWord);
}
int getPostion(char *targetWord) {
int pos = 0;
if(head==NULL) {
printf("Linked List not initialized");
return -1;
}
struct Node *current = head;
//current = head;
while(current!=NULL) {
pos++;
if(strcmp(current->word, targetWord) == 0) {
//printf("%s found at position %d\n", targetWord, pos);
return pos;
}
if(current->next != NULL)
current = current->next;
else
break;
}
return -1;
//printf("%s does not exist in the list\n", targetWord);
}
int countWord(char *wording) {
int count = 0;
for(int i=0;i<6;i++) {
if (strcmp(words[i], wording)==0) {
//printf("found word");
count++;
}
}
return count;
}
void insert_specified(char * wording, int pos)
{
struct Node *ptr;
ptr= malloc(sizeof *ptr);
ptr->word = malloc(sizeof(char) * 12);
struct Node *temp;
int i;
if(ptr == NULL)
{
printf("\n OVERFLOW");
}
else
{
//printf("\nEnter the location\n");
//scanf("%d",&loc);
temp=head;
for(i=0;i<pos;i++)
{
temp = temp->next;
if(temp == NULL)
{
printf("\ncan't insert\n");
return;
}
}
strcpy(ptr->word, wording);
ptr->next = temp->next;
ptr -> prev = temp;
temp->next = ptr;
temp->next->prev=ptr;
printf("Node Inserted\n");
}
}
int countNodes() {
int counter = 0;
//Node current will point to head
struct Node *current = head;
while(current != NULL) {
//Increment the counter by 1 for each node
counter++;
current = current->next;
}
return counter;
}
I tried to ask the user for a number of words it wants to input for my program to store the items in a doubly linked list but instead gives a segmentation fault error
struct Node *head is a global variable which is zero initialized. In addData() you set struct Node* temp = head; and then you deference temp like your stack trace shows which will segfault.
Anyways, before you even get there the 2nd scanf() fails as it the input buffer contains the \n from reading the previous number. The syntax of the format string also looks wrong to me. In any case as you don't check the return value of you are operating on uninitialized data. Here is the minimal fix:
if(scanf(" %99[^\n]*", name) != 1) {
printf("scanf failed\n");
return 1;
}
I also replaced the hard-coded < 8 with < MEMORY to avoid a buffer overflow. Here is an example run:
Enter number of words to be stored in the word stream: 2
Enter name 1 : test
flag num-> 0
[test,
number of words1
Enter name 2 : test2
flag num-> 0
[test2, test,
number of words2
[test2, test,
Entered names are:
test
test2
Is it possible to have multiple data inside a single linked list node in C? And how do you input and access data with this?
#include <stdio.h>
#include <stdlib.h>
struct node{
int data;
char name[30];
struct node *next;
};
struct node *head, *tail = NULL;
void addNode(int data, char string) {
struct node *newNode = (struct node*)malloc(sizeof(struct node));
newNode->data = data;
newNode->name[30] = string;
newNode->next = NULL;
if(head == NULL) {
head = newNode;
tail = newNode;
}
else {
tail->next = newNode;
tail = newNode;
}
}
void sortList() {
struct node *current = head, *index = NULL;
int temp;
if(head == NULL) {
return;
}
else {
while(current != NULL) {
index = current->next;
while(index != NULL) {
if(current->data > index->data) {
temp = current->data;
current->data = index->data;
index->data = temp;
}
index = index->next;
}
current = current->next;
}
}
}
void display() {
struct node *current = head;
if(head == NULL) {
printf("List is empty \n");
return;
}
while(current != NULL) {
printf("%d - %s", current->data, current->name);
current = current->next;
}
printf("\n");
}
int main()
{
char string1[10] = "Aaron";
char string2[10] = "Baron";
char string3[10] = "Carla";
addNode(9, string1);
addNode(7, string2);
addNode(2, string3);
printf("Original list: \n");
display();
sortList();
printf("Sorted list: \n");
display();
return 0;
}
I don't understand why my code didn't work. I was trying to make use of single linked list where it can accept/input and print/output the number and the name at the same time.
What I want it to happen is to print the number and the name.
The output should be:
Carla - 2
Baron - 7
Aaron - 9
Please read my comments marked as // CHANGE HERE.
// CHANGE HERE: accept a character array as argument
void addNode(int data, char string[]) {
struct node *newNode = (struct node*)malloc(sizeof(struct node));
newNode->data = data;
// CHANGE HERE: copy char array argument to name
strncpy(newNode->name, string, 30);
newNode->next = NULL;
if(head == NULL) {
head = newNode;
tail = newNode;
}
else {
tail->next = newNode;
tail = newNode;
}
}
void sortList() {
struct node *current = head, *index = NULL;
int temp;
char temp1[30];
if(head == NULL) {
return;
}
else {
while(current != NULL) {
index = current->next;
while(index != NULL) {
if(current->data > index->data) {
temp = current->data;
current->data = index->data;
index->data = temp;
// CHANGE HERE: swap the name along with data
strncpy(temp1, current->name, 30);
strncpy(current->name, index->name, 30);
strncpy(index->name, temp1, 30);
}
index = index->next;
}
current = current->next;
}
}
}
void display() {
struct node *current = head;
if(head == NULL) {
printf("List is empty \n");
return;
}
while(current != NULL) {
printf("%d - %s\n", current->data, current->name);
current = current->next;
}
printf("\n");
}
I am trying to delete a node at a specific location but I keep getting a segmentation fault 11.
I am reading the position and value from a file.
Here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct node {
float val;
struct node *prev;
struct node *next;
}node_t;
void printForward(node_t *head) {
node_t *current = head;
while (current != NULL) {
printf("%.2f\n", current->val);
current = current->next;
}
}
void printBackward(node_t *head) {
node_t *current = head;
while (current->next != NULL) {
current = current->next;
}
while (current != NULL) {
printf("%.2f\n", current->val);
current = current->prev;
}
}
void deleteAtPos(node_t **head, int pos) {
int i;
node_t *current = *head;
node_t *temp = NULL;
if (pos == 0) {
temp = (*head)->next;
free(*head);
(*head) = temp;
(*head)->prev = NULL;
return;
}
for (i = 0; i < (pos - 1); i++) {
if (current->next != NULL) {
current = current->next;
}
}
temp = current->next;
current->next = temp->next;
free(temp);
}
// Fix insert at position
void insertAtPos(node_t **head, int pos, float val) {
int i;
node_t *newNode = malloc(sizeof(node_t));
node_t *current = *head;
newNode->val = val;
if (pos == 0) {
newNode->next = (*head);
newNode->prev = NULL;
(*head)->prev = newNode;
(*head) = newNode;
return;
}
for (i = 0; i < pos; i++) {
if (current->next != NULL) {
current = current->next;
}
else {
printf("Node does not exist\n");
break;
}
}
current->prev->next = newNode;
newNode->prev = current->prev;
newNode->next = current;
current->prev = newNode;
}
void addEnd(node_t **head, float val) {
node_t *current = *head;
node_t *newNode = malloc(sizeof(node_t));
newNode->next = NULL;
newNode->val = val;
if (*head == NULL) {
*head = newNode;
newNode->prev = NULL;
return;
}
while (current->next != NULL) {
current = current->next;
}
current->next = newNode;
newNode->prev = current;
}
int main(int argc, char *argv[]) {
if (argc != 2) {
printf("Error");
}
node_t *head = NULL;
FILE *fp;
int i = 0, x;
float valLine1, valLine2, valLine3;
char buffer[200], *token, *del = ",";
float posVals[200], delPos[200];
fp = fopen(argv[1], "r");
fgets(buffer, sizeof(buffer), fp);
token = strtok(buffer, del);
while (token != NULL) {
valLine1 = atof(token);
addEnd(&head, valLine1);
token = strtok(NULL, del);
}
printForward(head);
printf("\n");
del = ":,";
fgets(buffer, sizeof(buffer), fp);
token = strtok(buffer, del);
while (token != NULL) {
valLine2 = atof(token);
posVals[i] = valLine2;
token = strtok(NULL, del);
i++;
}
for (x = 0; x < i; x += 2) {
insertAtPos(&head, posVals[x + 1], posVals[x]);
}
printForward(head);
fgets(buffer, sizeof(buffer), fp);
i = 0;
token = strtok(buffer, del);
while (token != NULL) {
valLine3 = atof(token);
delPos[i] = valLine3;
token = strtok(NULL, del);
i++;
}
printf("\n");
for (x = 0; x < i; x++) {
deleteAtPos(&head, delPos[x]);
}
printForward(head);
printf("\n");
printBackward(head);
fclose(fp);
}
The trouble is with my deleteAtPos function but I can't figure out why.
Here is the output:
24.00
0.04
17.00
-200.10
34.60
0.00
Segmentation fault: 11
And here is the contents of the file:
17,32.5,12,0,34.6,-200.1,17,0.04,24
1:2,4.1:5,-12:4
3,5,0
Please help!
Thank you
I have modified your deleteAtPos() function now you can delete at any position and your backward() function will print correct values.
void deleteAtPos(node_t **head, int pos) {
int i;
node_t *current = *head;
node_t *temp = NULL;
if (pos == 0) {
temp = (*head)->next;
free(*head);
(*head) = temp;
(*head)->prev = NULL;
return;
}
for (i = 0; i < (pos - 1); i++) {
if (current->next != NULL) {
current = current->next;
}
}
temp = current;
if(current->next==NULL)
{
current->prev->next = current->next;
}
else
{
current->prev->next = current->next;
current->next->prev = current->prev;
}
free(temp);
}
You are saying the trouble is with deleteAtPos. But your code is very far from an SSCCE, so I don't want to isolate the problem for you - you should do that, and most of the time, during the process of isolation, you will find the answer. If not, you can then post the question here.
Therefore I will just list the things I can see are wrong with deleteAtPos and maybe if you fix all of them, the problem will disappear.
You are not handling the situation where *head is NULL, the list has 0 elements. This would surely segfault.
You are not checking that pos >= 0.
You are not correctly handling the case where your list has one element, either. Another segfault.
You are not correctly handling the case where pos is the end of your list. Another segfault.
Where is error the following code?
addNode() function is not run, neither is the traverse() function.
Last data is not shown.
#include <stdio.h>
#include <stdlib.h>
struct isimler{
char isim[10];
struct isimler *next;
};
typedef struct isimler node;
node *head;
void createList(){
int k, n;
node *po;
printf("Eleman Sayisi: "); scanf("%d", &n);
for(k = 0; k<n; k++){
if(k == 0){
head = (node *) malloc(sizeof(node));
po = head;
}else{
po->next = (node *) malloc(sizeof(node));
po = po->next;
}
printf("Isim Girin: "); scanf("%s",po->isim);
}
po->next = NULL;
}
void addNode(){
node *po, *newNode;
po = head;
while(po != NULL){
po = po->next;
}
po = (node *) malloc(sizeof(node));
printf("Isim Girin: "); scanf("%s", po->isim);
po->next = NULL;
}
void traverseList(){
node *po;
int i=0;
po = head;
while(po != NULL){
printf("%d.\t%s\n",i,po->isim);
po = po->next;
i++;
}
}
int main(){
createList();
traverseList();
addNode();
traverseList();
return 1903;
}
Your current addNode() method creates a new node but it doesn't add it to your linked list.
You need to modify your addNode() method like so:
void addNode(){
node *po, *newNode;
po = head;
while(po->next != NULL) { // change this so you don't lose the end of the list
po = po->next; // po is now pointing to the last node in the list
}
newNode = (node *) malloc(sizeof(node)); // change this to newNode
printf("Isim Girin: "); scanf("%s", newNode->isim);
po->next = newNode; // add the new node here, don't set it to NULL
newNode->next = NULL;
}
You can have look this code and get to know where exactly you are having problem
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
struct test_struct
{
int val;
struct test_struct *next;
};
struct test_struct *head = NULL;
struct test_struct *curr = NULL;
struct test_struct* create_list(int val)
{
printf("\n creating list with headnode as [%d]\n",val);
struct test_struct *ptr = (struct test_struct*)malloc(sizeof(struct test_struct));
if(NULL == ptr)
{
printf("\n Node creation failed \n");
return NULL;
}
ptr->val = val;
ptr->next = NULL;
head = curr = ptr;
return ptr;
}
struct test_struct* add_to_list(int val, bool add_to_end)
{
if(NULL == head)
{
return (create_list(val));
}
if(add_to_end)
printf("\n Adding node to end of list with value [%d]\n",val);
else
printf("\n Adding node to beginning of list with value [%d]\n",val);
struct test_struct *ptr = (struct test_struct*)malloc(sizeof(struct test_struct));
if(NULL == ptr)
{
printf("\n Node creation failed \n");
return NULL;
}
ptr->val = val;
ptr->next = NULL;
if(add_to_end)
{
curr->next = ptr;
curr = ptr;
}
else
{
ptr->next = head;
head = ptr;
}
return ptr;
}
struct test_struct* search_in_list(int val, struct test_struct **prev)
{
struct test_struct *ptr = head;
struct test_struct *tmp = NULL;
bool found = false;
printf("\n Searching the list for value [%d] \n",val);
while(ptr != NULL)
{
if(ptr->val == val)
{
found = true;
break;
}
else
{
tmp = ptr;
ptr = ptr->next;
}
}
if(true == found)
{
if(prev)
*prev = tmp;
return ptr;
}
else
{
return NULL;
}
}
int delete_from_list(int val)
{
struct test_struct *prev = NULL;
struct test_struct *del = NULL;
printf("\n Deleting value [%d] from list\n",val);
del = search_in_list(val,&prev);
if(del == NULL)
{
return -1;
}
else
{
if(prev != NULL)
prev->next = del->next;
if(del == curr)
{
curr = prev;
}
else if(del == head)
{
head = del->next;
}
}
free(del);
del = NULL;
return 0;
}
void print_list(void)
{
struct test_struct *ptr = head;
printf("\n -------Printing list Start------- \n");
while(ptr != NULL)
{
printf("\n [%d] \n",ptr->val);
ptr = ptr->next;
}
printf("\n -------Printing list End------- \n");
return;
}
int main(void)
{
int i = 0, ret = 0;
struct test_struct *ptr = NULL;
print_list();
for(i = 5; i<10; i++)
add_to_list(i,true);
print_list();
for(i = 4; i>0; i--)
add_to_list(i,false);
print_list();
for(i = 1; i<10; i += 4)
{
ptr = search_in_list(i, NULL);
if(NULL == ptr)
{
printf("\n Search [val = %d] failed, no such element found\n",i);
}
else
{
printf("\n Search passed [val = %d]\n",ptr->val);
}
print_list();
ret = delete_from_list(i);
if(ret != 0)
{
printf("\n delete [val = %d] failed, no such element found\n",i);
}
else
{
printf("\n delete [val = %d] passed \n",i);
}
print_list();
}
return 0;
}
I am unsure how to set a pointer to a pointer to build a tree. Like once I have traveled to a leaf and call insert, how should I insert another element calling insert with the root node or the address of the root pointer? I think the problem with this function is the name root where that should be the double pointer right?
#include "bst.h"
#include <stdio.h>
#include <stdlib.h>
//arbitrary list of temp nodes
TreeNode *new_node, *root, *tmp, *parent;
int elemArray[100], i1, i2, i0;
int main( int argc, char *argv[] ) {
//Throw error is *Argv[] is not an integer
//assuming it was an integer
int cnt = atoi( argv[1] );
printf( "number is %d\n", cnt );
//
printf("Enter %i integer values to place in tree:\n", cnt);
for ( i1 = 0; i1 < cnt; ++i1) {
scanf( "%d", &elemArray[i1] );
}
//first ouput "INput Values"
printf( " Input Values:\n " );
for ( i2 = 0; i2 < cnt; ++i2) {
printf( "%d\n", elemArray[i2] );
}
TreeNode** root = (TreeNode*)malloc(sizeof(TreeNode*));
buildTree(root, elemArray, cnt );
printf( "Preorder:\n ");
//traverse
//TreeNode* tempN = malloc(sizeof(TreeNode*));
//tempN->data= 5;
traverse( root, PREORDER);
//traverse a single node
printf( "Inorder:\n ");
printf( "Postorder:\n ");
//Build tree with each element
return 0;
}
This is the .h file
/// The definition of the tree structure
typedef struct TreeNode {
int data ; // the data stored in the node
struct TreeNode* left ; // node's left child
struct TreeNode* right ; // node's right child
} TreeNode;
/// The three supported traversals
typedef enum {
PREORDER, // parent -> left -> right
INORDER, // left -> parent -> right
POSTORDER // left -> right -> parent
} TraversalType;
and lastly the traverse function so far as it failed the first test.
void traverse( const TreeNode* root, const TraversalType type ) {
if ( type == PREORDER) {
if (root != NULL)
{
printf("%d", root->data);
traverse( root->left, PREORDER);
traverse( root-> right, PREORDER);
}
}
}
void build_tree(TreeNode** root, const int elements[], const int count) {
TreeNode* node = malloc(sizeof(TreeNode*));
node->left = node ->right = NULL;
*root = node;
for ( int i0 = 0; i0 < count; ++i0 ){
TreeNode* node = malloc(sizeof(TreeNode*));
*root = node;
node->data = elements[cnt];
insertNode( &(*root), &node );
}
}
Why is the insertNode getting the errors (multiple) and I don't know which is the pointer and which is the struct. GUYS ANY HINT WILL BE HELPFUL PLEASE?
bst.c:94:20: error: request for member 'left' in something not a structure or union
insert(root->left, new_node);
void insertNode(TreeNode** root, TreeNode* new_node) {
if (new_node-> data < &root-> data) {
if (&root-> left == NULL)
&root-> left == new_node;
else
insert(root->left, new_node);
}
if (new_node->data > &root->data) {
if(&root-> right ==NULL)
&root->right = new_node;
else
insert(&root->right, new_node);
}
}
SO for Edit 2: I do have a header file which has a build_Tree(**root, elems[], sizeofElem[]), which means i need a helper function insert. Yes is would be easier to add by input starting*.
Edit 1
#include "bst.h"
#include <stdio.h>
#include <stdlib.h>
//arbitrary list of temp nodes
TreeNode *new_node, *root, *tmp, *parent, *current;
int elemArray[5], i1, i2, i0;
/*
Insert a new node into the tree by referencing the root and using recursion
*/
TreeNode* getN(int dataElem) {
TreeNode *newNode = malloc(sizeof(*newNode));
if (newNode != NULL)
{
newNode->data = dataElem;
newNode->left = NULL;
newNode->right = NULL;
}
return newNode;
}
/** This func should just be the root of the tree in the parameter,
but I like the idea of a pointer becuase it helps to create a tempory
pointer rather than newNode
**/
TreeNode* addNodeToTree(TreeNode *root, int data) {
TreeNode *current = *root; //define the current pointer to the root always
TreeNode *parent = *root
TreeNode *newNode = getN(data);
if (*root == NULL)
{
printf("First Node");
*root = newNode;
}
else
{
while(current != NULL)
{
parent = current;
if (current->data > data)
current = current->left;
else if (current->data < data)
current = current->right;
}
if (parent->data > data)
parent->left = newNode;
else if (parent->data < data)
parent->right = newNode;
}
}
void build_Tree(TreeNode** root, const int elements[], const int count) {
*root = malloc(sizeof(TreeNode));
for ( i0 = 0; i0 < count; ++i0 ){
printf("%d\n", elements[count]);
addNodeToTree(&root, elements[count]);
}
}
int main( int argc, char *argv[] ) {
//Throw error is *Argv[] is not an integer
//assuming it was an integer
int cnt = atoi( argv[1] );
printf( "number is %d\n", cnt );
//
printf("Enter %i integer values to place in tree:\n", cnt);
for ( i1 = 0; i1 < cnt; ++i1) {
scanf( "%d", &elemArray[i1] );
}
//first ouput "INput Values"
printf( " Input Values:\n " );
for ( i2 = 0; i2 < cnt; ++i2) {
printf( "%d\n", elemArray[i2] );
printf("building tree0\n");
}
printf("building tree\n");
TreeNode** root = (TreeNode**)malloc(sizeof(TreeNode*));
TreeNode *root = NULL;
build_Tree(root, elemArray, cnt );
printf( "Preorder:\n ");
//traverse
//TreeNode* tempN = malloc(sizeof(TreeNode*));
//tempN->data= 5;
traverse( *root, PREORDER); //pass the pointer of root to traverse the tree
//traverse a single node
printf( "Inorder:\n ");
printf( "Postorder:\n ");
//Build tree with each element
return 0;
}
void traverse( const TreeNode* root, const TraversalType type ) {
if ( type == PREORDER) {
if (root != NULL)
{
printf("%d", root->data);
traverse( root->left, PREORDER);
traverse( root-> right, PREORDER);
}
}
}
/**
void insertNode(TreeNode** root, TreeNode* new_node) {
if (new_node-> data < *root-> data) {
if (*root-> left == NULL)
*root-> left == new_node;
else
insert(*root->left, new_node);
}
if (new_node->data > *root->data) {
if(*root-> right ==NULL)
*root->right = new_node;
else
insert(*root->right, new_node);
}
}
**/
//question1: what is the
Edit 2 for main and build_tree
void build_Tree(TreeNode** root, const int elements[], const int count) {
//*root = malloc(sizeof(TreeNode));
for ( i0 = 0; i0 < count; i0++ ){
//create the node
//
TreeNode *current = *root; //define the current pointer to the root always
TreeNode *parent = *root;
//dont create node
int data = elements[i0];
TreeNode *newNode = getN(data);
if (*root == NULL)
{
printf("First Node %d\n", elements[i0]);
*root = newNode;
}
else
{
printf("Next Node %d\n", elements[i0]);
while(current != NULL)
{
parent = current;
if (current->data > data)
current = current->left;
else if (current->data < data)
current = current->right;
}
if (parent->data > data)
parent->left = newNode;
else if (parent->data < data)
parent->right = newNode;
}
//return root;
}
}
TreeNode* getN(int dataElem) {
TreeNode *newNode = malloc(sizeof(*newNode));
if (newNode != NULL)
{
newNode->data = dataElem;
newNode->left = NULL;
newNode->right = NULL;
}
return newNode;
}
int main( int argc, char *argv[] ) {
//Throw error is *Argv[] is not an integer
//assuming it was an integer
int cnt = atoi( argv[1] );
printf( "number is %d\n", cnt );
//
printf("Enter %i integer values to place in tree:\n", cnt);
for ( i1 = 0; i1 < cnt; ++i1) {
scanf( "%d", &elemArray[i1] );
}
//first ouput "INput Values"
printf( " Input Values:\n " );
for ( i2 = 0; i2 < cnt; ++i2) {
printf( "%d\n", elemArray[i2] );
printf("building tree0\n");
}
printf("building tree\n");
TreeNode* root; //= malloc(sizeof(TreeNode*));
root = NULL;
build_Tree(&root, elemArray, cnt );
printf( "Preorder:\n ");
//traverse
//TreeNode* tempN = malloc(sizeof(TreeNode*));
//tempN->data= 5;
//traverse( *root, PREORDER); //pass the pointer of root to traverse the tree
//traverse a single node
printf( "Inorder:\n ");
printf( "Postorder:\n ");
//Build tree with each element
return 0;
}
Say you created a function addNodeToTree(TreeNode *root, int data), pass the root node, and data to it as argument.
Now inside this function, simply create another variable say TreeNode *current = root which will help us basically to traverse the tree and place the node at its respective position, and TreeNode *newNode = NULL(this will become the new node, which is to be inserted).
Now before moving ahead, to actually place the node, we will first check, if the root is not null, i.e. the tree is EMPTY. For that, we will test:
if (root == NULL)
{
newNode = malloc(sizeof(*newNode)); // else we can make a function for this
// thingy too. Creating a function too,
// for you to look at.
root = newNode;
}
If the tree is not EMPTY, i.e. it contains a node already, then we will traverse the tree to find the place, where to put the new node. So the else part, will be like:
else
{
parent = current = root;
// This loop will actually help us, find the `parent`,
// of the `newNode`(which is to be inserted)
while (current != NULL)
{
parent = current;
if (current->data > data)
current = current->left;
else if (current->data < data)
current = current->right;
}
// Now once, we have found, the node, under which the
// newNode will be placed, now we have to check, whether
// newNode will become a `left child/right child` of the
// parent.
newNode = getNewNode(data);
if (parent->data > data)
parent->left = newNode;
else if (parent->data < data)
parent->right = newNode;
return root;
}
TreeNode * getNewNode(int data)
{
TreeNode *newNode = malloc(sizeof(*newNode));
if (newNode != NULL)
{
newNode->data = data;
newNode->left = NULL;
newNode->right = NULL;
}
return newNode;
}
Now the newNode has been inserted, and you can simply traverse in any order to see the Tree.
EDIT 1:
Here is one working example, just see if this makes sense. Else please do ask any question, that might may arise.
#include <stdio.h>
#include <stdlib.h>
typedef struct TREENODE
{
int data;
struct TREENODE *left;
struct TREENODE *right;
}TreeNode;
void display(TreeNode *node)
{
printf("*********************************\n");
printf("Address of Node: %p\n", node);
printf("Data: %d\n", node->data);
printf("Left Child: %p\n", node->left);
printf("Right Child: %p\n", node->right);
printf("*********************************\n");
}
TreeNode * getNewNode(int data)
{
TreeNode *newNode = malloc(sizeof(*newNode));
if (newNode != NULL)
{
newNode->data = data;
newNode->left = NULL;
newNode->right = NULL;
}
return newNode;
}
int getIntData(char *message)
{
int value = 0;
char buffer[BUFSIZ] = {'\0'};
fputs(message, stdout);
fgets(buffer, sizeof(buffer), stdin);
sscanf(buffer, "%d", &value);
return value;
}
TreeNode * addNodeToTree(TreeNode *root, int data)
{
TreeNode *current = root, *parent = root;
TreeNode *newNode = getNewNode(data);
if (root == NULL)
{
root = newNode;
}
else
{
while(current != NULL)
{
parent = current;
if (current->data > data)
current = current->left;
else if (current->data < data)
current = current->right;
}
if (parent->data > data)
parent->left = newNode;
else if (parent->data < data)
parent->right = newNode;
}
return root;
}
void inOrderTraversal(TreeNode *root)
{
if (root != NULL)
{
inOrderTraversal(root->left);
display(root);
inOrderTraversal(root->right);
}
}
int main(void)
{
TreeNode *root = NULL;
int data = 0;
data = getIntData("Enter Data: ");
root = addNodeToTree(root, data);
data = getIntData("Enter Data: ");
root = addNodeToTree(root, data);
data = getIntData("Enter Data: ");
root = addNodeToTree(root, data);
inOrderTraversal(root);
return EXIT_SUCCESS;
}
EDIT 2:
To make addNodeToTree(...), implement pointer to a pointer, one simply needs to change the function as:
void addNodeToTree(TreeNode **root, int data)
{
TreeNode *current = *root;
TreeNode *parent = *root;
TreeNode *newNode = getNewNode(data);
if (*root == NULL)
{
*root = newNode;
}
else
{
// same as before, just don't return anythingy, from the function.
// As the function uses pointer to a pointer, hence whatever changes
// are done, here will be reciprocated in the main function automatically
}
// no need to return anythingy
}
And the call from main will now look like:
int main(void)
{
TreeNode *root = NULL;
int data = 0;
data = getIntData("Enter Data: ");
addNodeToTree(&root, data);
// Just see the call to addNodeToTree(...), the rest is same, as before
}
EDIT 3:
In order to take elements from an array instead of adding them directly to tree, just change the main method to this form:
int main(void)
{
TreeNode *root = NULL;
int element[5] = {19, 11, 5, 28, 25};
int size = sizeof(element) / sizeof(element[0]);
int counter = 0;
for (counter = 0; counter < size; ++counter)
{
addNodeToTree(&root, element[counter]);
}
inOrderTraversal(root);
return EXIT_SUCCESS;
}