Node structure gains itself as a parent during expansion - c

My assignment is to write a solver for 3x3 sliding tile puzzle which has to embedded later.
I have the structure
struct node
{
char state[9];
struct node* parentNode;
char lastMove;
} node;
I use a pseudo stack for
struct node
{
char state[9];
struct node* parentNode;
char lastMove;
} node;
I use a stack which will be used later for the IDS algorithm.
struct node stack[60000];
struct node* Node = stack;
#define push(Node, n) (*((Node)++) = (n))
#define pop(Node) (*--(Node))
My function expandNode creates all valid child nodes of its given parent
void expandNode(struct node* parent)
{
char help;
int emptyField = -1;
struct node newNode;
for (int i = 0; i < 9; i++)
{
if (parent->state[i] == '0') emptyField = i;
}
for (int i = 0; i < 4; i++)
{
if(lastMoveVal(parent->lastMove, moves[i]) == '0') continue;
if (moveValid(parent->state, moves[i]) == '1')
{
newNode.parentNode = parent;
...
My main function
void main()
{
struct node root;
char rootState[9] = { '6','8','3','0','4','5','1','7','2' };
assignArray(root.state, rootState);
push(Node, root);
struct node curr;
curr = pop(Node);
expandNode(&curr);
for(int i = 0; i < 10; i++)
{
curr = pop(Node);
printf("\n");
for(int j = 0; j<9; j++)
{
printf("%c", curr.state[j]);
};
printf(" PARENT: ");
for(int j = 0; j<9; j++)
{
printf("%c", curr.parentNode->state[j]);
};
}
}
Here is the output:
683405172 PARENT: 683405172
683145072 PARENT: 683145072
083645172 PARENT: 083645172
As you see the expansion of the nodes is correct but the state of the parent node is not the expected 683045172 but the state of node itself.

Related

Calling malloc in structure

struct NODE{
double theta, phi;
int ID;
int pointer;
};
int main(void)
{
FILE *fp;
int ID[5000][5000];
struct NODE node[5000*5000];
struct NODE node2[5000*5000];
int elem[5000][8];
int tempID;
for(i=0; i< 5000*5000; i++){
node[i].theta = 0;
node[i].phi = 0;
}
for(k=0; k<5000; k++){
for(j=0; j< 5000; j++){
ID[k][j] = -1;
}
}
}
This is a part of the source code of my project. here i want to allocate memory in this lines using malloc. How can i do this??
struct NODE node[5000*5000];
struct NODE node2[5000*5000];
You need to call malloc in the following manner:
struct NODE *node, *node2;
node = malloc(5000*5000*sizeof(*node));
if (node == NULL)
{
exit(1); // or any other error check
}
node2 = malloc(5000*5000*sizeof(*node));
if (node2 == NULL)
{
exit(1); // or any other error check
}
Rest of the code will be unchanged.

How do I Bubble Sort a linked list?

I am trying to create a linked list and sort it by Bubble Sort. I succeeded to create the linked list, but when I am trying to Bubble Sort it, some accidents occur and I do not know the problem. What is the problem?
#include <stdio.h>
#include <stdlib.h>
//the struct of LinkedList
typedef struct Node
{
int data;
struct Node * pNext;
}NODE,*PNODE;
PNODE createList();//Creat one LinkedList
int lengthList(PNODE pHead);//get the length of LinkedList
void sortList(PNODE);//bubble sort
int main()
{
int length;
PNODE pHead=NULL;
pHead=createList();
sortList(pHead);
return 0;
}
//Create LinkedList
PNODE createList()
{
int i,n;
int val;
PNODE pHead=(PNODE)malloc(sizeof(NODE));
if(pHead==NULL)
{
printf("failed to create!\n");
exit(-1);
}
pHead->pNext=NULL;
PNODE pTail=pHead;
printf("please input the length of the LinkedList:");
scanf("%d",&n);
for(i=0;i<n;i++)
{
printf("number %d is:\n",i+1);
scanf("%d",&val);
PNODE pNew=(PNODE)malloc(sizeof(NODE));
if(pNew==NULL)
{
printf("failed to create\n");
exit(-1);
}
pNew->data=val;
pTail->pNext=pNew;
pNew->pNext=NULL;
pTail=pNew;
}
return pHead;
}
//get the length of LinkedList
int lengthList(PNODE pHead)
{
int i=0;
PNODE p=pHead->pNext;
while(p!=NULL)
{
i++;
p=p->pNext;
}
return i;
}
//bubble sort
void sortList(PNODE pHead)
{
int i,j,t,len;
PNODE p,q;
len=lengthList(pHead);
p=pHead->pNext;
for(i=0;i<len-1;i++)
{
for(j=0;j<len-i;j++)
{
q=p->pNext;
if( p->data > q->data)
{
t=p->data;
p->data=q->data;
q->data=t;
}
p=q;//here may be the error
}
}
return;
}
You are running off the end of your list in sortList
p=pHead->pNext;
for(i=0;i<len-1;i++)
{
for(j=0;j<len-i;j++)
{
q=p->pNext;
....
p=q;//here may be the error
}
}
Bug 1) Your list is only len long but you are attempting to advance p to p->pNext far more then len times.
Bug 2) pHead does not need to be a full NODE - it's just a PNODE pointer. You never use its data field. You should have pHead point to the first node in the list, and then start your iteration at pHead rather than pHead->pNext.
Bug 3) You never clean up your memory allocations.
As #Airsource pointed out the bugs, keep in mind most of them are caused because of poor designing choice of your program. Try to do it like below & you will run into less errors
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
typedef struct _Node{
int data;
struct _Node* next;
}Node;
typedef struct {
Node* headPtr;
Node* tailPtr;
unsigned size;
}List;
static void create_node(List* list, int element) {
if (list->headPtr == NULL) {
// List is empty
list->headPtr = (Node* )malloc(sizeof(Node));
list->headPtr->data = element;
list->headPtr->next = 0;
list->tailPtr = list->headPtr;
list->size++;
}else{
// List was already populated
Node* temp = (Node* )malloc(sizeof(Node));
temp->data = element;
temp->next = 0;
list->tailPtr->next = temp;
list->tailPtr = temp;
list->size++;
}
}
void create_list(List* list, int length){
int ele;
int i;
list->headPtr = list->tailPtr = 0;
list->size = 0;
for (i = 0; i < length; i++) {
scanf("%d", &ele);
create_node(list, ele);
}
}
void print_list(List* list){
Node* loop = list->headPtr;
while(loop){
printf("%d ", loop->data);
loop = loop->next;
}
printf("\n");
}
int main(){
List* list;
int n;
printf("Enter the length of the list: ");
scanf("%d", &n);
create_list(list, n);
print_list(list);
bubble_sort(list);
print_list(list);
if (cleanup(list))
printf("Memory rescued!!\n");
else
printf("OOPS!! Error\n");
return 0;
}
Moreover, you can get the size anytime just by list->size. No need for separate function to do that.
Finally to sort it using bubble sort you could do something like this below
void bubble_sort(List* list) {
int i, j;
Node* first, *second;
int temp;
first = list->headPtr;
second = list->headPtr->next;
for (i = 0; i < list->size - 1; i++) {
for (j = 0; j < list->size - i - 1; j++) {
if (first->data > second->data){
temp = first->data;
first->data = second->data;
second->data = temp;
}
first = second;
second = second->next;
}
first = list->headPtr;
second = list->headPtr->next;
}
}
and for cleanup you do this
bool cleanup(List* list) {
Node* curr = list->headPtr;
Node* nxt = list->headPtr->next;
while(nxt){
free(curr);
curr = nxt;
nxt = curr->next;
}
list->headPtr = list->tailPtr = 0;
list->size = 0;
return !nxt ? true: false;
}
There are couple of bugs in your program. I will address them one by one:
Line 28 PNODE pHead=(PNODE)malloc(sizeof(NODE));
Here you are allocating a memory and creating a node before checking if n>0 or not.
Line 36 printf("please input the length of the LinkedList:");
Now up to this point you have created a one node, head node which has no value in it (so contains garbage)
In effect your createList() creates a linked list with n+1 nodes instead of n and the head->value contains garbage.
Solution:
printf("please input the length of the LinkedList:");
scanf("%d", &n);
for(i=0; i<n; i++)
{
PNODE pNew = (PNODE)malloc(sizeof(NODE));
if(pNew == NULL)
{
printf("failed to create!\n");
exit(-1);
}
scanf("%d", &val);
pNew->data = val;
pNew->pNext = NULL;
if (!i)
pHead = pNew;
else
pTail->pNext = pNew;
pTail = pNew;
}
return pHead;
Line 59 PNODE p=pHead->pNext;
Here you are counting nodes starting from the second node (leaving out head). No wonder you will get length as n as you have created a linked list of length n+1 in your createList()
Imagine what if n = 0 and thus pHead = NULL?
Then this line will result in SegFault.
Solution:
change PNODE p=pHead->pNext; to PNODE p = pHead;
Line 73 p=pHead->pNext;
Here you will start sorting excluding the first node, head node.
Also this should be inside the outter for and outside of the inner for to reset the p to first node for each pass.
Line 76 for(j=0;j<len-i;j++)
Here j must be less than len - 1 - i as in pass 1 (i = 0) in the worst case j will be equal to len-1 for j < len-i, where p will point to the last node of linked list and q will be NULL as q = p -> pNext. Which will make q->data to result in SegFault.
To summarise, your sort routine is producing SegFault in the very first Pass and even if it didn't (by properly adjusting the loop-terminating expression in inner for) the outer for loop is contributing nothing towards the sorting except increasing the time complexity.
Solution:
for(i = 0; i < len - 1; i++)
{
p = pHead;
for(j = 0; j < len - 1 - i; j++)
{
q = p -> pNext;
if(p->data > q->data)
{
t = p -> data;
p -> data = q -> data;
q -> data = t;
}
p = q;
}
}
A question:
How are you checking whether element have been sorted or not?
A printList() routine would have been helpful in spotting the above bugs.
"Always verify whether you correctly stored the input or not by explicitly printing the same before processing it!"

multiway tree memory allocation of children

I am trying to build a multi-way tree in C. I've got stuck on allocation memory for childrens.
I have a vector which contains the fathers of each node. Here is my code:
#define MAX_CHILDS 10
int t[10] = {1, 2, 4, 1, -1, 3, 2, 1, 0, 4};
NODE *root;
NODE *v[MAX_CHILDS];
//add children for specified node
void ADD_REF(int i) {
v[i]->children[v[i]->child_count] = v[t[i]];
v[i]->child_count++;
}
//creates the tree
NODE *T1(int n, int *t) {
int root = 0;
for (int i = 0; i < n; i++) {
v[i] = (NODE *) malloc(sizeof(NODE));
v[i]->info = i;
v[i]->child_count = 0;
v[i]->children = (NODE **) malloc(sizeof(NODE)); // I think the problem is here
}
for (int i = 0; i<n; i++) {
if (t[i] == -1)
root = i;
else
ADD_REF(i);
}
return v[root];
}
void main() {
root = T1(MAX_CHILDS, t);
print_tree(root, 0); // prints the tree
}
Here is the structure of the NODE:
typedef struct NODE {
int info;
int child_count;
struct NODE **children;
} NODE;
I am not sure exactly if the problem is at the memory allocation. With my logic it should work.
I've found my error.
The memory allocation was ok. The problem was at adding new children.
I've added children for the current node instead of adding children to it's parent.
This was the solve:
void ADD_REF(int i) {
v[t[i]]->children[v[t[i]]->child_count] = v[i];
v[t[i]]->child_count++;
}

Hashing, linked list, delete node

My task is to delete a node from a array of pointers which point to structure.
My code doesn't work and I just don't know why:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "Jmena4.h"
#define LENGTH 101
#define P 127
#define Q 31
typedef struct node {
char *name;
struct uzel *next;
} NODE;
int hash(const char Name[]) {
int i;
int n = strlen(Name);
int result;
result = Name[0] * P + Name[1] * Q + Name[n - 1] + n;
return result % LENGTH;
}
void Insert(NODE *array[], const char *name) {
NODE *u;
int h;
u = (NODE*)malloc(sizeof(NODE));
u->name = name;
h = hash(name);
u->next = array[h];
array[h] = u;
}
int Search(NODE *array[], const char *name) {
NODE *u;
u = array[hash(name)];
while (u != NULL) {
if (strcmp(u->name, name) == 0) {
printf("%s\n", u->name);
return 1;
}
u = u->next;
}
printf("Name: %s wasn't found\n", name);
return 0;
}
int Delete(NODE *array[], const char *name) {
NODE *current;
NODE *previous;
int position = hash(name);
current = array[position];
previous = NULL;
while (current != NULL) {
if (strcmp(current->name, name) == 0) {
if (previous == NULL) {
array[position] = current->next;
return 1;
} else {
previous->next = current->next;
current = NULL;
return 1;
}
}
previous = current;
current = current->next;
}
return 0;
}
int main() {
int i;
NODE *array[LENGTH];
for (i = 0; i < LENGTH; i++) {
array[i] = NULL;
}
for (i = 0; i < Pocet; i++) {
Insert(array, Jmena[i]);
}
for (i = 0; i < PocetZ; i++) {
Delete(array, JmenaZ[i]);
}
Search(array, "Julie");
system("PAUSE");
return 0;
}
EDIT 1: I changed names of variables and instead of position = array[position] should be current = array[position], but it still doesn't work.
EDIT 2 : In array Jmena is string "Julie" and I can search it after Insert function, but after I delete strings from JmenaZ which not included "Julie" program output is: Name: Julie wasn't found.
For one thing, current isn't initialized before it gets tested in the while loop.

n-ary tree searching function

I'm trying to make a function for n-ary tree searching, but it doesn't work well, it returns wrong node after level 2. Anyone knows why?
Here is node implementation
typedef struct node
{
char name[30];
int year;
struct node* ptr;
struct node* p[10];
} node;
And there is a function
node *search(node *p, char* name, int year)
{
int i, n;
if(p == NULL)
return (NULL);
if((!strcmp(p->name, name) && (p->year == year))
return (p);
n = number(p); \\returns number of childs
for(i = 0; i < n; i++)
if(search(p->p[i], name, year))
return (p->p[i]);
}
You return the child that holds the requested node but not the node itself.
for(i = 0; i < n; i++)
{
if ((p2 = search(p->p[i], name, year)))
return p2;
}
return NULL;

Resources