Linked list variation - c

I am in a bit of a pickle. I have a variation of a linked list where not only do the nodes contain a value, but also each node will have a flag declaring whether it is a valid node or not (1 is valid; 0 is invalid). I have some functions that I am having difficulty with. I have deleteLast which deletes the last valid node, or in other words, clears the valid flag to 0. Bear in mind the last valid node might not be the last node; I was hoping countNodes would of use here. deleteValue 'deletes' first valid node with specified value. restoreValue restores the first 'deleted' node with specified value. lastly, compact makes a new list of valid nodes only in reverse order of the old list. deleteLast is the function I'm having most difficulty with. Any feedback on that function or any of the other functions will be of great help. Here's some code:
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
struct Node{
struct Node *link;
int value;
int valid;
}
int countNodes (Node *ptrToFirst){
int count=0;
if(ptrToFirst==NULL){
return 0;
}
else{
while(ptrToFirst!=NULL){
if(ptrToFirst->valid==1)
count++;
ptrToFirst=ptrToFirst->link;
}
}
int deleteLast(Node *ptrToFirst){
Node p;
if(countNodes||ptrToFirst!=NULL){
while(ptrToFirst!=NULL){
ptrToFirst->link;
if(ptrToFirst->valid==1)
if(ptrToFirst->link==NULL){
}
}
}
else return 0;
}
int deleteValue(Node *ptrToFirst, int val){
if(ptrToFirst==NULL){
return 0;
}
while(ptrToFirst!=NULL){
if(ptrToFirst->value==val&&ptrToFirst->valid==1){
ptrToFirst->valid=0;
return 0;
}
else
ptrToFirst=ptrToFirst->link;
}
}
int restoreValue(Node *start, int val){
if(start==NULL){
return 0;
}
while(start!=NULL){
if(start->value==val&&start->valid==0)
start->valid=1;
return 1;
else
start=start->link;
}
}
int compact(Node *old, **ptrToNewHeadPtr){
Node temp;
if(old!=NULL){
while(old!=NULL){
if(old->valid==1)
temp=old;
*ptrToNewHeadPtr=temp;
old=old->link;
}
return 1;
}
else return 0;
}

Related

how to remove code duplications in this code?

I am a new C99 programmer and want the help of the community on this one.
I wrote the following function which receives two pointers for a node (Or simply Node) and a pointer to a pointer to node (Or *Node) an merges them together into one sorted Node.
This is Given:
typedef struct node_t {
int x;
struct node_t *next;
} *Node;
typedef enum {
SUCCESS = 0,MEMORY_ERROR, EMPTY_LIST, UNSORTED_LIST, NULL_ARGUMENT,
} ErrorCode;
int getListLength(Node list);
bool isListSorted(Node list);
This is the code I wrote:
ErrorCode mergeSortedLists(Node list1, Node list2, Node *merged_out)
{
if (merged_out==NULL)
return NULL_ARGUMENT;
if (list1==NULL || list2==NULL)
return EMPTY_LIST;
if (!isListSorted(list1) || !isListSorted(list2))
return UNSORTED_LIST;
Node ptr=*merged_out;
int list1_len=getListLength(list1),list2_len=getListLength(list2);
for (int i=0;i<list1_len+list2_len;i++)
{
int min=0;
if (list1!=NULL && (list2==NULL || (list2!=NULL && list1->x<=list2->x))){
min = list1->x;
list1=list1->next;
}
else{
min=list2->x;
list2=list2->next;
}
ptr->x=min;
if (i==list1_len+list2_len-1){
ptr->next=NULL;//The next for the last Node should be Null
continue;
}
ptr->next=malloc(sizeof(*ptr));
if (ptr->next==NULL){
//We should Free all previosly allocated memory
//except for the first node since it was not allocated via malloc
return MEMORY_ERROR;
}
ptr=ptr->next;
}
ptr=NULL;
return SUCCESS;
}
But after reviewing my code I was told it has a lot of code duplications (more precisely inside he for loop) which should be corrected by using external functions, do u notice any code duplications? and how to fix that, any ideas?

Creating and displaying a basic BST in C

I'm sure I'm making some silly mistake, hope somebody can help me out and clear some of my basic concepts.
Here's my code to create and print a basic BST in C:
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
typedef struct bst
{
int value;
struct bst *left;
struct bst *right;
}T;
T *temp=NULL, *newnode;
T *tree; // had globally declared as NULL previously
T* createnode(int val)
{
newnode=(T*)malloc(sizeof(T));
if(newnode==NULL)
{
printf("Memory not allocated! \n");
}
else
{
newnode->value=val;
newnode->right=NULL;
newnode->left=NULL;
}
return newnode;
}
T * insert_tree(T *tree, int val)
{
if(tree==NULL)
{
newnode=createnode(val);
tree=newnode;
return tree;
}
if (val < tree->value)
{
tree->left=insert_tree(tree->left,val);
}
else if(val > tree->value)
{
tree->right=insert_tree(tree->right, val);
}
return tree;
}
void display_preorder(T *tree) //changed to accept parameter
{
if(tree)
{
printf("%d \n", tree->value);
display_preorder(tree->left);
display_preorder(tree->right);
}
}
int main(void)
{
insert_tree(tree,34);
insert_tree(tree,45);
insert_tree(tree,88);
insert_tree(tree,87);
display_preorder();
return 0;
}
It runs and executes without error, but, the output screen is blank.
Can somebody please point out the errors and mistakes?
Thank You.
The problem is in the insert_tree function.
Because your function gets only a pointer of a tree and not a pointer to a pointer you returned the value.
So, in the main you should place the tree equal to the function.
Your function gets the tree pointer by value and not by reference.
like this:
int main(void)
{
tree = insert_tree(tree, 34);
tree = insert_tree(tree, 45);
tree = insert_tree(tree, 88);
tree = insert_tree(tree, 87);
display_preorder(tree);
getchar();
return 0;
}

Binary heap using queue

There are lots of C examples by using an array to represent the tree.
However, I'm trying to use a tree(Nodes) for the Binary heap.
I was trying to add the child left and then right. In order to insert the elements in Width-first-Search, I've used a Queue. Is this necessary?
My Queue is using a Node* not a int type. Because, if I put a int in the Queue I must search the position of the Node(more time needed). Is this an appropriate way to built a Binary heap?
During the insertion, there are bubbling up and downs. However, since i have a binary heap and also a Queue. Do I have to match the orders in Queue also?
4.Do I need to search for inserting position like a BST? or do I approach to the address directly by using Queue?
I've learned the theory. However, the codes and structures are unfamiliar.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int left(int a,int b)
{
return (int)(a-floor((float)a/(float)b)*b);
}
typedef struct Node
{
int data;
struct Node* leftNext;
struct Node* rightNext;
}Node;
struct queue
{
Node** data;
int top;
int bottom;
int size;
}typedef Queue;
int push(Queue* Q,Node* input)
{
printf("PUSH : %d\n",input);
//한칸은 비울 것임.
if(left((*Q).top-(*Q).bottom,(*Q).size)==(*Q).size-1)
{
printf("큐가 다 찼습니다.\n");
return 0;
}
else
{
//큐의 크기를 넘으면 아래로 이동
if((*Q).top==(*Q).size)
(*Q).top=0;
printf("TOP : %d\n",(*Q).top);
(*Q).data[(*Q).top++]=input;
return 1;
}
}
Node* pop(Queue* Q)
{
if(left((*Q).top-(*Q).bottom,(*Q).size)==0)
printf("큐가 비었습니다.\n");
else
{
if((*Q).bottom==(*Q).size)
(*Q).bottom=0;
printf("BOTTOM : %d\n",(*Q).bottom);
return (*Q).data[(*Q).bottom];
}
}
typedef struct Heap
{
Node* head;
}Heap;
int insert(Node** head,int data,Queue* Q)
{
if((*head)!=NULL)
{
if((*head)->leftNext==NULL)
{
(*head)->leftNext=(Node*)malloc(sizeof(Node));
(*head)->leftNext->data=data;
(*head)->leftNext->leftNext=NULL;
(*head)->leftNext->rightNext=NULL;
push(Q,&(*head)->leftNext);
}
else if((*head)->rightNext==NULL)
{
(*head)->rightNext=(Node*)malloc(sizeof(Node));
(*head)->rightNext->data=data;
(*head)->rightNext->leftNext=NULL;
(*head)->rightNext->rightNext=NULL;
push(Q,&(*head)->rightNext);
(*Q).bottom++;
}
else
{
if(insert((pop(Q)),data,Q)==1)
return 1;
else
return 0;
}
}
else
{
printf("헤드가 비었습니다.");
return 0;
}
return 1;
}
int main()
{
//입력 15 6 12 7 10 17
Heap h;
//큐 초기화
Queue Q;
//큐 크기
int temp=100;
Q.data=(Node**)malloc(sizeof(Node*)*temp);
Q.size=temp;
Q.top=0;
Q.bottom=0;
h.head=(Node*)malloc(sizeof(Node));
h.head->data=15;
h.head->leftNext=NULL;
h.head->rightNext=NULL;
insert(&(h.head),6,&Q);
insert(&(h.head),12,&Q);
insert(&(h.head),7,&Q);
insert(&(h.head),10,&Q);
insert(&(h.head),17,&Q);
return 0;
}

What is wrong with my array of linked lists implementation as all elements get over-written?

I'm trying to implement a hash table as an array of linked lists. Currently I'm trying to have a simple hash table where the key is the index of the array and value is a singly linked list for implementing chaining.
This is the code that I've written so far:
#include<stdio.h>
#include<stdlib.h>
struct Node
{
int value;
struct Node *next;
};
struct Node *hashtable[7];
int empty(int index)
{
if(hashtable[index]==NULL)
return 0;
return 1;
}
void addNode(int frame,struct Node **iter)
{
if(*iter==NULL)
*iter=malloc(sizeof(struct Node));
else
{
while((*iter)->next != NULL)
(*iter)=(*iter)->next;
(*iter)->next=malloc(sizeof(struct Node));
(*iter)=(*iter)->next;
}
(*iter)->value=frame;
(*iter)->next=NULL;
}
void print()
{
int i;
struct Node **iter;
for(i=0;i<7;i++)
{
iter=&hashtable[i];
while(*iter !=NULL)
{
printf("%d%s%d\n",(*iter)->value,"--",i);
(*iter)=(*iter)->next;
}
}
}
int main()
{
int i=0,count=7;
for(i=0;i<7;i++)
hashtable[i]=NULL;
i=empty(1);
printf("%d",i);
do
{
printf("Enter no:\n");
scanf("%d",&i);
struct Node** temp;
temp=&hashtable[i-1%7];
addNode(rand(),temp);
count--;
print();
} while(count > 0);
return 0;
}
When I'm calling print, I can only see one element added to one particular index, which is the last element that was added, what am I doing wrong here?
void add_node(int frame,struct Node **iter)
{
/* find (pointer to) NULL pointer at end of chain */
for ( ; *iter; iter = &(*iter)->next ) {;}
*iter = malloc(sizeof **iter );
(*iter)->value = frame;
(*iter)->next = NULL;
}

Can anyone help me find why this C program work on VS2005 but not on DEV-C++

I have a C program for an exercise and it has a strange issue
The program runs just fine on VS 2005 but it crashes on DEV-C++ and the problem that the problem is that the exercise is always evaluated against DEV-C++
The program is about inserting nodes to a BST and this is where the problem lies...
Well i would really appreciate some help.
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
typedef struct tree_node
{
int value;
int weight;
struct tree_node *left;
struct tree_node *right;
} TREE_NODE;
TREE_NODE *create_tree(int list[], int size);
TREE_NODE *search_pos_to_insert(TREE_NODE *root, int value, int *left_or_right);
// this is the problematic function */
void inorder(TREE_NODE *root); /* Inorder Traversing */
TREE_NODE *temp;
int main()
{
TREE_NODE *root; /* Pointer to the root of the BST */
int values[] = {10, 5, 3, 4, 1, 9, 6, 7, 8, 2}; /* Values for BST */
int size = 10, tree_weight;
root = create_tree(values, 10);
printf("\n");
inorder(root); /* Inorder BST*/
system("PAUSE");
}
TREE_NODE *search_pos_to_insert(TREE_NODE *root, int value, int *left_or_right)
{
if(root !=NULL)
{
temp = root;
if(value >root->value)
{
*left_or_right=1;
*search_pos_to_insert(root->right, value, left_or_right);
}
else
{
*left_or_right=0;
*search_pos_to_insert(root->left, value, left_or_right);
}
}
else
return temp;/* THIS IS THE PROBLEM (1) */
}
TREE_NODE *create_tree(int list[], int size)
{
TREE_NODE *new_node_pntr, *insert_point, *root = NULL;
int i, left_or_right;
/* First Value of the Array is the root of the BST */
new_node_pntr = (TREE_NODE *) malloc(sizeof(TREE_NODE));
new_node_pntr->value = list[0];
new_node_pntr->weight = 0;
new_node_pntr->left = NULL;
new_node_pntr->right = NULL;
root = new_node_pntr;
/* Now the rest of the arrat. */
for (i = 1; i < size; i++)
{
/* THIS IS THE PROBLEM (2) */
insert_point = search_pos_to_insert(root, list[i], &left_or_right);
/* insert_point just won't get the return from temp */
new_node_pntr = (TREE_NODE *) malloc(sizeof(TREE_NODE));
new_node_pntr->value = list[i];
new_node_pntr->weight = 0;
new_node_pntr->left = NULL;
new_node_pntr->right = NULL;
if (left_or_right == 0)
insert_point->left = new_node_pntr;
else
insert_point->right = new_node_pntr;
}
return(root);
}
void inorder(TREE_NODE *root)
{
if (root == NULL)
return;
inorder(root->left);
printf("Value: %d, Weight: %d.\n", root->value, root->weight);
inorder(root->right);
}
Your search_pos_to_insert isn't returning anything in the first section, where root is not NULL. It is recursively calling the function, but not gathering the result. You need to return whatever your recursive calls return to ensure correctness.
You should change the calls
*search_pos_to_insert(root->right, value, left_or_right);
...
*search_pos_to_insert(root->left, value, left_or_right);
to
return search_pos_to_insert(root->right, value, left_or_right);
...
return search_pos_to_insert(root->left, value, left_or_right);
While I haven't delved deep into many issues, are you sure your use of "temp" as a global is correct here? Should it not be local to the search function, so the function is reentrant?
In your function TREE_NODE *search_pos_to_insert() you have code pathes, that don't return a value. Your compiler should issue a warning about it.
The line:
return temp;/* THIS IS THE PROBLEM (1) */
is reached only if the if(root != NULL) evaluates to true.
Replace the recursive calls with:
return search_pos_to_insert(root->right, value, left_or_right);
return search_pos_to_insert(root->left, value, left_or_right);
to make it work.
Frank your the man ..
In some moment i thought that maybe i could return the function itself but i was almost sure it wouldn't work and also i took a different road (to left_or_right) and i was completely lost
Well u saved from a lot of anger and u really saved my day(probably a lot more)

Resources