I'm trying to create a extended binary tree in a main function with finite number of nodes.
The problem is that compliler keeps showing
error: incopatible types when assigning to type 'struct node' from type 'int'
This is my code:
#include <stdio.h>
#include <stdlib.h>
#define NULLitem (-1)
typedef struct node * link;
struct node {
int item;
link l;
link r;
}
link NEW (int item, link l, link r)
{
link x = malloc(sizeof * x);
x->item = item;
x->l = l;
x->r = r;
return x;
}
void Tprint(link p, int indent)
{
int i;
if (p!=NULL){
Tprint(p->r, indent+4);
for(i=0; i<indent; i++)
printf(" ");
printf("%d\n", p->item);
Tprint(p->l,indent+4);
}
}
int main(void)
{
link T, M, N, z, Root;
z = NEW(NULLitem,NULL,NULL);
Root->item = 6;
T = NEW(5, NULL, NULL);
Root->l = T;
M = NEW(7, NULL, NULL);
Root->r = M;
M->l= NEW(NULLitem, NULL, NULL);
M->r= NEW(9,z,z);
N = NEW(2,z,z);
T->l = N;
T->r = NEW(NULLitem,NULL, NULL);
Tprint(Root,3);
return 0;
}
The error is on line 12 (the compiler says it all), "Pointer from integer without cast" is a warning which will disappear if you correct the error on line 12 of your program.
You actually forgot the semicolon here at:
struct node { int item;
link l;
link r;
}
Write a semicolon after the braces, your program should be like:
#include <stdio.h>
#include <stdlib.h>
#define NULLitem (-1)
typedef struct node * link;
struct node { int item;
link l;
link r;
};
link NEW (int item, link l, link r){
link x = malloc(sizeof * x);
x->item = item;
x->l = l;
x->r = r;
return x;
}
void Tprint(link p, int indent){
int i;
if (p!=NULL){
Tprint(p->r, indent+4);
for(i=0; i<indent; i++)
printf(" ");
printf("%d\n", p->item);
Tprint(p->l,indent+4);
}
}
int main(void)
{
link T, M, N, z, Root;
z = NEW(NULLitem,NULL,NULL);
Root->item = 6;
T = NEW(5, NULL, NULL);
Root->l = T;
M = NEW(7, NULL, NULL);
Root->r = M;
M->l= NEW(NULLitem, NULL, NULL);
M->r= NEW(9,z,z);
N = NEW(2,z,z);
T->l = N;
T->r = NEW(NULLitem,NULL, NULL);
Tprint(Root,3);
return 0;
}
The output would be like:
-1
9
-1
7
-1 6
-1
5
-1
2
-1
Runs without any errors.
Related
I need to put inside an array, the values of a binary tree, but the thing is, I should only put inside the array the values that are at a certain depth. And it should output the number of elements inserted at the array.
I have made this:
int nivel2_(ABin a, int n, int v[], int level, int *i){
int t;
if(!a) return 0;
if(n == level){
v[(*i)++] = a->value;
return 1;
}else{
t = nivel2_(a->left, n, v, level+1, i) + nivel2_(a->right, n, v, level+1, i);
}
return t;
}
int nivel2(ABin a, int n, int v[]){
int k = 0;
int *i;
i = &k;
return nivel2_(a, n, v, 1, i);
}
As I will keep changing the index recursively and only when we reach the depth we want, I thought of using a pointer, this way, when one part of the recursive folding happens it will change the value to all the other folding processes. Makes sense?
Structures:
typedef struct slist
{
int value;
struct slist* next;
} *SList;
typedef struct arvbin* ABin;
typedef struct arvbin
{
int value;
ABin right;
ABin left;
} arvb;
DOES IT WORK?
Only when I want the elements of the first level of depth!
Calling like this:
nivel2(tree2, 1, v);
Complete code
#include <stdio.h>
#include <stdlib.h>
typedef struct slist
{
int value;
struct slist* next;
} *SList;
typedef struct arvbin* ABin;
typedef struct arvbin
{
int value;
ABin right;
ABin left;
} arvb;
int nivel2_(ABin a, int n, int v[], int level, int *i){
int t;
if(!a) return 0;
if(n == level){
v[(*i)++] = a->value;
return 1;
}else{
t = nivel2_(a->left, n, v, level+1, i) + nivel2_(a->right, n, v, level+1, i);
}
return t;
}
int nivel2(ABin a, int n, int v[]){
int k = 0;
int *i;
i = &k;
return nivel2_(a, n, v, 1, i);
}
void insertTree(ABin *tree, int val){
if((*tree)==NULL){
*tree = (ABin) malloc(sizeof(arvb));
(*tree)->value = val;
(*tree)->left = NULL;
(*tree)->right = NULL;
return;
}
else if(val > (*tree)->value)
{
insertTree(&((*tree)->right), val);
}
else if(val <= (*tree)->value)
{
insertTree(&((*tree)->left), val);
}
return;
}
int main(){
int v[10] = {0};
ABin tree2 = NULL;
insertTree(&tree2, 22);
insertTree(&tree2, 1);
insertTree(&tree2, 3);
nivel2(tree2, 1, v);
int i;
for(i=0; i<5; i++){
printf("%d\n", v[i]);
}
return 0;
}
The code looks mostly OK to me. Here's a mildly modified version, mainly with a tree printing function added, and some diagnostics, and an extended tree. My suspicion is that you expected your tree to have just 2 levels, but it actually had 3.
Code
#include <stdio.h>
#include <stdlib.h>
typedef struct slist
{
int value;
struct slist* next;
} *SList;
typedef struct arvbin* ABin;
typedef struct arvbin
{
int value;
ABin right;
ABin left;
} arvb;
static int nivel2_(ABin a, int n, int v[], int level, int *i)
{
int t = 0;
if (a)
{
if (n == level)
{
v[(*i)++] = a->value;
t = 1;
}
else
{
t += nivel2_(a->left, n, v, level + 1, i);
t += nivel2_(a->right, n, v, level + 1, i);
}
}
return t;
}
static int nivel2(ABin a, int n, int v[])
{
int k = 0;
int r = nivel2_(a, n, v, 1, &k);
printf("r = %d; k = %d\n", r, k);
return k;
}
static
void insertTree(ABin *tree, int val)
{
if ((*tree) == NULL)
{
*tree = (ABin) malloc(sizeof(arvb));
(*tree)->value = val;
(*tree)->left = NULL;
(*tree)->right = NULL;
return;
}
else if (val > (*tree)->value)
{
insertTree(&((*tree)->right), val);
}
else if (val <= (*tree)->value)
{
insertTree(&((*tree)->left), val);
}
}
static void tree_to_array(ABin tree, int level)
{
int v[10] = { 0 };
int n = nivel2(tree, level, v);
printf("Converted level %d to array:", level);
for (int i = 0; i < n; i++)
printf(" %d", v[i]);
putchar('\n');
}
static void print_tree(ABin tree, int level)
{
if (tree != 0)
{
printf("Level %d: %d\n", level, tree->value);
print_tree(tree->left, level + 1);
print_tree(tree->right, level + 1);
}
}
int main(void)
{
ABin tree2 = NULL;
insertTree(&tree2, 22);
insertTree(&tree2, 10);
insertTree(&tree2, 13);
insertTree(&tree2, 33);
insertTree(&tree2, 39);
insertTree(&tree2, 43);
insertTree(&tree2, 19);
print_tree(tree2, 1);
for (int level = 1; level < 5; level++)
tree_to_array(tree2, level);
return 0;
}
Sample output
Level 1: 22
Level 2: 10
Level 3: 13
Level 4: 19
Level 2: 33
Level 3: 39
Level 4: 43
r = 1; k = 1
Converted level 1 to array: 22
r = 2; k = 2
Converted level 2 to array: 10 33
r = 2; k = 2
Converted level 3 to array: 13 39
r = 2; k = 2
Converted level 4 to array: 19 43
That looks correct to me for the tree shape that's printed.
Assume the inputs are
a = [2,3,4,1]
b = [1,2,4,3]
The function DoThis takes the first input and gives the following output.
3,2,4,1,
2,4,3,1,
2,3,1,4,
1,3,4,2
The DoThis function is as follows:
int **DoThis(int n, int arr[n]){
int l = n;
int **b = malloc(l * sizeof(*b));//sizeof(*b) : sizeof(int *)
int i, j, k;
for (i = 0; i < l; i++) {
j = (i + 1) % l;
int *copy = malloc(l * sizeof(*copy));//sizeof(int)
for (k = 0; k < l; k++)
copy[k] = arr[k];
int t = copy[i];
copy[i] = copy[j];
copy[j] = t;
//printf("{%d, %d, %d, %d}\n", copy[0], copy[1], copy[2], copy[3]);
b[i] = copy;
}
return b;
}
This function will be then performed on all the output produced at first level and so on, until the input . So it will look like this.
Since we found [1,2,4,3], we stop the function and output as 2, as it is in level 2.
How can I do this??
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
typedef struct element {
int *array;
int size;
} Element;
bool Element_equal(Element *a, Element *b){
return a->size == b->size && memcmp(a->array, b->array, a->size * sizeof(*a->array))==0;
}
Element *E_copy(Element *e){
Element *el = malloc(sizeof(*el));
el->array = malloc(e->size * sizeof(*e->array));
memcpy(el->array, e->array, e->size * sizeof(*e->array));
el->size = e->size;
}
void E_print(Element *e){
int i;
for(i=0; i<e->size; i++)
printf("%d ", e->array[i]);
printf("\n");
}
void E_drop(Element *e){
free(e->array);
free(e);
}
typedef struct node {
Element *data;
int level;
struct node *next;
} Node;
void Node_drop(Node *node){
E_drop(node->data);
free(node);
}
typedef struct queque {
Node *top;
Node *tail;
} Queque;
Queque *Q_new(void){
return calloc(1, sizeof(Queque));
}
Node *Q_deq(Queque *q){
if(q->top){
Node *node = q->top;
q->top = q->top->next;
return node;
}
return NULL;
}
void Q_drop(Queque *q){
Node *node;
while(node = Q_deq(q))
Node_drop(node);
free(q);
}
void Q_enq(Queque *q, Element *element, int level){
Node *node = malloc(sizeof(*node));
node->data = element;
node->level = level;
node->next = NULL;
q->tail = q->top ? (q->tail->next = node) : (q->top = node);
}
Element **transpose(Element *e){
int l = e->size;
Element **b = malloc(l * sizeof(*b));
int i, j;
for (i = 0; i < l; i++) {
j = (i + 1) % l;
Element *copy = E_copy(e);
int t = copy->array[i];
copy->array[i] = copy->array[j];
copy->array[j] = t;
b[i] = copy;
}
return b;
}
int Cyc_Ken_Tau(Element *start, Element *goal){
Queque *queque = Q_new();
Q_enq(queque, E_copy(start), 0);//level 0
while(true){
Node *node = Q_deq(queque);
if(Element_equal(node->data, goal)){
int ret = node->level;
Node_drop(node);
Q_drop(queque);
return ret;
}
Element **new_list = transpose(node->data);
int i;
for(i=0; i < node->data->size; ++i){
Q_enq(queque, new_list[i], node->level + 1);
}
free(new_list);
Node_drop(node);
}
}
int main(){
int a[] = {2, 3, 4, 1};
int b[] = {1, 2, 4, 3};
int n = sizeof(a)/sizeof(*a);
Element start = { a, n };
Element goal = { b, n };
int level = Cyc_Ken_Tau(&start, &goal);
printf("%d\n", level);
return 0;
}
Use memcmp to compare your permutation to the desired one.
Also, be sure to match some frees to your mallocs when you're done with the data to avoid memory leaks.
I'm trying to come up with a rudimentary radix sort (I've never actually seen one, so I'm sorry if mine is awful), but I am getting an EXC_BAD_ACCESS error on the line link = *(link.pointer);. My C skills aren't great, so hopefully someone can teach me what I'm doing wrong.
I'm using XCode and ARC is enabled.
Here is the code:
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <time.h>
#define ARRAY_COUNT 10
#define MAX_VALUE 1000000
#define MODULO 10.0f
typedef enum
{
false,
true
} bool;
typedef struct linkedListStruct
{
int value;
struct linkedListStruct *pointer;
} LinkedList;
void radixSort(int *array);
bool arraySorted(int *array);
int * intArray(int minValue, int maxValue);
int main(int argc, const char * argv[])
{
int *sortingArray = intArray(0, MAX_VALUE);
radixSort(sortingArray);
printf("Array %s sorted", arraySorted(sortingArray) ? "" : "not");
return 0;
}
void radixSort(int *array)
{
int numberOfIterations = (int)ceilf(log(MAX_VALUE)/log(MODULO));
for(int n = 0; n < numberOfIterations; n++)
{
LinkedList *linkedListPointers[(int)MODULO] = {0};
int i = ARRAY_COUNT;
while(i--)
{
int location = (int)floor((array[i] % (int)powf(MODULO, n + 1))/powf(MODULO, n));
LinkedList link = { array[i], NULL };
link.pointer = linkedListPointers[location];
linkedListPointers[location] = &link;
}
int location = 0;
for(int pointerSelection = 0; pointerSelection < MODULO; pointerSelection++)
{
if(linkedListPointers[pointerSelection])
{
LinkedList link = { 0, linkedListPointers[pointerSelection] };
linkedListPointers[pointerSelection] = NULL;
while(link.pointer)
{
link = *(link.pointer);
array[location++] = link.value;
}
}
}
}
}
bool arraySorted(int *array)
{
int i = ARRAY_COUNT;
while(--i)if(array[i - 1] > array[i])break;
return !i;
}
int * intArray(int minValue, int maxValue)
{
int difference = maxValue - minValue;
int *array = (int *)malloc(sizeof(int) * ARRAY_COUNT);
int i;
for(i = 0; i < ARRAY_COUNT; i++)
{
array[i] = rand()%difference + minValue;
}
return array;
}
Also, if someone wants to suggest improvements to my sort, that would also be appreciated.
The problem came from how I was allocating the linked list. I changed
LinkedList link = { array[i], NULL };
link.pointer = linkedListPointers[location];
to
LinkedList *link = malloc(sizeof(LinkedList));
link->value = array[i];
link->pointer = linkedListPointers[location];
In the first example, the pointer to link remained the same through each loop iteration (I wasn't aware it would do that), so I needed to make the pointer point to a newly allocated memory chunk.
EDIT:
Changing that also had me change from
while(link.pointer)
{
link = *(link.pointer);
array[location++] = link.value;
}
to
while(linkPointer)
{
link = *linkPointer;
array[location++] = link.value;
linkPointer = link.pointer;
}
Goal:
Traverse the vertices memory block in the Heap struct.
Errors: I get expected unqualified-id before ‘(’ token when trying to access vertices. Also, ‘vertices’ was not declared in this scope.
Header:
typedef struct Heap *PriorityQueue_t;
typedef struct HeapItem *PriorityItem_t;
PriorityQueue_t Init(int max_capacity, int source_vertex);
Implementation:
#include "heap.h"
#include <stdlib.h>
#include <limits.h>
struct Heap
{
int size;
PriorityItem_t vertices;
};
struct HeapItem
{
int id;
int distance;
};
PriorityQueue_t Init(int max_capacity, int source_vertex)
{
PriorityQueue_t Q;
Q = (PriorityQueue_t)malloc(sizeof(PriorityQueue_t));
Q->vertices = (PriorityItem_t)malloc(sizeof(PriorityItem_t)*max_capacity);
Q->size = max_capacity;
int i;
for(i = 0; i < Q->size; i++)
{
Q->(vertices + i)->id = i; //Errors on this line.
Q->(vertices + i)->distance = INT_MAX;
}
Q->(vertices + source_vertex)->distance = 0;
return Q;
}
You've placed the parens in the wrong place. Try this:
(Q->vertices + i)->id = i; //Errors on this line.
(Q->vertices + i)->distance = INT_MAX;
}
(Q->vertices + source_vertex)->distance = 0;
Q->(vertices + i)->id = i; //Errors on this line.
Q->(vertices + i)->distance = INT_MAX;
Q->(vertices + source_vertex)->distance = 0;
You can't do that like that...
Q->vertices[i].id = i;
(Q->vertices + i)->distance = INT_MAX;
(*(Q->vertices + source_vertex)).distance = 0; // Not sensible, but legal
You can avoid a lot of parentheses by using plain indexing and removing the casts:
PriorityQueue_t Init(int max_capacity, int source_vertex)
{
PriorityQueue_t Q;
Q = malloc(sizeof *Q);
Q->vertices = malloc(max_capacity * sizeof *Q->vertices);
Q->size = max_capacity;
int i;
for(i = 0; i < Q->size; i++)
{
Q->vertices[i].id = i;
Q->vertices[i].distance = INT_MAX;
}
// maybe add next line:
// assert (source_vertex >=0 && source_vertex < Q->size);
Q->vertices[source_vertex].distance = 0;
return Q;
}
I'm attempting to complete an assignment on sparse matrices in C. I have a sparse matrix held as a list of values and coordinates and am converting it to Yale format.
I have run into a strange memory allocation issue that no one seems to have seen before. My code is:
yale* convertMatrix(matrix_list* input){
int matrix_elements = input->elements;
int matrix_rows = input->m;
yale* yale = (struct y*)calloc(1, sizeof(yale));
int* A = (int*)calloc(matrix_elements, sizeof(int));
int* IA = (int*)calloc(matrix_rows + 1, sizeof(int));
int* JA = (int*)calloc(matrix_elements, sizeof(int));
printf("%d elements\n",matrix_elements);
yale->A = A; // Value
yale->IA = IA; // Row (X)
yale->JA = JA; // Column (Y)
yale->elements = matrix_elements;
yale->m = matrix_rows;
yale->n = input->n;
list* tmp_list = input->first;
for(int i = 0, j = 0, tmp_y = 0; i < matrix_elements && tmp_list!=NULL; i++){
printf("Input Value: %d \n",tmp_list->point.value);
A[i] = tmp_list->point.value;
// Initialise the first row
if(i == 0) IA[0] = tmp_list->point.x;
else{
// Add a new row index
if(tmp_y != tmp_list->point.x){
j++;
IA[j] = i;
tmp_y = tmp_list->point.x;
}
}
JA[i] = tmp_list->point.y;
tmp_list = tmp_list->next;
}
for(int i = 0; i < matrix_elements; i++)
printf("%d,",yale->A[i]);
printf("\n");
for(int i = 0; i < matrix_rows + 1; i++)
printf("%d,",yale->IA[i]);
printf("\n");
for(int i = 0; i < matrix_elements; i++)
printf("%d,",yale->JA[i]);
return yale;
}
And here is the struct for yale:
typedef struct y{
int n;
int m;
int elements;
int *IA;
int *JA;
int *A;
} yale;
But the program segfaults at the first relevant printf on the first iteration of the loop.
printf("%d,",yale->A[i]);
I'm positive:
matrix_elements is an integer (9 in my test case)
matrix_rows is an integer
A / IA / JA are all filled with correct values (if you swap yale->A for A in the printf, it works fine).
Directly callocing the array to the struct pointers doesn't affect the result.
Mallocing, callocing, not typecasting, all no effect.
Thanks to Xcode and gdb I can also see that at the point of the segfault. The structure pointers do NOT seem to point to the arrays
I suggest you run your code under Valgrind. This should report the buffer overflow error. (A buffer overflow is where you write past the end of an array).
I also recommend you write some unit tests for your code. They can be very helpful detecting bugs. In particular, I suggest you write a test with a 3x3 input matrix with a value in every position. Check that the values you get out are what you expect.
To get it compiled, I need to prepend this to the snippet:
#include <stdlib.h>
#include <stdio.h>
typedef struct y{
int n;
int m;
int elements;
int *IA;
int *JA;
int *A;
} yale;
typedef struct list {
struct list *next;
struct point { int x,y,value; } point;
} list;
typedef struct matrix_list {
int elements;
int m;
int n;
struct list *first;
int *point;
} matrix_list;
UPDATE: I transformed the program into something more readable (IMHO). I don't have the faintest idea what the IA and JA are supposed to do, but the below fragment should be equivalent to the OP.
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
struct y {
unsigned int n;
unsigned int m;
unsigned int elements;
unsigned int *IA;
unsigned int *JA;
int *A;
} ;
struct list {
struct list *next;
struct point { unsigned int x,y; int value; } point;
} ;
struct matrix_list {
unsigned int elements;
unsigned int m;
unsigned int n;
struct list *first;
} ;
struct y *convertMatrix(struct matrix_list* input)
{
unsigned int matrix_elements = input->elements;
unsigned int matrix_rows = input->m;
unsigned int ii,jj,tmp_y;
struct y *yale ;
struct list *tmp_list ;
yale = calloc(1, sizeof *yale);
assert (yale != NULL);
printf("%u elements\n",matrix_elements);
yale->A = calloc(matrix_elements, sizeof *yale->A);
assert (yale->A != NULL);
yale->IA = calloc(matrix_rows + 1, sizeof *yale->IA);
assert (yale->IA != NULL);
yale->JA = calloc(matrix_elements, sizeof *yale->JA);
assert (yale->JA != NULL);
yale->elements = matrix_elements;
yale->m = matrix_rows;
yale->n = input->n;
// Initialise the first row, set start condition
// FIXME: this ignores the empty list or size=0 cases
yale->IA[0] = tmp_y = input->first->point.x;
ii = jj = 0;
for(tmp_list = input->first ;tmp_list; tmp_list = tmp_list->next) {
printf("Input Value: %d \n",tmp_list->point.value);
yale->A[ii] = tmp_list->point.value;
// Add a new row index
if(tmp_y != tmp_list->point.x){
jj++;
yale->IA[jj] = ii;
tmp_y = tmp_list->point.x;
}
yale->JA[ii] = tmp_list->point.y;
if (++ii >= matrix_elements ) break;
}
for(int i = 0; i < matrix_elements; i++)
printf("%d,",yale->A[i]);
printf("\n");
for(int i = 0; i < matrix_rows + 1; i++)
printf("%u,",yale->IA[i]);
printf("\n");
for(int i = 0; i < matrix_elements; i++)
printf("%u,",yale->JA[i]);
return yale;
}
Note: I moved the (ii == 0) {} condition out of the loop, and replaced the one-letter indices by there two-letter equivalents. Also: all the indices are unsigned (as they should be)