What kind of error in Binary search code? - c

I am implementing the binary search tree with some operations ( new node, search, insert and display).
It results in following warning.
binarytree.c:70: warning: assignment makes pointer from integer without a cast
binarytree.c:72: warning: assignment makes pointer from integer without a cast
binarytree.c:73: warning: return makes integer from pointer without a cast
binarytree.c: At top level:
binarytree.c:78: warning: conflicting types for ‘printInoder’
binarytree.c:47: warning: previous implicit declaration of ‘printInoder’ was here
binarytree.c: In function ‘NewNode’:
binarytree.c:122: warning: return makes pointer from integer without a cast
Undefined symbols for architecture x86_64:
"_newNode", referenced from:
_main in cckg2mll.o
_insert in cckg2mll.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status
You will see my source code here below but I wish to hear your suggestions. I fully understand the Binary trees functions but I think it is not related to any algorithm but it is a programming problem.
Source Code
It is really long code but I cannot reduce it for your guys.
#include <stdlib.h>
#include <stdio.h>
#define false 0
#define true 1
struct Node
{
int data;
struct Node *left, *right;
}*node,*root;
int main(void)
{
root = (struct Node *)malloc(sizeof(struct Node));
int option = 1;
int choice,value,target,newvalue;
while(option)
{
printf("Enter your choice \n");
scanf("%d\n",&choice);
switch(choice)
{
case 1:
printf("Enter the a new value\n");
insert(root,value);
scanf("%d\n",&value);
break;
case 2:
printf("Enter the traget \n");
scanf("%d\n",&target);
lookup(root,target);
break;
case 3:
printf("Enter the new node \n");
scanf("%d\n",&newvalue);
newNode();
break;
case 4:
printInoder();
break;
}
printf("Enter 0 or 1\n");
scanf("%d\n",&option);
}
}
int insert(struct Node *node ,int data)
{
// 1. If the tree is empty, return a new, single node
node = (struct Node *)malloc(sizeof(struct Node));
if (node == NULL)
{
return(newNode(data));
}
else
{
// 2. Otherwise, recur down the tree
if (data <= node->data)
node->left = insert(node->left, data);
else
node->right = insert(node->right, data);
return(node); // return the (unchanged) node pointer
}
}
void printInoder()
{
root = (struct Node *)malloc(sizeof(struct Node));
if (root != NULL)
{
printInoder(root->left);
printf("%d ",root->data);
printInoder (root->right);
}
}
int lookup(struct Node *node, int target)
{
node = (struct Node *)malloc(sizeof(struct Node));
// 1. Base case == empty tree
// in that case, the target is not found so return false
if (node == NULL)
{
return(false);
}
else
{
// 2. see if found here
if (target == node->data) return(true);
else
{
// 3. otherwise recur down the correct subtree
if (target < node->data)
return(lookup(node->left, target));
else return(lookup(node->right, target));
}
}
}
struct Node *NewNode(int x)
{
node =(struct Node *)malloc(sizeof(struct Node)); // "new" is like "malloc"
node->data = x;
node->left = NULL;
node->right = NULL;
return(x);
}

So, the biggest issue is that you ignore data types. insert function returns int but whenever you assign its return value or even return something inside this function, the variables you use are pointers instead - so change return type of insert to struct Node *node.
Also, in case 4 part, you use function printInoder which is declared and defined after calling it (below main function) so that is why it warns you that you should at least declare this function before main.
Finally, inside insert function, you call newNode but this function is called NewNode and it is also declared and defined below main.

You called the following function using newNode not NewNode. Also, move the * off of the NewNode part.
struct Node *NewNode(int x)
{
node =(struct Node *)malloc(sizeof(struct Node)); // "new" is like "malloc"
node->data = x;
node->left = NULL;
node->right = NULL;
return(x);
}
Your insert function returns a node pointer but is declared with an int return type.
Also, you need to declare functions above where they are called the first time. add a declaration statement to the top of the page for your functions to work.
return_type function_name(params);
Finally, rename your function to printInOrder() instead of printInoder()

Your code has many errors.
I've edited it a bit:
#include <stdlib.h>
#include <stdio.h>
#define false 0
#define true 1
struct Node
{
int data;
struct Node *left, *right;
};
void insert(struct Node **node, int data);
int lookup(struct Node *node, int target);
void printInoder(struct Node *root);
struct Node *NewNode(int x);
int main(void)
{
struct Node *root = NULL;
int option = 1;
int choice, value, target;
while (option)
{
choice = value = target = 0;
printf("Enter your choice \n");
scanf("%d", &choice);
switch (choice)
{
case 1:
printf("Enter the a new value\n");
scanf("%d", &value);
insert(&root, value);
break;
case 2:
printf("Enter the traget \n");
scanf("%d", &target);
printf("%d\n", lookup(root, target));
break;
case 3:
printf("Printing\n");
printInoder(root);
printf("\n");
break;
}
printf("Enter 0 or 1\n");
scanf("%d", &option);
}
return 0;
}
void insert(struct Node **root, int data)
{
// 1. If the tree is empty, return a new, single node
struct Node *node = NewNode(data);
if (*root == NULL)
{
*root = node;
return;
}
// 2. Otherwise, recur down the tree
if (data <= (*root)->data)
insert(&(*root)->left, data);
else
insert(&(*root)->right, data);
}
void printInoder(struct Node *root)
{
if (root == NULL) return;
printInoder(root->left);
printf("%d ", root->data);
printInoder(root->right);
}
int lookup(struct Node *root, int target)
{
// 1. Base case == empty tree
// in that case, the target is not found so return false
if (root == NULL)
{
return(false);
}
// 2. see if found here
if (target == root->data) return(true);
// 3. otherwise recur down the correct subtree
if (target < root->data)
return(lookup(root->left, target));
else return(lookup(root->right, target));
}
struct Node *NewNode(int x)
{
struct Node *node= malloc(sizeof *node);
node->data = x;
node->left = NULL;
node->right = NULL;
return node;
}
Try it, and take a look at the changes in the code.

Related

How malloc allocates space while inserting values to a binary search tree?

bellow there is a simple code for a binary search tree. It has 2 cases, the first one inserts values to the tree and the second one finds the preorder traversal of the tree.
My question has to do with the malloc function. In the first case we have this ptr = (struct node *)malloc(sizeof(struct node)); and lets say that the value that we want to insert is 50. I can see while debugging that ptr=50 and I can't understand how (struct node *)malloc(sizeof(struct node)) gives this result.
Also when we have struct node *ptr, *nodeptr, *parentptr as pointing variables to struct node inside the function and after that we have for example parentptr=NULL; this parentptr refers to the pointer *parentptr or its just a variable.
struct node
{
int data;
struct node* left;
struct node* right;
};
struct node* tree;
struct node*
insert(struct node*, int);
void
preorder(struct node*);
int
main()
{
int option, val;
struct node* ptr;
tree = NULL;
do {
printf("\n ******MAIN MENU******* \n");
printf("\n 1. Insert an element");
printf("\n 2. Preorder Traversal");
printf("\n 3. Exit");
printf("\n\n Enter your option : ");
scanf("%d", &option);
switch (option) {
case 1:
printf("\n Enter the value of the new node : ");
scanf("%d", &val);
tree = insert(tree, val);
break;
case 2:
printf("\n The elements of the tree are : \n");
preorder(tree);
break;
}
} while (option != 3);
getch();
return 0;
}
struct node*
insert(struct node* tree, int val)
{
struct node *ptr, *nodeptr, *parentptr;
ptr = (struct node*)malloc(sizeof(struct node));
ptr->data = val;
ptr->left = NULL;
ptr->right = NULL;
if (tree == NULL) {
tree = ptr;
tree->left = NULL;
tree->right = NULL;
} else {
nodeptr = tree;
parentptr = NULL;
while (nodeptr != NULL) {
parentptr = nodeptr;
if (val < nodeptr->data)
nodeptr = nodeptr->left;
else
nodeptr = nodeptr->right;
}
if (val < parentptr->data)
parentptr->left = ptr;
else
parentptr->right = ptr;
}
return tree;
}
void
preorder(struct node* tree)
{
if (tree != NULL) {
printf("%d\t", tree->data);
preorder(tree->left);
preorder(tree->right);
}
}

Inserting into binary search tree using recursion in C

I was making a program to make a binary search tree which takes input from the user.
I have deliberately shown two search functions in my code below.
Problem: The search function2 works correctly but the search function1 does not work correctly (when used after commenting the other each time).
Why is it so?
I tried doing the dry run and building the recursion stack, which works fine as per me. But somehow I think the search function 1 is not able to make that linking in the linked list to insert the element. That is the reason I am not getting the right output when I try to do the inorder traversal
Any help will be really appreciated!
#include <stdio.h>
#include <stdlib.h>
struct node{
int data;
struct node *left;
struct node *right;
};
struct node *root = NULL;
struct node *newNode(int data){
struct node *temp = (struct node *)malloc(sizeof(struct node));
temp->data = data;
temp->left = NULL;
temp->right = NULL;
return temp;
}
//SEARCH FUNCTION 1: this does not work correctly
void search(struct node *t,int data){
if(t){
if(data > t->data){
search(t->right,data);
}else{
search(t->left,data);
}
}else{
t = newNode(data);
}
}
//SEARCH FUNCTION 2: this works fine and inserts the element correctly
void search(struct node *t, int data){
if(data < t->data && t->left != NULL){
search(t->left, data);
}else if(data < t->data && t->left == NULL){
t->left = newNode(data);
}else if(data > t->data && t->right != NULL){
search(t->right,data);
}else{
t->right = newNode(data);
}
}
void insertNode(int data){
if(!root){
root = newNode(data);
return;
}
search(root, data);
}
void inorder(struct node *t){
if(t){
if(t->left){
inorder(t->left);
}
printf("%d ->", t->data);
if(t->right){
inorder(t->right);
}
}
}
int main(){
int step, data;
while(1){
printf("1. Insert element\n");
printf("2. Print tree\n");
scanf("%d",&step);
switch(step){
case 1: printf("enter element to be inserted\n");
scanf("%d",&data);
insertNode(data);
break;
case 2:inorder(root);
printf("\n");
break;
}
}
return 0;
}
The problem is that the statement t = newNode(data) assigns to a local variable, so the result is lost immediately after returning from the function.
In this case one solution is double indirection, as you don't just want to modify the thing a pointer points to, but the pointer itself.
void search(struct node **pt,int data)
{
struct node *t = *pt;
if (t) {
if (data > t->data) {
search(&t->right,data);
} else {
search(&t->left,data);
}
} else {
*pt = newNode(data);
}
}
1st search function:
void search(struct node *t,int data){
...
t = newNode(data);
}
but then in the 2nd search function you do:
void search(struct node *t, int data){
...
t->right = newNode(data);
}
which will remember the assignment, while the first will not, since when you are going to recurse, the changes will be lost.
You see in the 2nd case, you are assign what newNode() returns to data member of a struct that is a pointer, while the struct is passed a pointer in this function. However, in the 1st case, you assign the result in a struct that is passed by one pointer only. If a double pointer would be used, things would be differently.

Linked list- find_node_data

I have previously posted about this same topic. I am self-learning data structures using MIT Open Courseware. I'm doing the 6.S096-Introduction to C/C++ course and attempting the fourth assignment.
It is based on binary search trees and I gave it a try. I wanted to print the values for debugging but kept getting different executions each time.
One time, the cycle doesn't complete and the other time, it goes on to infinity. The debugging block also relates to the other function(find_node_data) I have to complete. So if I can figure what's wrong here, I can easily finish the find_node_data. I have commented a few things to see if it affects anything. What am I doing wrong?
#include <stdio.h>
#include <stdlib.h>
typedef struct node{
int node_id;
int data;
struct node* left;
struct node* right;
}node;
///*** DO NOT CHANGE ANY FUNCTION DEFINITIONS ***///
// Declare the tree modification functions below...
node* newNode(int data,int node_id){
node* new_node = (node*) malloc(sizeof(node));
new_node->data = data;
new_node->node_id= node_id;
new_node->right= new_node->left=NULL;
return new_node;
}
node* insert_node(node* root, int node_id, int data) {
if(root==NULL)
return newNode(data,node_id);
else{
node* cur;
if(node_id<root->node_id){
cur=insert_node(root->left,data,node_id);
root->left=cur;
}
else if(node_id>root->node_id){
cur=insert_node(root->right,data,node_id);
root->right=cur;
}
}
return root;
}
// Find the node with node_id, and return its data
/*int find_node_data(node* root, int node_id) {
node* current;
for( current = root->; current->next!=NULL;
current= current->next){
if(current->data == data) return current;
}
return NULL;
}
*/
int main() {
/*
Insert your test code here. Try inserting nodes then searching for them.
When we grade, we will overwrite your main function with our own sequence of
insertions and deletions to test your implementation. If you change the
argument or return types of the binary tree functions, our grading code
won't work!
*/
int T,data,node_id;
printf("Print yo cases");
scanf("%d", &T);
node* root = NULL;
while(T-->0){
printf("Type yo numnums no. %d:",T);
scanf("%d %d",&data,&node_id);
root=insert_node(root,data,node_id);
}
node *lol;
node *king;
for(lol=root;lol->left!=NULL;lol=lol->left){
//for(king=root;king->right!=NULL;king=king->right){
printf("executed!\n");
printf("%d ",lol->node_id);//,king->node_id);
//}
}
return 0;
}
To find the node_data you can use recursion to find the node.
node* find_node_data(node *root, int node_id) {
if (root == NULL)
return NULL;
else if (root->node_id == node_id)
return root;
else {
node *left = find_node_data(root->left, node_id);
return left? left: find_node_data(root->right, node_id);
}
}
And then get the data for the node e.g. get the data for node with node_id 42:
printf("node data %d", find_node_data(root, 42)->data);
Full program below (I can't guarantee its correctness but maybe you can?)
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int node_id;
int data;
struct node *left;
struct node *right;
} node;
///*** DO NOT CHANGE ANY FUNCTION DEFINITIONS ***///
// Declare the tree modification functions below...
node *newNode(int data, int node_id) {
node *new_node = (node *) malloc(sizeof(node));
new_node->data = data;
new_node->node_id = node_id;
new_node->right = new_node->left = NULL;
return new_node;
}
node *insert_node(node *root, int data, int node_id) {
if (root == NULL)
return newNode(data, node_id);
else {
node *cur;
if (node_id < root->node_id) {
cur = insert_node(root->left, data, node_id);
root->left = cur;
}
else if (node_id > root->node_id) {
cur = insert_node(root->right, data, node_id);
root->right = cur;
}
}
return root;
}
// Find the node with node_id, and return its data
/*
int find_node_data_old(node *root, int node_id) {
node *current;
for (current = root->; current->next != NULL;
current = current->next) {
if (current->data == data) return current;
}
return NULL;
}*/
node* find_node_data(node *root, int node_id) {
if (root == NULL)
return NULL;
else if (root->node_id == node_id)
return root;
else {
node *left = find_node_data(root->left, node_id);
return left? left: find_node_data(root->right, node_id);
}
}
void print(node *np) {
if (np) {
print(np->left);
printf("(%d, %d)", np->node_id, np->data);
print(np->right);
}
}
int main() {
/*
Insert your test code here. Try inserting nodes then searching for them.
When we grade, we will overwrite your main function with our own sequence of
insertions and deletions to test your implementation. If you change the
argument or return types of the binary tree functions, our grading code
won't work!
*/
int T, data, node_id;
printf("Print yo cases");
scanf("%d", &T);
node *root = NULL;
while (T-- > 0) {
printf("Type yo numnums no. %d:", T);
scanf("%d %d", &data, &node_id);
root = insert_node(root, data, node_id);
}
node *lol;
node *king;
for (lol = root; lol->left != NULL; lol = lol->left) {
//for(king=root;king->right!=NULL;king=king->right){
printf("executed!\n");
printf("%d ", lol->node_id);//,king->node_id);
//}
}
print(root);
printf("\n");
printf("node data %d", find_node_data(root, 42)->data);
return 0;
}
Test
Print yo cases3
Type yo numnums no. 2:22 42
Type yo numnums no. 1:21 41
Type yo numnums no. 0:20 40
executed!
42 executed!
41 (40, 20)(41, 21)(42, 22)
node data 22
You may also use Jonathan Leffler's improved recursion to find the node:
node *find_node_data2(node *root, int node_id) {
if (root == NULL)
return NULL;
else if (root->node_id == node_id)
return root;
else if (root->node_id > node_id)
return find_node_data(root->left, node_id);
else
return find_node_data(root->right, node_id);
}
Both functions return the correct values as seen in the second test.
int main() {
/*
Insert your test code here. Try inserting nodes then searching for them.
When we grade, we will overwrite your main function with our own sequence of
insertions and deletions to test your implementation. If you change the
argument or return types of the binary tree functions, our grading code
won't work!
*/
int T, data, node_id;
printf("Print yo cases");
scanf("%d", &T);
node *root = NULL;
while (T-- > 0) {
printf("Type yo numnums no. %d:", T);
scanf("%d %d", &data, &node_id);
root = insert_node(root, data, node_id);
}
node *lol;
node *king;
for (lol = root; lol->left != NULL; lol = lol->left) {
//for(king=root;king->right!=NULL;king=king->right){
printf("executed!\n");
printf("%d ", lol->node_id);//,king->node_id);
//}
}
print(root);
printf("\n");
printf("node data %d\n", find_node_data(root, 42)->data);
printf("node data find_node_data2 %d", find_node_data2(root, 42)->data);
return 0;
}
Test 2
Print yo cases3
Type yo numnums no. 2:11 12
Type yo numnums no. 1:13 14
Type yo numnums no. 0:20 42
(12, 11)(14, 13)(42, 20)
node data 20
node data find_node_data2 20

Working tree traversal program seems like it does not work

I was new to trees in C. To learn more, I googled and found some nice example program. http://see-programming.blogspot.in/2013/03/insertion-deletion-and-traversal-in.html I copied it and ran it It worked perfectly. One of its functions was known as traverse. Its code is as follows:
void traverse(struct treeNode *node) {
if (node != NULL) {
traverse(node->left);
printf("%3d", node->data);
traverse(node->right);
}
return;
}
The whole program:
#include <stdio.h>
#include <stdlib.h>
struct treeNode {
int data;
struct treeNode *left, *right;
};
struct treeNode *root = NULL;
/* create a new node with the given data */
struct treeNode* createNode(int data) {
struct treeNode *newNode;
newNode = (struct treeNode *) malloc(sizeof (struct treeNode));
newNode->data = data;
newNode->left = NULL;
newNode->right = NULL;
return(newNode);
}
/* insertion in binary search tree */
void insertion(struct treeNode **node, int data) {
if (*node == NULL) {
*node = createNode(data);
} else if (data < (*node)->data) {
insertion(&(*node)->left, data);
} else if (data > (*node)->data) {
insertion(&(*node)->right, data);
}
}
/* deletion in binary search tree */
void deletion(struct treeNode **node, struct treeNode **parent, int data) {
struct treeNode *tmpNode, *tmpParent;
if (*node == NULL)
return;
if ((*node)->data == data) {
/* deleting the leaf node */
if (!(*node)->left && !(*node)->right) {
if (parent) {
/* delete leaf node */
if ((*parent)->left == *node)
(*parent)->left = NULL;
else
(*parent)->right = NULL;
free(*node);
} else {
/* delete root node with no children */
free(*node);
}
/* deleting node with one child */
} else if (!(*node)->right && (*node)->left) {
/* deleting node with left child alone */
tmpNode = *node;
(*parent)->right = (*node)->left;
free(tmpNode);
*node = (*parent)->right;
} else if ((*node)->right && !(*node)->left) {
/* deleting node with right child alone */
tmpNode = *node;
(*parent)->left = (*node)->right;
free(tmpNode);
(*node) = (*parent)->left;
} else if (!(*node)->right->left) {
/*
* deleting a node whose right child
* is the smallest node in the right
* subtree for the node to be deleted.
*/
tmpNode = *node;
(*node)->right->left = (*node)->left;
(*parent)->left = (*node)->right;
free(tmpNode);
*node = (*parent)->left;
} else {
/*
* Deleting a node with two children.
* First, find the smallest node in
* the right subtree. Replace the
* smallest node with the node to be
* deleted. Then, do proper connections
* for the children of replaced node.
*/
tmpNode = (*node)->right;
while (tmpNode->left) {
tmpParent = tmpNode;
tmpNode = tmpNode->left;
}
tmpParent->left = tmpNode->right;
tmpNode->left = (*node)->left;
tmpNode->right =(*node)->right;
free(*node);
*node = tmpNode;
}
} else if (data < (*node)->data) {
/* traverse towards left subtree */
deletion(&(*node)->left, node, data);
} else if (data > (*node)->data) {
/* traversing towards right subtree */
deletion(&(*node)->right, node, data);
}
}
/* search the given element in binary search tree */
void findElement(struct treeNode *node, int data) {
if (!node)
return;
else if (data < node->data) {
findElement(node->left, data);
} else if (data > node->data) {
findElement(node->right, data);
} else
printf("data found: %d\n", node->data);
return;
}
void traverse(struct treeNode *node) {
if (node != NULL) {
traverse(node->left);
printf("%3d", node->data);
traverse(node->right);
}
return;
}
int main() {
int data, ch;
while (1) {
printf("1. Insertion in Binary Search Tree\n");
printf("2. Deletion in Binary Search Tree\n");
printf("3. Search Element in Binary Search Tree\n");
printf("4. Inorder traversal\n5. Exit\n");
printf("Enter your choice:");
scanf("%d", &ch);
switch (ch) {
case 1:
while (1) {
printf("Enter your data:");
scanf("%d", &data);
insertion(&root, data);
printf("Continue Insertion(0/1):");
scanf("%d", &ch);
if (!ch)
break;
}
break;
case 2:
printf("Enter your data:");
scanf("%d", &data);
deletion(&root, NULL, data);
break;
case 3:
printf("Enter value for data:");
scanf("%d", &data);
findElement(root, data);
break;
case 4:
printf("Inorder Traversal:\n");
traverse(root);
printf("\n");
break;
case 5:
exit(0);
default:
printf("u've entered wrong option\n");
break;
}
}
return 0;
}
When I ran the program it worked perfectly. But when I analyzed the traverse function, I could not understand it. When you call the traverse function from the main, you pass the root to it as in this program. But when the node is not NULL, it continues printing the tree as more data is left to print. But every time the node is not NULL, the line traverse (node->left); calls the function once again before printing the node. Thus I do not understand how the whole tree gets printed. It would be helpful if someone could explain.
Let's take this binary tree as an example.
binary tree
How the whole tree gets printed?
Each time we call traverse function, we will print the data of *node.
Traverse process is a recursive process in which functions dealing with root node will call functions dealing with root's left-child and right-child. For example, traverse(15) will call traverse(5) and traverse(16), and traverse(5) will call traverse(3) and traverse(12).
Recuration ends with leaf nodes and every node is visited and printed.
Why the result is in-order?
In each call of void traverse(struct treeNode *node), we could regard *node as the root of a subtree. Following codes mean data of *node won't be printed until recurse of its left-child returns.
traverse(node->left);
printf("%3d", node->data);
traverse(node->right);
And traverse(node->left) returns only when its left-child and right-child are traversed, childs of node->left will also printed before *node. So, all nodes in left sub-tree of *node will be printed before *node, and all nodes in right sub-tree of *node will be printed after it.
For example, traverse(12) calls traverse(10) before print 12, traverse(10) calls traverse(6) and traverse(6) calls traverse(7). Since 7 is a leaf node, traverse(7), traverse(6) and traverse(10) returns in order. Then traverse(12) print 12 and calls traverse(13).
We could get in-order result of 6 7 10 12 13

improvement in my linklist program

Here is a program it is working
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node *next, *prev;
};
struct node *root = NULL;
void push(int);
void pop(void);
struct node *create_node(int);
void travel(void);
int main()
{
int i, j, choice, count;
printf("enter choice\n");
scanf("%d", &choice);
count = 0;
while (choice == 1) {
printf("enter a data element");
scanf("%d", &j);
if (count == 0) {
root = (struct node *)malloc(sizeof(struct node));
root->next = NULL;
root->data = j;
} else
push(j);
count++;
printf("enter choice\n");
scanf("%d", &choice);
}
printf("the link list is \n");
//travel function to be created
travel();
}
void push(int data)
{
struct node *t1;
t1 = root;
while (t1->next != NULL) {
t1 = t1->next;
}
t1->next = create_node(data);
}
void pop()
{
}
void travel(void)
{
struct node *t1;
t1 = root;
while (t1->next != NULL) {
printf("%d ", t1->data);
t1 = t1->next;
}
printf("%d ", t1->data);
}
struct node *create_node(int data)
{
struct node *p = (struct node *)malloc(sizeof(struct node));
p->data = data;
p->next = NULL;
p->prev = NULL;
return p;
}
the above program is fully working,I have used a global pointer root.
My problem is if I do not want to use a global pointer root here then how do I maintain
that list because each time I will have to return the root of list in my push pop functions
is there any other way to achieve the same?
The simplest way to achieve this is to pass a pointer to the root node pointer to each of your functions:
void push(struct node **root, int data) { ... }
void pop(struct node **root) { ... }
void travel(struct node *root) { ... }
So, in your main function you might declare a local variable to hold the root pointer:
struct node *root = NULL;
and then when you call push, for example, you pass the address of the root poiner:
push(&root, data);
I strongly recommend that you fix your push and travel functions so that they are robust to the root pointer being NULL. This was discussed in a previous question of yours and you should heed the advice.
If you did that then you could get rid of the test for count being zero and the associated special case code. You would then replace this:
if (count == 0) {
root = (struct node *)malloc(sizeof(struct node));
root->next = NULL;
root->data = j;
} else
push(&root, j);
with this:
push(&root, j);
To drive home the message, your new push would look like this:
void push(struct node **root, int data)
{
if (*root == NULL)
*root = create_node(data);
else
{
struct node *last = *root;
while (last->next != NULL) {
last = last->next;
}
last->next = create_node(data);
}
}
You would need to modify travel also to include a check for the root node being NULL. I will leave that as an exercise for you.
Maintaining both head and tail pointers could be a better approach since it would avoid so many list traversals.

Resources