Deleting the root of a heap with no effect - c

I have tried to implement functions related to heaps in C and I have stumbled across a problem with my delete heap root function.
When the heap has only one element, the function does not delete anything, even though I explicitly said that the heap becomes NULL if it has only one element.
Below I have posted my code with all the functions that I have created (maybe there is something wrong with the other functions, but it doesn't seem likely to me). The main problem is the deleteRoot function.
#include <stdio.h>
#include <stdlib.h>
typedef struct Heap Heap;
struct Heap
{
Heap *left;
Heap *right;
Heap *parent;
int value;
};
Heap *newHeap(int x)
{
Heap *t = malloc(sizeof(Heap));
t->value = x;
t->left = NULL;
t->right = NULL;
t->parent = NULL;
return t;
}
void printHeap(Heap *h)
{
if(h!=NULL)
{
printf("Value %d (",h->value);
printHeap(h->left);
printf(")");
printf("(");
printHeap(h->right);
printf(")");
}
}
int getHeapMinDepth(Heap *h)
{
if(h == NULL) return 0;
int leftdepth = getHeapMinDepth(h->left);
int rightdepth = getHeapMinDepth(h->right);
int mindepth = (leftdepth < rightdepth) ? leftdepth : rightdepth;
return mindepth + 1;
}
int getHeapMaxDepth(Heap *h)
{
if(h == NULL) return 0;
int leftdepth = getHeapMaxDepth(h->left);
int rightdepth = getHeapMaxDepth(h->right);
int maxdepth = (leftdepth > rightdepth) ? leftdepth : rightdepth;
return maxdepth + 1;
}
void bubbleUp(Heap *h)
{
int aux;
if(h->parent != NULL && h != NULL)
{
if(h->parent->value < h->value)
{
aux = h->value;
h->value = h->parent->value;
h->parent->value = aux;
bubbleUp(h->parent);
}
}
}
void bubbleDown(Heap *h)
{
int aux;
if(h != NULL)
{
if(h->left != NULL && h->left->value > h->value)
{
aux = h->value;
h->value = h->left->value;
h->left->value = aux;
bubbleDown(h->left);
}
else if(h->right != NULL && h->right->value > h->value)
{
aux = h->value;
h->value = h->right->value;
h->right->value = aux;
bubbleDown(h->right);
}
}
}
void addElement(Heap *h ,int x)
{
if(h == NULL) h = newHeap(x);
else if(h->left == NULL)
{
h->left = newHeap(x);
h->left->parent = h;
bubbleUp(h->left);
}
else if(h->right == NULL)
{
h->right = newHeap(x);
h->right->parent = h;
bubbleUp(h->right);
}
else if(getHeapMinDepth(h->left) <= getHeapMinDepth(h->right)) addElement(h->left,x);
else addElement(h->right,x);
}
void deleteRoot(Heap *h)
{
Heap *auxheap = h;
if(h!=NULL && h->left == NULL && h->right == NULL) h = NULL;
else if(h!=NULL)
{
while(auxheap ->left != NULL || auxheap->right != NULL)
{
if(getHeapMaxDepth(auxheap->left) > getHeapMaxDepth(auxheap->right)) auxheap = auxheap->left;
else auxheap = auxheap->right;
}
h->value = auxheap->value;
auxheap->value = -1;
auxheap = auxheap->parent;
if(auxheap->right != NULL && auxheap->right->value == -1) auxheap->right = NULL;
else auxheap->left = NULL;
bubbleDown(h);
}
}
int main()
{
int i;
Heap *h = newHeap(2);
deleteRoot(h);
addElement(h,12);
addElement(h,5);
addElement(h,7);
addElement(h,15);
printHeap(h);
return 0;
}
Thank you in advance!

In order to avoid your call-by-value problem in C, use a pointer to pointer as parameter for your root-deletion function.
void deleteRoot(Heap **h)
{
/* assuming that h is not NULL, which is guaranteed with "&something" */
if((*h)!=NULL && (*h)->left == NULL && (*h)->right == NULL) *h = NULL;
/* ... */
}
int main()
{
int i;
Heap *h = newHeap(2);
deleteRoot(&h);
/* ... */
return 0;
}

Related

How to remove necessary nodes from a binary tree?

Good evening forum members.
The following is on the agenda:
Read a sequence of coordinates (x, y, z) of spatial points from the file, ordered by distance from the point of origin (develop a separate function for calculating the distance and store this value in the data structure);
To bypass use the bottom option from right to left;
Extract from the tree all nodes whose z coordinate falls within the specified range zmin ..zmax (I decided to take from 7 to 14) and indicate their number;
To completely erase the tree, use the direct (from the root) version of the bypass from left to right;
Print the entire tree using a non-recursive function.
Please help with number 3. It is not possible to implement the deletion algorithm according to a given condition. It either does not work at all, or errors arrive (
Thanks in advance to everyone who responds
CODE:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define MAX_LEN 8
#define STACK_INIT_SIZE 20
typedef struct Tree {
int z;
int viddal;
struct Tree* left, * right;
} TREE;
typedef struct Stack {
size_t size, limit;
TREE** data;
} STACK;
int Distance(FILE* ftxt, int* vid, int* z_cord);
int CreateTreeFromFile(void);
TREE* NewNode(FILE* f, int viddal, int z);
void AddNewNode(TREE* pnew);
void PrintTreeNIZ(TREE* proot);
void iterPostorder(TREE* root);
void OutputTreeStructure(const char* title);
void ShowTree(TREE* proot, int level);
void ShowLevels(void);
int TreeHeight(TREE* proot);
void EraseTree(TREE* proot);
void DeleteSomeNodes(void);
int DeleteNode(TREE* pnew_adr);
TREE* root;
int main(){
system("chcp 1251");
if (CreateTreeFromFile() == 0)
return 0;
puts("\n Created tree: ");
PrintTreeNIZ(root);
OutputTreeStructure("of created tree");
DeleteSomeNodes();
OutputTreeStructure("of the new tree");
EraseTree(root);
root = NULL;
puts("\n Tree was deleted from DM\n\n");
return 0;
}
int Distance(FILE* ftxt, int *vid, int* z_cord) {
TREE* pel = (TREE*)malloc(sizeof(TREE));
if (feof(ftxt)) {;
return NULL;
}
else {
int x, y, z;
fscanf(ftxt, "%d%d%d", &x, &y, &z);
*z_cord = z;
*vid = sqrt(x * x + y * y + z * z);
}
}
int CreateTreeFromFile()
{
const char* fname = "Cords_1.txt";
FILE* fvoc = fopen(fname, "r");
if (fvoc == NULL) {
printf("\n\t\tCan`t open file %s...\n", fname);
return 0;
}
TREE* node;
int viddal, z;
Distance(fvoc, &viddal, &z);
while ((node = NewNode(fvoc, viddal, z)) != NULL) {
AddNewNode(node);
Distance(fvoc, &viddal, &z);
}
fclose(fvoc);
return 1;
}
TREE* NewNode(FILE* f, int viddal, int z)
{
TREE* pel;
pel = (TREE*)malloc(sizeof(TREE));
if (feof(f)) {
return NULL;
}
pel->viddal = viddal;
pel->z = z;
pel->left = pel->right = NULL;
return pel;
}
void AddNewNode(TREE* pnew) {
if (root == NULL) {
root = pnew;
return;
}
TREE* prnt = root;
do {
if (pnew->viddal == prnt->viddal) {
free(pnew);
return;
}
if (pnew->viddal < prnt->viddal) {
if (prnt->left == NULL) {
prnt->left = pnew;
return;
}
else
prnt = prnt->left;
}
else {
if (prnt->right == NULL) {
prnt->right = pnew;
return;
}
else
prnt = prnt->right;
}
} while (1);
}
void PrintTreeNIZ(TREE* proot)
{
if (proot == NULL)
return;
printf("\n Right Tree");
iterPostorder(proot->right);
printf("\n\n Left Tree");
iterPostorder(proot->left);
printf("\n\n Korin - %d", proot->viddal);
}
void OutputTreeStructure(const char* title)
{
printf("\n\n\n Structur%s:\n\n", title);
ShowLevels();
ShowTree(root, 0);
puts("\n");
}
#define TAB 7
void ShowTree(TREE* proot, int level)
{
if (proot == NULL) return;
ShowTree(proot->right, level + 1);
printf("\n%*c%d", level * TAB + 10, ' ', proot->viddal);
ShowTree(proot->left, level + 1);
}
void ShowLevels(void)
{
int lev;
printf(" Level: ");
for (lev = 1; lev <= TreeHeight(root); lev++)
printf(" %-*d", 6, lev);
printf("\n\n");
}
int TreeHeight(TREE* proot)
{
int lh, rh;
if (proot == NULL) return 0;
lh = TreeHeight(proot->left);
rh = TreeHeight(proot->right);
return lh > rh ? lh + 1 : rh + 1;
}
void EraseTree(TREE* proot)
{
if (proot == NULL)
return;
EraseTree(proot->left);
EraseTree(proot->right);
free(proot);
}
STACK* createStack() {
Stack* tmp = (Stack*)malloc(sizeof(Stack));
tmp->limit = STACK_INIT_SIZE;
tmp->size = 0;
tmp->data = (TREE**)malloc(tmp->limit * sizeof(TREE*));
return tmp;
}
void freeStack(Stack** s) {
free((*s)->data);
free(*s);
*s = NULL;
}
void push(Stack* s, TREE* item) {
if (s->size >= s->limit) {
s->limit *= 2;
s->data = (TREE**)realloc(s->data, s->limit * sizeof(TREE*));
}
s->data[s->size++] = item;
}
TREE* pop(Stack* s) {
if (s->size == 0) {
exit(7);
}
s->size--;
return s->data[s->size];
}
TREE* peek(Stack* s) {
return s->data[s->size - 1];
}
void iterPostorder(TREE* root) {
Stack* ps = createStack();
TREE* lnp = NULL;
TREE* peekn = NULL;
while (!ps->size == 0 || root != NULL) {
if (root) {
push(ps, root);
root = root->left;
}
else {
peekn = peek(ps);
if (peekn->right && lnp != peekn->right) {
root = peekn->right;
}
else {
pop(ps);
printf("\n\t Visited -> %d", peekn->viddal);
lnp = peekn;
}
}
}
freeStack(&ps);
}
// HELP WITH THAT
//--------------------------------------------------------------------------------------------
void DeleteSomeNodes(void)
{
printf("\n\t Deleting needing nods:\n");
TREE* pfind = (TREE*)malloc(sizeof(TREE));
do {
if (pfind->z >= 7 && pfind->z <= 14) {
DeleteNode(root);
printf(" Number %d was deleted from tree\n", root);
}
} while (1);
puts("\n\n");
}
#define NoSubTree 0
#define LeftSubTree -1
#define RightSubTree 1
#define TwoSubTrees 2
int DeleteNode(TREE* pnew_adr)
{
TREE* proot = root;
int subtr;
if (proot == NULL) return 0;
if (pnew_adr->viddal < proot->viddal)
return DeleteNode(proot->left);
if (pnew_adr->viddal > proot->viddal)
return DeleteNode(proot->right);
if (proot->left == NULL && proot->right == NULL)
subtr = NoSubTree;
else if (proot->left == NULL)
subtr = RightSubTree;
else if (proot->right == NULL)
subtr = LeftSubTree;
else
subtr = TwoSubTrees;
switch (subtr) {
case NoSubTree:
root = NULL; break;
case LeftSubTree:
root = proot->left; break;
case RightSubTree:
root = proot->right; break;
case TwoSubTrees:
TREE* pnew_root = proot->right, * pnew_prnt = proot;
while (pnew_root->left != NULL) {
pnew_prnt = pnew_root;
pnew_root = pnew_root->left;
}
pnew_root->left = proot->left;
if (pnew_root != proot->right) {
pnew_prnt->left = pnew_root->right;
pnew_root->right = proot->right;
}
root = pnew_root;
}
free(proot);
return 1;
}
//--------------------------------------------------------------------------------------------

Why is my Hash Map insert function not working?

I am making a Hash Map with people's names as its key using C language. I am using separate chaining to resolve the collision.
This is my code:
#include<stdio.h>
#include<stdlib.h>
#define MinTableSize 1
#include <stdbool.h>
//Colission resolution Using linked list
struct ListNode;
typedef struct ListNode *Position;
struct HashTbl;
typedef struct HashTbl *HashTable;
typedef unsigned int Index;
Index Hash(const char *Key, int Tablesize)
{
unsigned int HashVal = 0;
while(*Key != '\0')
{
HashVal += *Key++;
}
return HashVal % Tablesize;
}
struct ListNode
{
int Element;
Position Next;
};
typedef Position List;
struct HashTbl
{
int TableSize;
List *TheLists;
};
//Function to find next prime number for the size
bool isPrime(int n)
{
if(n <= 1)
{
return false;
}
if(n <= 3)
{
return true;
}
if(n%2 == 0 || n%3 == 0)
{
return false;
}
for(int i = 5; i*i <= n; i = i + 6)
{
if(n%i == 0 || n%(i + 2) == 0)
{
return false;
}
}
return true;
}
int NextPrime(int N)
{
if(N <= 1)
{
return 2;
}
int prime = N;
bool found = false;
while(!found)
{
prime++;
if(isPrime(prime))
{
found = true;
}
}
return prime;
}
HashTable InitializeTable(int TableSize)
{
HashTable H;
int i;
if(TableSize < MinTableSize)
{
printf("Table size is too small\n");
return NULL;
}
H = malloc(sizeof(struct HashTbl));
if(H == NULL)
{
printf("Out of space\n");
return NULL;
}
H->TableSize = NextPrime(TableSize);
H->TheLists = malloc(sizeof(List) * H->TableSize);
if(H->TheLists == NULL)
{
printf("Out of space\n");
return NULL;
}
for(i = 0; i < H->TableSize; i++)
{
H->TheLists[i] = malloc(sizeof(struct ListNode));
if(H->TheLists[i] == NULL)
{
printf("Out of space\n");
return NULL;
}
else
{
H->TheLists[i]->Next = NULL;
}
}
return H;
}
//funtion to find the value
Position Find(const char *Key, HashTable H)
{
Position P;
List L;
L = H->TheLists[Hash(Key, H->TableSize)];
P = L->Next;
while(P != NULL && P->Element != Key)
{
P = P->Next;
}
return P;
}
void Insert(const char *Key, HashTable H)
{
Position Pos;
Position NewCell;
List L;
Pos = Find(Key, H);
if(Pos == NULL)
{
NewCell = malloc(sizeof(struct ListNode));
if(NewCell == NULL)
{
printf("Out of space\n");
return NULL;
}
else
{
L = H->TheLists[Hash(Key, H->TableSize)];
NewCell->Next;
NewCell->Element = Key;
L->Next = NewCell;
printf("Key inserted\n");
}
}
else
{
printf("Key already exist\n");
}
}
int main()
{
char Name[6][20] = {"Joshua", "Erica", "Elizabeth", "Monica", "Jefferson", "Andrian"};
int Size = sizeof(Name[0])/sizeof(Name[0][0]);
HashTable H = InitializeTable(Size);
Insert(Name[0], H);
Insert(Name[1], H);
Insert(Name[2], H);
Insert(Name[3], H);
}
The putout of this code is:
Key inserted
Key inserted
This means, it only successfully inserted two keys, while the other name has not been inserted. I think there's some error in my Insert() function, but I got no clue. I tried using an online compiler and it compile properly.

Getting Segmentation fault in C code while trying to assign a pointer to some object

I am trying to solve a question in C language. The problem statement is(reading whole problem is not important for my doubt):
Given an arbitrary unweighted rooted tree which consists of N nodes.
The goal of the problem is to find largest distance between two nodes in a tree.
Distance between two nodes is a number of edges on a path between the nodes (there will be a unique path between any pair of nodes since it is a tree).
The nodes will be numbered 0 through N - 1.
The tree is given as an array A, there is an edge between nodes A[i] and i (0 <= i < N). Exactly one of the i's will have A[i] equal to -1, it will be root node.
I made TreeNode and I am storing all next connections TreeNode pointers in array(like adjacency list in graph)
My solution is:
/**
* #input A : Integer array
* #input n1 : Integer array's ( A ) length
*
* #Output Integer
*/
struct TreeNode2 {
int value;
struct TreeNode2 *next;
};
struct TreeNode2* createNode(int n)
{
struct TreeNode2 *node = (struct TreeNode2 *)calloc(1, sizeof(struct TreeNode2));
node->value = n;
node->next = NULL;
return node;
}
int maximum(int a,int b)
{
if(a>b)
return a;
return b;
}
int dfs(struct TreeNode2 **tree, int node)
{
if( tree[node] == NULL )
return 0;
int len1 = 0;
int len2 = 0;
struct TreeNode2 *ptr = tree[node];
while(ptr!=NULL)
{
int curr = dfs(tree, (ptr->value));
if( curr > len1 )
{
len1 = curr;
}
else if(curr > len2)
{
len2 = curr;
}
ptr = ptr->next;
}
return maximum( len1 + len2 , maximum( len1 , len2 ) + 1 );
}
int solve(int* A, int n1)
{
struct TreeNode2 *tree[n1];
int i=0;
for(i=0;i<n1;i++)
{
tree[i] = NULL;
}
for(i=0;i<n1;i++)
{
if(A[i] != -1)
{
struct TreeNode2 *temp = tree[i];
struct TreeNode2 *newNode = createNode(A[i]);
tree[i] = newNode;
newNode->next = temp;
// printf("A[i] = %d \n",A[i]);
struct TreeNode2 *temp2 = tree[ A[i] ];
struct TreeNode2 *newNode2 = createNode(i);
tree[ A[i] ] = newNode2;
newNode2->next = temp2;
}
}
int ans = dfs(tree, 0);
return ans;
}
I'm getting the segmentation fault the moment I am adding
tree[ A[i] ] = newNode2;
in solve function in forloop for input -1, 0. I tried tree[A[i]] = NULL (it worked). The problem is when A[i] = 0, tree[0] = NULL is working but tree[0] = newNode2 is not working why.?
Finally I caught the problem, actually in this problem tree connection is undirected so the code is stuck in loop inside dfs. I used visited array to solve this issue.
From the link, the example explanation shows that node 0 has three [direct] children (nodes, 1, 2, 3).
I could be wrong about this, but I think an algorithm that works is as follows:
As we build the tree, we remember the node with the maximum depth.
After the tree is built, we can traverse it to find the maximum depth of any [leaf] node that is not max node we found when building.
The solution is the sum of the depth of those two nodes
Here's some code I wrote to do that. I submitted it for test input and it passed.
Edit: I've revised the test and now it passes all tests but exceeds the time limit in the "Efficiency" test.
I expected as much because of the [seeming] O(n^2) but I wanted to try a non-standard approach that doesn't use "visited".
I added some code to dump a text file that can be fed to graphviz with -DGRAPH. It produces an output file: grf. To process this, do:
dot -Tsvg < grf > grf.svg
Then, you can point your browser to the grf.svg file to display the graph.
Anyway, here's the working but slow code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define sysfault(_fmt...) \
do { \
printf(_fmt); \
exit(1); \
} while (0)
#ifndef ROOTLEAF
#define ROOTLEAF 0
#endif
#if ROOTLEAF
#define PTROK(_ptr) (_ptr != NULL)
#else
#define PTROK(_ptr) 1
#endif
#ifdef DEBUG
#define dbgprt(_fmt...) \
do { \
printf(_fmt); \
} while (0)
#define nodeshow(_node,_tag) \
do { \
_nodeshow(_node,_tag); \
} while (0)
#ifndef GRAPH
#define GRAPH
#endif
#else
#define dbgprt(_fmt...) \
do { \
} while (0)
#define nodeshow(_node,_tag) \
do { \
} while (0)
#endif
#define MAXNODE 40000
#define COUNTOF(_arr) \
(sizeof(_arr) / sizeof(_arr[0]))
typedef struct node node_t;
struct node {
int paridx;
int depth;
node_t *parent;
node_t *next;
node_t *cldhead;
node_t *cldtail;
node_t *leaf;
};
static node_t *root = NULL;
static node_t *lhsbest = NULL;
static node_t *rhsbest = NULL;
static int Acnt = -1;
static node_t nodelist[MAXNODE + 1] = { 0 };
static int soldepth;
static FILE *xfgrf;
static char *
tlsbuf(void)
{
static int bufidx = 0;
static char buf[16][1000];
char *bp;
bp = buf[bufidx];
++bufidx;
bufidx %= 16;
*bp = 0;
return bp;
}
static int
nodenum(node_t *node)
{
if (node != NULL)
return node - nodelist;
else
return -1;
}
static char *
nodexid(node_t *lhs,node_t *rhs)
{
int lhsnum = nodenum(lhs);
int rhsnum = nodenum(rhs);
int tmp;
char *buf;
if (lhsnum > rhsnum) {
tmp = lhsnum;
lhsnum = rhsnum;
rhsnum = tmp;
}
buf = tlsbuf();
sprintf(buf,"%d,%d",lhsnum,rhsnum);
return buf;
}
static void
_nodeshow(node_t *node,const char *tag)
{
#ifdef DEBUG
if (node != NULL) {
dbgprt("nodeshow: %s node=%d paridx=%d depth=%d\n",
tag,nodenum(node),node->paridx,node->depth);
}
else
dbgprt("nodeshow: %s null\n",tag);
#endif
}
// newnode -- create new node;
static node_t *
newnode(int idx,node_t *par)
{
node_t *node;
node = &nodelist[idx];
if (par != NULL) {
node->paridx = nodenum(par);
node->depth = par->depth + 1;
}
else
node->paridx = -1;
node->parent = par;
return node;
}
// fastfind -- find node based on i from A[i]
static node_t *
fastfind(int value)
{
node_t *node;
node = &nodelist[value];
nodeshow(node,"fastfind");
return node;
}
// addchild -- attach child node to parent
static void
addchild(node_t *par,node_t *cld)
{
cld->next = par->cldhead;
par->cldhead = cld;
}
int
pathok(node_t *cur)
{
int okay;
if (ROOTLEAF)
okay = (cur != NULL);
else
okay = (cur != NULL) && (cur != root);
return okay;
}
int
pathcost(node_t *lhs,node_t *rhs)
{
int lhsok;
int rhsok;
int cost;
dbgprt("pathcost: ENTER lhs=%d rhs=%d xid=%s\n",
nodenum(lhs),nodenum(rhs),nodexid(lhs,rhs));
cost = 0;
if (lhs == root) {
dbgprt("pathcost: QWKROOT\n");
cost = rhs->depth;
lhs = NULL;
rhs = NULL;
}
while (1) {
if ((lhs == NULL) && (rhs == NULL))
break;
// join at lower level than root
if (lhs == rhs)
break;
#ifdef DEBUG
nodeshow(lhs,"LHS");
nodeshow(rhs,"RHS");
#endif
lhsok = pathok(lhs);
rhsok = pathok(rhs);
if (PTROK(lhs) && PTROK(rhs) && (lhs->depth > rhs->depth)) {
//nodeshow(lhs,"LHSDEEP");
if (lhsok) {
cost += 1;
dbgprt("pathcost: LCOST/D cost=%d\n",cost);
lhs = lhs->parent;
}
continue;
}
if (PTROK(lhs) && PTROK(rhs) && (rhs->depth > lhs->depth)) {
//nodeshow(lhs,"RHSDEEP");
if (rhsok) {
cost += 1;
dbgprt("pathcost: RCOST/D cost=%d\n",cost);
rhs = rhs->parent;
}
continue;
}
if (PTROK(lhs) && lhsok) {
cost += 1;
dbgprt("pathcost: LCOST/S cost=%d\n",cost);
lhs = lhs->parent;
}
if (PTROK(rhs) && rhsok) {
cost += 1;
dbgprt("pathcost: RCOST/S cost=%d\n",cost);
rhs = rhs->parent;
}
}
dbgprt("pathcost: EXIT cost=%d\n",cost);
return cost;
}
void
search1(void)
{
int curcost;
node_t *end = &nodelist[Acnt];
node_t *leafbase = NULL;
node_t *lhs = NULL;
node_t *rhs = NULL;
int bestcost = 0;
int leafcnt = 0;
// link all leaf nodes together
for (rhs = nodelist; rhs < end; ++rhs) {
if (ROOTLEAF) {
if (rhs != nodelist) {
if (rhs->cldhead != NULL)
continue;
}
}
else {
if (rhs->cldhead != NULL)
continue;
}
nodeshow(rhs,"ISLEAF");
if (leafbase == NULL)
leafbase = rhs;
if (lhs != NULL)
lhs->leaf = rhs;
lhs = rhs;
++leafcnt;
}
lhsbest = NULL;
rhsbest = NULL;
do {
if (leafcnt == 1) {
bestcost = leafbase->depth;
lhsbest = leafbase;
break;
}
for (lhs = leafbase; lhs != NULL; lhs = lhs->leaf) {
nodeshow(lhs,"LEAFLHS");
for (rhs = lhs->leaf; rhs != NULL; rhs = rhs->leaf) {
curcost = pathcost(lhs,rhs);
if (curcost > bestcost) {
lhsbest = lhs;
nodeshow(lhsbest,"LHSGUD");
rhsbest = rhs;
nodeshow(rhsbest,"RHSGUD");
bestcost = curcost;
}
}
}
} while (0);
nodeshow(lhsbest,"LHSBEST");
nodeshow(rhsbest,"RHSBEST");
soldepth = bestcost;
}
int
pathcost2(node_t *lhs,node_t *rhs)
{
int lhsok;
int rhsok;
int cost;
dbgprt("pathcost2: ENTER lhs=%d rhs=%d xid=%s\n",
nodenum(lhs),nodenum(rhs),nodexid(lhs,rhs));
cost = 0;
if (lhs == root) {
dbgprt("pathcost: QWKROOT\n");
cost = rhs->depth;
lhs = NULL;
rhs = NULL;
}
while (1) {
if ((lhs == NULL) && (rhs == NULL))
break;
// join at lower level than root
if (lhs == rhs)
break;
#ifdef DEBUG
nodeshow(lhs,"LHS");
nodeshow(rhs,"RHS");
#endif
lhsok = pathok(lhs);
rhsok = pathok(rhs);
if (PTROK(lhs) && PTROK(rhs) && (lhs->depth > rhs->depth)) {
//nodeshow(lhs,"LHSDEEP");
if (lhsok) {
cost += 1;
dbgprt("pathcost: LCOST/D cost=%d\n",cost);
lhs = lhs->parent;
}
continue;
}
if (PTROK(lhs) && PTROK(rhs) && (rhs->depth > lhs->depth)) {
//nodeshow(lhs,"RHSDEEP");
if (rhsok) {
cost += 1;
dbgprt("pathcost: RCOST/D cost=%d\n",cost);
rhs = rhs->parent;
}
continue;
}
if (PTROK(lhs) && lhsok) {
cost += 1;
dbgprt("pathcost: LCOST/S cost=%d\n",cost);
lhs = lhs->parent;
}
if (PTROK(rhs) && rhsok) {
cost += 1;
dbgprt("pathcost: RCOST/S cost=%d\n",cost);
rhs = rhs->parent;
}
}
dbgprt("pathcost2: EXIT cost=%d\n",cost);
return cost;
}
void
search2(void)
{
int curcost;
node_t *end = &nodelist[Acnt];
node_t *leafbase = NULL;
node_t *lhs = NULL;
node_t *rhs = NULL;
int bestcost = 0;
int leafcnt = 0;
int maxdepth = 0;
lhsbest = NULL;
rhsbest = NULL;
// link all leaf nodes together
for (rhs = nodelist; rhs < end; ++rhs) {
if (rhs->cldhead != NULL)
continue;
nodeshow(rhs,"ISLEAF");
if (rhs->depth > maxdepth) {
maxdepth = rhs->depth;
rhsbest = rhs;
}
if (leafbase == NULL)
leafbase = rhs;
if (lhs != NULL)
lhs->leaf = rhs;
lhs = rhs;
++leafcnt;
}
do {
bestcost = maxdepth;
lhsbest = leafbase;
if (leafcnt == 1) {
bestcost = leafbase->depth;
lhsbest = leafbase;
break;
}
for (lhs = leafbase; lhs != NULL; lhs = lhs->leaf) {
nodeshow(lhs,"LEAFLHS");
for (rhs = lhs->leaf; rhs != NULL; rhs = rhs->leaf) {
curcost = pathcost(lhs,rhs);
if (curcost > bestcost) {
lhsbest = lhs;
nodeshow(lhsbest,"LHSGUD");
rhsbest = rhs;
nodeshow(rhsbest,"RHSGUD");
bestcost = curcost;
}
}
}
} while (0);
nodeshow(lhsbest,"LHSBEST");
nodeshow(rhsbest,"RHSBEST");
soldepth = bestcost;
}
void
dograph(void)
{
#ifdef GRAPH
int idx;
node_t *cur;
node_t *par;
char *bp;
char buf[100];
xfgrf = fopen("grf","w");
fprintf(xfgrf,"digraph {\n");
for (idx = 0; idx < Acnt; ++idx) {
cur = &nodelist[idx];
bp = buf;
bp += sprintf(bp,"label=\"N%d D%d\"",nodenum(cur),cur->depth);
if (cur == rhsbest)
bp += sprintf(bp," color=Green");
if (cur == lhsbest)
bp += sprintf(bp," color=Red");
fprintf(xfgrf,"\tN%d [%s]\n",nodenum(cur),buf);
par = cur->parent;
if (par != NULL)
fprintf(xfgrf,"\tN%d -> N%d\n",nodenum(par),nodenum(cur));
}
fprintf(xfgrf,"}\n");
fclose(xfgrf);
#endif
}
int
solve(int *A,int argcnt)
{
int idx;
int parval;
node_t *par;
if (root != NULL) {
memset(nodelist,0,sizeof(nodelist));
root = NULL;
}
// find the root node
// FIXME/CAE -- probably always the first
Acnt = argcnt;
for (idx = 0; idx < Acnt; ++idx) {
int parval = A[idx];
if (parval == -1) {
dbgprt("solve: ROOT idx=%d\n",idx);
root = newnode(idx,NULL);
break;
}
}
// build all child nodes:
for (idx = 0; idx < Acnt; ++idx) {
parval = A[idx];
if (parval == -1)
continue;
dbgprt("solve: NODE idx=%d parval=%d\n",idx,parval);
// find parent
par = fastfind(parval);
// create node
node_t *cur = newnode(idx,par);
// attach child to parent
addchild(par,cur);
}
// traverse all nodes in the tree to find max distance ...
search2();
dograph();
return soldepth;
}

priority queue utilizing a heap working except for freeC

I have my priority queue working and printing as I expected it to, but the free is invalid and I'm not sure why, i'm following all the protocols for the heap that I have learned so far, but my program will not finish.
#include <stdlib.h>
#include "priority_queue.h"
struct item{
int priority;
int value;
};
typedef struct item Item;
struct priority_queue{
int size;
int capacity;
int front;
Item* data;
};
typedef struct priority_queue Priority_queue;
void priority_queue_fix_down(PRIORITY_QUEUE hQueue, int index, int size);
PRIORITY_QUEUE priority_queue_init_default(void){
Priority_queue* pQueue_ptr;
pQueue_ptr = (Priority_queue*)malloc(sizeof(Priority_queue));
if(pQueue_ptr != NULL){
pQueue_ptr->size = 0;
pQueue_ptr->capacity = 1;
pQueue_ptr->data = (Item*)malloc(sizeof(Item)*pQueue_ptr->capacity);
if (pQueue_ptr->data == NULL){
free(pQueue_ptr);
pQueue_ptr = NULL;
}
}
return pQueue_ptr;
}
Status priority_queue_insert(PRIORITY_QUEUE hQueue, int priority_level, int data_item)
{
Priority_queue* pQueue_ptr = (Priority_queue*)hQueue;
Item* temp, temp2;
//temp = (Item*)malloc(sizeof());
int i;
if (pQueue_ptr->size >= pQueue_ptr->capacity)
{
//not enough space
temp = (Item*)malloc(sizeof(Item) * 2 * pQueue_ptr->capacity);
if (temp == NULL)
{
return FAILURE;
}
for (i = 0; i < pQueue_ptr->size; i++)
{
temp[i] = pQueue_ptr->data[i];
}
pQueue_ptr->front = 0;
pQueue_ptr->capacity *= 2;
free(pQueue_ptr->data);
pQueue_ptr->data = temp;
}
i = pQueue_ptr->size;
(pQueue_ptr->data[i]).priority = priority_level;
(pQueue_ptr->data[i]).value = data_item;
int index_of_parent;
index_of_parent = (i - 1) / 2;
while (i >= 1 && ((pQueue_ptr->data[i]).priority > (pQueue_ptr->data[index_of_parent]).priority))
{
temp2 = pQueue_ptr->data[index_of_parent];
pQueue_ptr->data[index_of_parent] = pQueue_ptr->data[i];
pQueue_ptr->data[i] = temp2;
i = index_of_parent;
index_of_parent = (i - 1) / 2;
}
pQueue_ptr->size++;
// pQueue_ptr->front = 0;
// pQueue_ptr->back = pQueue_ptr->size-1;
return SUCCESS;
}
void print_heap(PRIORITY_QUEUE hQueue){
Priority_queue* pQueue_ptr = (Priority_queue*) hQueue;
for(int x = 0; x<pQueue_ptr->size;x++){
printf("%d\n", pQueue_ptr->data[x].priority);
}
}
Status priority_queue_service(PRIORITY_QUEUE hQueue){
//set variables
Priority_queue* pQueue_ptr = (Priority_queue*) hQueue;
Item temp;
int size, index, index_left_child, index_right_child;
if(pQueue_ptr->size == 0){
return FAILURE;
}
index = 0;
temp = pQueue_ptr->data[0];
pQueue_ptr->data[0] = pQueue_ptr->data[pQueue_ptr->size-1];
pQueue_ptr->data[size-1] = temp;
pQueue_ptr->size--;
priority_queue_fix_down(pQueue_ptr, pQueue_ptr->front, pQueue_ptr->size);
return SUCCESS;
}
int priority_queue_front(PRIORITY_QUEUE hQueue, Status* status)
{
Priority_queue* pPriority_queue = (Priority_queue*)hQueue;
if (priority_queue_is_empty(pPriority_queue))
{
if (status != NULL)
{
*status = FAILURE;
}
return 0;
}
if (status != NULL)
{
*status = SUCCESS;
}
return (pPriority_queue->data[pPriority_queue->front]).value;
}
Boolean priority_queue_is_empty(PRIORITY_QUEUE hQueue){
Priority_queue* pQueue_ptr = (Priority_queue*) hQueue;
if (pQueue_ptr->size <= 0)
return TRUE;
else
return FALSE;
}
This is where I get the error when debugging, on free(pPriority_queue->data); It doesn't even reach the line below. I tried taking someone elses "service" function and it worked, but they implemented "fix down" in their service function, while I'm trying to do it outside in a separate function.
void priority_queue_destroy(PRIORITY_QUEUE* phQueue){
Priority_queue* pPriority_queue = (Priority_queue*)*phQueue;
free(pPriority_queue->data);
free(*phQueue);
// *phQueue = NULL;
return;
}
void priority_queue_fix_down(PRIORITY_QUEUE hQueue, int index, int size){
Priority_queue* pQueue_ptr = (Priority_queue*) hQueue;
Item* temp;
temp = (Item*)malloc(sizeof(Item));
if (temp == NULL)
return NULL;
//int front = priority_queue_front(pQueue_ptr, NULL);
int index_left_child = 2* index + 1;
int index_right_child = 2* index + 2;
// print_heap(pQueue_ptr);
// printf("\nsize: %d\nindex: %d\n", size, index);
// // printf("Front: %d\n", pQueue_ptr->data[0]);
// if(pQueue_ptr->data[index_left_child].priority > (pQueue_ptr->data[index]).priority){
// printf("Left child index %d\nRight child index: %d\nLeft child has highest priority of: %d\n",index_left_child, index_right_child, pQueue_ptr->data[index_left_child].priority);
// }
// else
// printf("Right child index: %d\nLeft child index %d\nRight child has highest priority of: %d\n",index_right_child, index_left_child, pQueue_ptr->data[index_right_child].priority);
if (index_left_child < size){
if (index_right_child < size && pQueue_ptr->data[index_right_child].priority > (pQueue_ptr->data[index_left_child]).priority){
if(pQueue_ptr->data[index_right_child].priority > (pQueue_ptr->data[index]).priority){
*temp = pQueue_ptr->data[index];
pQueue_ptr->data[index] = pQueue_ptr->data[index_right_child] ;
pQueue_ptr->data[index_right_child] = *temp;
priority_queue_fix_down(pQueue_ptr, index_right_child, size);
}
}
if(pQueue_ptr->data[index_left_child].priority > (pQueue_ptr->data[index]).priority){
*temp = pQueue_ptr->data[index];
pQueue_ptr->data[index] = pQueue_ptr->data[index_left_child];
pQueue_ptr->data[index_left_child] = *temp;
priority_queue_fix_down(pQueue_ptr, index_left_child, size);
}
}
}

XOR maximization using a trie

I am trying to solve this question-
Given an array A of unsigned 32-bit ints, choose two in-bounds indices i, j so as to maximize the value of A[i] ^ A[j], where ^ is the bitwise XOR (exclusive OR) operator.
Example Input:
4 2 0 13 49
Output:
60
Explanation: 13 ^ 49 is 60
Here is my code
#include <stdio.h>
void insert(int n, int pos, struct node *t);
int find(struct node *p1, struct node *p2);
struct node *alloc();
struct node{
int value;
struct node *left;
struct node *right;
};
int main()
{
int t;
scanf("%d", &t);
while (t--)
{
int n;
scanf("%d", &n);
struct node root;
root.value = 0;
root.left = root.right = NULL;
while (n--)
{
int num;
scanf("%d", &num);
insert(num, 31 , &root);
}
int max = find(&root, &root);
printf("%d\n", max);
}
return 0;
}
void insert(int n, int pos, struct node *t)
{
if (pos >= 0)
{
struct node *m;
int bit = (1 << pos)&n;
if (bit)
{
if (t->right == NULL)
{
m=alloc();
m->value = 1;
m->left = NULL;
m->right = NULL;
t->right = m;
}
if (pos == 0)
{
m=alloc();
m->value = n;
m->left = NULL;
m->right = NULL;
t->left = m;
}
insert(n, pos - 1, t->right);
}
else
{
if (t->left == NULL)
{
m = alloc();
m->value = 0;
m->left = NULL;
m->right = NULL;
t->left = m;
}
if (pos == 0)
{
m=alloc();
m->value = n;
m->left = NULL;
m->right = NULL;
t->left = m;
}
insert(n, pos - 1, t->left);
}
}
}
int find(struct node *p1, struct node *p2)
{
if ((p1->left != NULL) ||(p1->right != NULL))
{
int n01 = 0;
int n10 = 0;
if (p1->left != NULL && p2->right != NULL)
{
n01 = find(p1->left, p2->right);
}
if ((p1->right != NULL) && (p2->left != NULL))
{
n10 = find(p2->left, p1->right);
}
else
{
if (p1->left!=NULL && p2->left!=NULL)
n01 = find(p1->left, p2->left);
else
n10 = find(p1->right, p2->right);
}
return (n01 > n10 ? n01 : n10);
}
else
{
return p1->value^p2->value;
}
}
struct node *alloc()
{
return (struct node *) malloc(sizeof(struct node));
}
I am only getting a 0 as output.I know there are mistakes in my code.Please help me in finding the mistakes or if necessary the right solution.

Resources