Kruskal Algorithm (set division) - c

I have a problem to understand Kruskal Algorithm. Here is the code
#include <stdio.h>
#define MAX_VERTICLES 100
#define INF 1000
int parent[MAX_VERTICLES];
int num[MAX_VERTICLES];
void setInit(int n) {
int i;
for (i = 0; i < n; i++) {
parent[i] = -1;
num[i] = 1;
}
}
int setFind(int vertex) {
int p, s, i = -1;
for (i = vertex;(p = parent[i]) >= 0; i = p)
;
s = i;
for (i = vertex;(p = parent[i]) >= 0; i=p)
parent[i]=s;
return s;
}
void setUnion(int s1, int s2) {
if (num[s1] < num[s2]) {
parent[s1]=s2;
num[s2]+=num[s1];
}
else {
parent[s2] = s1;
num[s1] += num[s2];
}
}
typedef struct {
int key;
int u;
int v;
}element;
#define MAX_ELEMENT 100
typedef struct {
element heap[MAX_ELEMENT];
int heap_size;
}HeapType;
void init(HeapType *h) {
h->heap_size = 0;
}
void printHeap(HeapType *h) {
int i;
int level = 1;
printf("\n==========");
for (i = 1; i <= h->heap_size;i++) {
if (i = level) {
printf("\n");
level *= 2;
}
printf("\t%d", h->heap[i].key);
}
printf("\n==========");
}
void insertMinHeap(HeapType *h, element item) {
int i;
i = ++(h->heap_size);
while ((i != 1) && (item.key < h->heap[i / 2].key)){
h->heap[i] = h->heap[i / 2];
i /= 2;
}
h->heap[i] = item;
}
element deleteMinHeap(HeapType *h) {
int parent, child;
element item, temp;
item = h->heap[1];
temp = h->heap[(h->heap_size)--];
parent = 1;
child = 2;
while (child <= h->heap_size) {
if ((child < h->heap_size) && (h->heap[child].key > h->heap[child + 1].key))
child++;
if (temp.key <= h->heap[child].key) break;
h->heap[parent] = h->heap[child];
parent = child;
child *=2;
}
h->heap[parent] = temp;
return item;
}
void insertHeapEdge(HeapType *h, int u, int v, int weight) {
element e;
e.u = u;
e.v = v;
e.key = weight;
insertMinHeap(h, e);
}
void insertAllEdges(HeapType *h){
insertHeapEdge(h, 0, 1, 13);
insertHeapEdge(h, 1, 2, 36);
insertHeapEdge(h, 2, 3, 12);
insertHeapEdge(h, 2, 4, 28);
insertHeapEdge(h, 3, 5, 32);
insertHeapEdge(h, 4, 5, 14);
insertHeapEdge(h, 0, 5, 19);
insertHeapEdge(h, 0, 6, 23);
insertHeapEdge(h, 1, 6, 15);
insertHeapEdge(h, 5, 6, 20);
}
void kruskal(int n) {
int edge_accepted = 0;
HeapType h;
int uset, vset;
element e;
init(&h);
insertAllEdges(&h);
setInit(n);
while (edge_accepted<(n-1)){
e = deleteMinHeap(&h);
uset = setFind(e.u);
vset = setFind(e.v);
if (uset != vset) {
printf("(%d,%d) %d \n", e.u, e.v, e.key);
edge_accepted++;
setUnion(uset, vset);
}7
}
}
void main(){
kruskal(7);
getchar();
}
I cannot understand how setFind and setUnion functions work.(the other things are fine)
Somebody can explain the algorithms explicitly, please?

The algorithm by Kruskal (which aims at the generation of a minimum spanning tree) needs subroutines for finding the connected component for a given vertex and the possibility to merge connected components.
Apparently, parent[i] stores one single vertex which can be followed until no parent is possible; the node which is reached this way is the root of the connected component - this node can be found via setFind; num[i] represents the number of children defined by this relation. Thus, the connected components are represented implicity.
The function setUnion aims at merging the smaller connected component into the larger one by attaching the root of one connected component to the other component and updating the number of children.

Related

How to make dynamic int array

I have trouble getting my dynamic int array to work properly. I have tried some examples but still can not get it to work. I think I am doing a minor pointer problem but I cannot figure out what. I want to have a dynamic int array and then from another function add numbers to this array. I have gotten the counter to work.
I have tried putting * at different places and trying my way but I am at this point lacking the knowledge to actually know where the * should be. I know some basics about & and * but apparently not enough
static void counterFunction(int* pointerToArray[], int* count)
{
while (*count < 10) {
*(*pointerToArray + *count) = *count;
*count = *count + 1;
}
}
static int* writeSortedToArray(void)
{
// I need to store 1000 numbers at this point
int* dynamicArray = malloc(1000 * sizeof(int));
int counter = 0;
counterFunction(&dynamicArray, &counter);
return 0;
}
The counter works properly, the dynamic array does not work at all. It only store a 0 according to my debugger (xcode)
To add to the other answers, I'd suggest a more generic approach and encapsulation of the management logic:
#include <assert.h> // assert()
#include <stddef.h> // size_t
#include <stdbool.h> // bool, true, false
#include <stdlib.h> // malloc(), calloc(), free(), EXIT_FAILURE, EXIT_SUCCESS
#include <stdio.h> // fputs(), printf(), putchar()
typedef int value_type;
char const *conversion_specifier = "%d"
size_t const initial_capacity = 10
size_t growth_factor = 2
typedef struct dynarray_tag {
size_t size;
size_t capacity;
value_type *data;
} dynarray_t;
dynarray_t dynarray_create(void)
{
dynarray_t new_dynarray = { 0, 0, NULL };
return new_dynarray;
}
dynarray_t dynarray_create_reserve(size_t capacity)
{
dynarray_t new_dynarray = { 0, capacity, NULL };
new_dynarray.data = malloc(capacity * sizeof *new_dynarray.data);
return new_dynarray;
}
dynarray_t dynarray_create_size(size_t size)
{
dynarray_t new_dynarray = { size, size, NULL };
new_dynarray.data = calloc(size, sizeof *new_dynarray.data);
return new_dynarray;
}
bool dynarray_is_valid(dynarray_t const *dynarray)
{
if (!dynarray)
return false;
if (!dynarray->size && !dynarray->capacity && !dynarray->data)
return true;
if (dynarray->size > dynarray->capacity)
return false;
if (dynarray->capacity && dynarray->data)
return true;
return false;
}
size_t dynarray_get_size(dynarray_t const *dynarray)
{
assert(dynarray_is_valid(dynarray));
return dynarray->size;
}
size_t dynarray_get_capacity(dynarray_t const *dynarray)
{
assert(dynarray_is_valid(dynarray));
return dynarray->capacity;
}
value_type* dynarray_at(dynarray_t *dynarray, size_t position)
{
assert(dynarray_is_valid(dynarray) && dynarray->size && position < dynarray->size);
return &dynarray->data[position];
}
value_type* dynarray_front(dynarray_t *dynarray)
{
assert(dynarray_is_valid(dynarray));
return dynarray_at(dynarray, 0);
}
value_type* dynarray_back(dynarray_t *dynarray)
{
assert(dynarray_is_valid(dynarray));
return dynarray_at(dynarray, dynarray->size - 1);
}
bool dynarray_reserve(dynarray_t *dynarray, size_t new_capacity)
{
assert(dynarray_is_valid(dynarray));
if (new_capacity <= dynarray->capacity)
return true;
if (new_capacity < dynarray->size)
return false;
value_type *new_data = realloc(dynarray->data, new_capacity * sizeof *new_data);
if (!new_data)
return false;
dynarray->data = new_data;
dynarray->capacity = new_capacity;
return true;
}
bool dynarray_resize(dynarray_t *dynarray, size_t new_size)
{
assert(dynarray_is_valid(dynarray));
if (new_size <= dynarray->capacity)
return true;
value_type *new_data = realloc(dynarray->data, new_size * sizeof *new_data);
if (!new_data)
return false;
dynarray->data = new_data;
dynarray->size = new_size;
dynarray->capacity = new_size;
return true;
}
bool dynarray_insert(dynarray_t *dynarray, size_t position, value_type value)
{
assert(dynarray_is_valid(dynarray));
if (dynarray->size + 1 > dynarray->capacity) {
size_t new_capacity = dynarray->capacity ? dynarray->capacity * growth_factor : initial_capacity;
if (!dynarray_reserve(dynarray, new_capacity))
return false;
}
for (size_t i = dynarray->size; i > position; --i)
dynarray->data[i] = dynarray->data[i - 1];
dynarray->data[position] = value;
dynarray->size++;
return true;
}
bool dynarray_push_front(dynarray_t *dynarray, value_type value)
{
assert(dynarray_is_valid(dynarray));
return dynarray_insert(dynarray, 0, value);
}
bool dynarray_push_back(dynarray_t *dynarray, value_type value)
{
assert(dynarray_is_valid(dynarray));
return dynarray_insert(dynarray, dynarray->size, value);
}
bool dynarray_insert_sorted(dynarray_t *dynarray, value_type value)
{
assert(dynarray_is_valid(dynarray));
if (!dynarray_get_size(dynarray) || value < *dynarray_front(dynarray))
return dynarray_push_front(dynarray, value);
if (value > *dynarray_back(dynarray))
return dynarray_push_back(dynarray, value);
size_t insert_pos = 0;
for (; insert_pos < dynarray->size && value > dynarray->data[insert_pos]; ++insert_pos);
return dynarray_insert(dynarray, insert_pos, value);
}
void dynarray_print(dynarray_t const *dynarray)
{
assert(dynarray_is_valid(dynarray));
for (size_t i = 0; i < dynarray->size; ++i) {
printf(conversion_specifier, dynarray->data[i]);
if (i + 1 < dynarray->size)
printf(", ");
}
}
void dynarray_sort(dynarray_t *dynarray) // insertion sort
{
assert(dynarray_is_valid(dynarray));
for (size_t i = 1; i < dynarray->size; i++) {
value_type key = dynarray->data[i];
size_t k = i - 1;
for (; k >= 0 && dynarray->data[k] > key; --k)
dynarray->data[k + 1] = dynarray->data[k];
dynarray->data[k + 1] = key;
}
}
void dynarray_free(dynarray_t *dynarray)
{
assert(dynarray_is_valid(dynarray));
free(dynarray->data);
dynarray->size = dynarray->capacity = 0;
dynarray->data = NULL;
}
int main(void)
{
dynarray_t arr = dynarray_create();
if (!dynarray_is_valid(&arr)) {
fputs("Not enough memory. :(\n\n", stderr);
return EXIT_FAILURE;
}
int result = EXIT_FAILURE;
for (value_type i = 2; i < 15; i += 2) {
if (!dynarray_push_back(&arr, i))
goto error_exit;
}
dynarray_print(&arr);
putchar('\n');
for (value_type i = 1; i < 14; i += 2) {
if (i != 7) {
if (!dynarray_push_front(&arr, i))
goto error_exit;
}
}
dynarray_print(&arr);
putchar('\n');
dynarray_sort(&arr);
dynarray_print(&arr);
putchar('\n');
if (!dynarray_insert_sorted(&arr, 0))
goto error_exit;
dynarray_print(&arr);
putchar('\n');
if (!dynarray_insert_sorted(&arr, 15))
goto error_exit;
dynarray_print(&arr);
putchar('\n');
if (!dynarray_insert_sorted(&arr, 7))
goto error_exit;
dynarray_print(&arr);
putchar('\n');
result = EXIT_SUCCESS;
error_exit:
result == EXIT_FAILURE && fputs("Not enough memory. :(\n\n", stderr);
dynarray_free(&arr);
return result;
}
Output:
2, 4, 6, 8, 10, 12, 14
13, 11, 9, 5, 3, 1, 2, 4, 6, 8, 10, 12, 14
1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14
0, 1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14
0, 1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
Todo:
dynarray_insert_range()
dynarray_create_init() from iterator pair
dynarray_from_file()
dynarray_copy()
dynarray_begin()
dynarray_end()
...
You make some mistakes:
1) int* pointerToArray[] is a pointer to pointer(s). You should use int* pointerToArray.
2) *(*pointerToArray+*count)=*count; is dereferencing pointerToArray two times, you should use *(pointerToArray + *count) = *count;.
3) dynamicArrayis already a pointer, you should not use the &operator to get its address. Then counterFunction(&dynamicArray, &counter);should be converted in counterFunction(dynamicArray, &counter);.
Finally, your code should look like:
#include <stdio.h>
#include <stdlib.h>
static void counterFunction(int * pointerToArray, int * count){
while (*count < 10) {
*(pointerToArray + *count) = *count;
*count += 1;
}
}
static int * writeSortedToArray(){
//I need to store 1000 numbers at this point
int * dynamicArray = malloc(100 * sizeof(int));
int counter = 0;
counterFunction(dynamicArray, &counter);
// as suggested, finally release the array
free(dynamicArray);
return 0;
}
int main(){
writeSortedToArray();
return 0;
}
static void counterFunction(int array[], int* count)
{
ptrdiff_t i;
for (i = *count; i < 10; i++)
array[i] = i;
*count = i;
}
static int *writeSortedToArray(void)
{
//I need to store 1000 numbers at this point
int *dynamicArray;
int counter;
dynamicArray = calloc(sizeof(*dynamicArray) * 1000);
counter = 0;
counterFunction(dynamicArray, &counter);
/* counter == 10 */
return dynamicArray;
}
First of all, if a function always returns 0, it should be void (except main(), for its own reasons). Although you probably didn't want to return 0, and instead return the array.
The counter function doesn't need to know that the array is dynamic. It can just accept any array, and use it with array notation.
I changed to a for loop, because it's more natural.
You don't need to pass a pointer to the array, and in fact you shouldn't, because then the compiler could notice the difference between a pointer to an array and a pointer to a pointer, and complain.
I don't get the purpose of your code, but this code is just the corrected version of your code.
Remember to free(dynamicArray); at some point.
Wrong use of pointer here. Your Dynamicarray from the WriteSortedToArray is already an adress so you do not need to pass it as an adress.
This should work :
static void counterFunction(int* pointerToArray, int count){
while (count < 10)
{
pointerToArray[count] = count;
count++;
}
}
static int* writeSortedToArray(void){
int* dynamicArray = malloc(1000 * sizeof(int));
int counter = 0;
counterFunction(dynamicArray, counter);
return 0;
}
If you want to keep the value of your counter when exiting your counterFunction which is 10, do this instead :
static void counterFunction(int* pointerToArray, int *count){
while (*count < 10)
{
pointerToArray[*count] = *count;
*count++;
}
}
static int* writeSortedToArray(void){
int* dynamicArray = malloc(1000 * sizeof(int));
int counter = 0;
counterFunction(dynamicArray, &counter);
return 0;
}
You should always free your memory using the free function to avoid memory leak issues.
free(dynamicArray)

My BFS code is only showing the direct paths from source to destination, but not all possible paths

I want to print all possible paths from a given source and destination. But in my BFS code, it only shows the two paths, not the multiple path. For a directed graph where n = 4, edge = 6, given,
1-2
1-3
1-5
5-3
5-4
3-4
3-2
It should've printed 3 paths:
1-5-4
1-3-4
1-5-3-4
But it only shows this two paths
1-3-4
1-5-4
This is my sample code for finding the src to destination path
#include <stdio.h>
int queue1[100], state[100], parent[100];
int front = 0, rear = -1, maxSize = 100;
int count = 0;
int initial = 1, waiting = 2, visited = 3;
int n, e;
int adj[100][100];
bool isEmpty()
{
return count == 0;
}
bool isFull()
{
return count == maxSize;
}
void enqueue(int val)
{
if (!isFull())
{
if (rear == maxSize - 1)
{
rear = -1;
}
rear++;
queue1[rear] = val;
count++;
}
}
int dequeue()
{
int val = queue1[front];
front++;
if (front == maxSize)
{
front = 0;
}
count--;
return val;
}
void BFS_Traversal(int src, int des)
{
int done = 0;
enqueue(src);
state[src] = waiting;
parent[src] = -1;
printf("path ");
while (!isEmpty() && done == 0)
{
src = dequeue();
// printf("%d ",src);
state[src] = visited;
for (int i = 1; i <= n; i++)
{
if (adj[src][i] == 1 && state[i] == initial)
{
enqueue(i);
state[i] = waiting;
parent[i] = src;
if (i == des)
{
state[i] = initial;
int k = des;
do
{
printf("%d ", k);
k = parent[k];
} while (k != -1);
printf("\n");
}
}
}
}
}
int main()
{
int src, start, end, des;
scanf("%d%d", &n, &e);
for (int i = 1; i <= e; i++)
{
scanf("%d%d", &start, &end);
adj[start][end] = 1;
}
for (int i = 1; i <= n; i++)
{
state[i] = initial;
}
for (int k = 1; k <= n; k++)
{
parent[k] = -1;
}
scanf("%d%d", &src, &des);
BFS_Traversal(src, des);
}
As, you can see 1-5-3-4 path is not showing because they are already visited. How should I modify this code to print all possible paths?

How to modify the priority of a value in a max-heap?

I am writing a max-heap, which can change the priority/value. However, I have problems to understand what is wrong in my code.
I have followed this as reference: ref
This is my code (I have hide some functions since it not the focus here)
static void swap(MAX_HEAP *heap, int i, int j);
static void swim(MAX_HEAP *heap, int k);
static void sink(MAX_HEAP *heap, int k);
void swap(MAX_HEAP *heap, int i, int j) {
HEAP_ELEM s;
int k;
s = heap->binary_heap[i];
k = heap->keys[s.fu];
heap->binary_heap[i] = heap->binary_heap[j];
heap->keys[k] = heap->keys[heap->binary_heap[j].fu];
heap->keys[heap->binary_heap[j].fu] = k;
heap->binary_heap[j] = s;
}
void swim(MAX_HEAP *heap, int k) {
int m;
m = k / 2.0;
while (k > 1 && heap->binary_heap[m].priority < heap->binary_heap[k].priority) {
swap(heap, k, m);
k = m;
m = k / 2.0;
}
}
void sink(MAX_HEAP *heap, int k) {
int j;
while (2 * k <= heap->n) {
j = 2 * k;
if (j < heap->n && heap->binary_heap[j].priority < heap->binary_heap[j + 1].priority)
j++;
if (!(heap->binary_heap[k].priority < heap->binary_heap[j].priority))
break;
swap(heap, k, j);
k = j;
}
}
MAX_HEAP *create_maxheap(int capacity) {
int i;
MAX_HEAP *ret;
ret = (MAX_HEAP*) malloc(sizeof (MAX_HEAP));
ret->n = 0;
ret->binary_heap = (HEAP_ELEM*) malloc(sizeof (HEAP_ELEM) * (capacity + 1));
ret->binary_heap[0].fu = 0;
ret->binary_heap[0].priority = 0;
ret->max = capacity;
ret->keys = (int*) malloc(sizeof (int) * (capacity + 1));
for (i = 0; i <= capacity + 1; i++) {
ret->keys[i] = -1;
}
return ret;
}
HEAP_ELEM get_maxheap(MAX_HEAP *heap) {
HEAP_ELEM ret;
if (heap->n == 0) {
return;
}
ret = heap->binary_heap[1];
heap->keys[ret.fu] = -1;
swap(heap, 1, heap->n);
heap->n--;
sink(heap, 1);
return ret;
}
void insert_maxheap(MAX_HEAP *heap, int fu, int p) {
if (heap->n + 1 >= heap->max) {
int i;
heap->max *= 2;
heap->keys = (int*) realloc(heap->keys, sizeof (int) * (heap->max + 1));
heap->binary_heap = (HEAP_ELEM*) realloc(heap->binary_heap, sizeof (HEAP_ELEM) * (heap->max + 1));
for (i = heap->n+1; i < heap->max + 1; i++) {
heap->keys[i] = -1;
}
}
heap->n++;
heap->binary_heap[heap->n].fu = fu;
heap->binary_heap[heap->n].priority = p;
heap->keys[fu] = heap->n;
swim(heap, heap->n);
}
void modify_maxheap(MAX_HEAP *heap, int fu, int p) {
int i;
i = heap->keys[fu];
int old;
if (i == -1) {
insert_maxheap(heap, fu, p);
return;
}
old = heap->binary_heap[i].priority;
heap->binary_heap[i].fu = fu;
heap->binary_heap[i].priority = p;
heap->keys[fu] = i;
if (old < p) {
/* we need to bubble up*/
swim(heap, i);
} else if (old > p) {
//we need to bubble down
sink(heap, i);
}
}
When I have the following execution, it gives bad results... what is wrong here? For instance...
int main(int argc, char** argv) {
MAX_HEAP *heap, *heap2;
HEAP_ELEM he;
heap = create_maxheap(3);
modify_maxheap(heap, 1, 7);
modify_maxheap(heap, 2, 10);
modify_maxheap(heap, 3, 78);
modify_maxheap(heap, 4, 3);
modify_maxheap(heap, 5, 45);
printf("heap 1\n\n");
while(heap->n > 0) {
he = get_maxheap(heap);
printf("..fu: %d; value: %d\n", he.fu, he.priority);
}
printf("max size of heap1: %d\n", heap->max);
printf("\n\n");
heap2 = create_maxheap(10);
modify_maxheap(heap2, 3, 90);
modify_maxheap(heap2, 1, 7);
modify_maxheap(heap2, 2, 10);
modify_maxheap(heap2, 3, 9);
modify_maxheap(heap2, 3, 92);
modify_maxheap(heap2, 4, 3);
modify_maxheap(heap2, 3, 90);
modify_maxheap(heap2, 1, 99);
modify_maxheap(heap2, 5, 45);
modify_maxheap(heap2, 1, 89);
printf("heap 2\n\n");
while(heap2->n > 0) {
he = get_maxheap(heap2);
printf("fu: %d; value: %d\n", he.fu, he.priority);
}
return (EXIT_SUCCESS);
}
Note that I am using an array to store the indices of HEAP_ELEM in order to know the position of a HEAP_ELEM (which has as primary key the "fu" and change its priority. This is my output:
heap 1
..fu: 3; value: 78
..fu: 5; value: 45
..fu: 2; value: 10
..fu: 1; value: 7
..fu: 4; value: 3
max size of heap1: 6
heap 2
fu: 1; value: 99
fu: 3; value: 90
fu: 1; value: 89
fu: 5; value: 45
fu: 4; value: 3
I have changed my modify_maxheap function and it worked:
void modify_maxheap(MAX_HEAP *heap, int fu, int p) {
int i;
i = heap->keys[fu];
if (i == -1) {
insert_maxheap(heap, fu, p);
return;
}
heap->binary_heap[i].priority = p;
swim(heap, i);
sink(heap, i);
}
The reason is that we have to bubble-up and bubble-down in case of any modification to guarantee the heap condition. I hope it can serve as base for someone.

What mistake am I making in the function definition(C)

So I have this code thats supposed to do this
// REQUIRES: n >= 1. Elements a[0] ... a[n-1] exist.
// PROMISES
// If n == 1, returns 1.
// Returns 1 if all of a[0] <= a[1] ... a[n-2] <= a[n-1] are true.
// Otherwise, returns 0.
#include <assert.h>
#include "array-utils4F.h"
#define UNIT_TESTS 1
int is_sorted(const int *a, int n)
{
assert (n >= 1);
if (n == 1)
return 1;
int k ;
for (k = 1; k < n ; k++) {
if (a[k-1] > a[k])
return 0;
return 1;
}
}
int max_el(const int *a, int n)
{
assert(n >= 1);
int result = 0, i;
for (i = 0; i < n; i++)
if (a[i] > result)
result = a[i];
return result;
}
#ifdef UNIT_TESTS
#include <stdio.h>
#define COUNT(x) (sizeof(x)/sizeof(x[0]))
void test_is_sorted(const char *tag, const int *a, int n, int expected_rv);
void test_max_el(const char *tag, const int *a, int n, int expected_rv);
int main(void)
{
int test_01[] = { 10, 20, 30, 40, 50 };
int test_02[] = { 10, 10, 10, 10 };
int test_03[] = { 10, 20, 30, 40, 35 };
int test_04[] = { 10, 20, 30, 25, 40 };
int test_05[] = { 10, 5, 15, 25 };
test_is_sorted("test_01", test_01, COUNT(test_01), 1);
test_is_sorted("test_02", test_02, COUNT(test_02), 1);
test_is_sorted("test_03", test_03, COUNT(test_03), 0);
test_is_sorted("test_04", test_04, COUNT(test_04), 0);
test_is_sorted("test_05", test_05, COUNT(test_05), 0);
fputc('\n', stdout);
int test_06[] = { 100, 1, 2, 3 };
int test_07[] = { 1, 2, 100, 3 };
int test_08[] = { 1, 2, 3, 100 };
int test_09[] = { -1, -2, -3, -4 };
int test_10[] = { -8, -7, -6, -7, -8 };
test_max_el("test_06", test_06, COUNT(test_06), 100);
test_max_el("test_07", test_07, COUNT(test_07), 100);
test_max_el("test_08", test_08, COUNT(test_08), 100);
test_max_el("test_09", test_09, COUNT(test_09), -1);
test_max_el("test_10", test_10, COUNT(test_10), -6);
fputc('\n', stdout);
return 0;
}
void test_is_sorted(const char *tag, const int *a, int n, int expected_rv)
{
printf("Testing is_sorted for case with tag \"%s\":", tag);
if (expected_rv == is_sorted(a, n))
printf(" Pass.\n");
else
printf(" FAIL!\n");
}
void test_max_el(const char *tag, const int *a, int n, int expected_rv)
{
printf("Testing max_el for case with tag \"%s\":", tag);
if (expected_rv == max_el(a, n))
printf(" Pass.\n");
else
printf(" FAIL!\n");
}
#endif // #ifdef UNIT_TESTS
but when I test it it doesnt work, what can I change.
when i use this test int test_04[] = { 10, 20, 30, 35, 40 };
it returns 0. what am i doing wrong?I have added my entire code but the function still shows some defect, idk why it is doing this any help would be appreciated.
For now, when you did that if (a[0] <= a[k+ 1]), you just check if all value in the array are greater or equal than the first element of your array. You must check if an element is greater or equal than the previous element and if it's lesser or equal than the next element.
int is_sorted(const int *a, int n)
{
assert (n >= 1);
int k;
for (k = 1 ; k < n ; k++) {
if (a[k-1] > a[k])
return 0;
}
return 1;
}
Instead of use a variable result, you can directly return 0 when you know that the array isn't sorted.
Without added local variables
int is_sorted(const int *a, int n) {
assert (n >= 1);
while (--n)
if (a[n] < a[n-1])
return 0;
return 1;
}
Try this one
int is_sorted(const int *a, int n)
{
assert (n >= 1);
if (n == 1)
return 1;
int k, result=1;
for (k = 0; k < n - 1; k++) {
if (a[k] > a[k+ 1])
{
result = 0;
break;
}
}
return result;
}

Knights tour recursive

I'm trying to write knights tour recursive algorithm:
int mov[8][2] = {{2,1},{2,-1},{-2,1},{-2,-1},{1,2},{-1,2},{1,-2},{-1,-2}};
typedef struct element {
int x;
int y;
struct element *prev, *next;
} node;
//adding pool to list
void dEnd(node **root, int x,int y)
{
node *pos;
pos = *root;
while(pos->next!= NULL)
pos = pos->next;
pos->next = (node *)malloc(sizeof(node));
pos->next->x=x;
pos->next->y=y;
pos->next->prev=pos;
pos->next->next=NULL;
}
void uEnd(node **root,int x,int y)
{
node *pos;
pos = *root;
while(pos->x!= x && pos->y !=y)
{
pos = pos->next;
}
pos->prev->next=NULL;
free(pos);
}
void printAll(node **root)
{
node *pos = *root;
while(pos->next)
{
printf("%d %d\n", pos->x,pos->y);
pos = pos->next;
}
}
int contains(int x,int y)
{
return(((x >= 0 ) && (x <= 7)) && ((y >= 0) && (y <= 7)));
}
//find move
int searchForMove(int x, int y, int **tab, node **list, int *number)
{
int i ;
for(i = 0; i < 8; i++)
{
int nx, ny;
nx = x + mov[i][0];
ny = y + mov[i][1];
if(contains(nx, ny) && !tab[nx][ny])
{
dEnd(list, nx, ny);
tab[nx][ny] = 1;
*number++;
if(!searchForMove(nx,ny,tab,list,number))
{
uEnd(list,nx,ny);
tab[nx][ny]=0;
*number--;
}
}
}
if(i == 7 && *number <64)
return 0;
if(*number == 64)
return 1;
}
Could someone show me where I made a mistake? I've checked step by step what pools algorithm is adding to list. What is big suprise algorithm after adding 4,3 pool and then 6,4 pool should call it self with 6,4 as actual position but I don't know why it's calling itself with 4,3 as actual position.
OP mostly had it. Aside from some minor code, it was the *number increment/decrement that was wrong in 2 places.
int searchForMove(int x, int y, int **tab, node **list, int *number) {
...
// *number++; // This increase the pointer to the next pointer.
(*number)++; // This dereferences number and increases it.
...
// *number--;
(*number)--; // CD
Working Example. "CD" implies my changes
// CD
#include <assert.h>
#include <inttypes.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
int mov[8][2] = { { 2, 1 }, { 2, -1 }, { -2, 1 }, { -2, -1 }, { 1, 2 },
{ -1, 2 }, { 1, -2 }, { -1, -2 } };
typedef struct element {
int x;
int y;
struct element *prev, *next;
} node;
//adding pool to list
void dEnd(node **root, int x, int y) {
node *pos;
pos = *root;
assert(pos); // CD
while (pos->next != NULL)
pos = pos->next;
pos->next = (node *) malloc(sizeof(node));
pos->next->x = x;
pos->next->y = y;
pos->next->prev = pos;
pos->next->next = NULL;
}
void uEnd(node **root, int x, int y) {
node *pos;
pos = *root;
while (pos->x != x && pos->y != y) {
pos = pos->next;
}
pos->prev->next = NULL;
free(pos);
}
void printAll(node **root) {
node *pos = *root;
unsigned i = 0; // CD
uint64_t mask = 0; // CD
while (pos->next) {
// printf("%d %d\n", pos->x, pos->y);
printf("%2u %d %d\n", i++, pos->x, pos->y); // CD prepend visit index.
mask |= 1llu << (pos->x + 8*pos->y); // CD accumulate visited squares
pos = pos->next;
}
printf("Mask %016" PRIX64 "\n", mask); // CD Show all locations visited
}
int contains(int x, int y) {
return (((x >= 0) && (x <= 7)) && ((y >= 0) && (y <= 7)));
}
//find move
int searchForMove(int x, int y, int **tab, node **list, int *number) {
int i;
for (i = 0; i < 8; i++) {
int nx, ny;
nx = x + mov[i][0];
ny = y + mov[i][1];
if (contains(nx, ny) && !tab[nx][ny]) {
dEnd(list, nx, ny);
tab[nx][ny] = 1;
// *number++;
(*number)++; // CD
if (!searchForMove(nx, ny, tab, list, number)) {
uEnd(list, nx, ny);
tab[nx][ny] = 0;
// *number--;
(*number)--; // CD
}
}
}
if (i == 7 && *number < 64)
return 0;
if (*number == 64)
return 1;
return 2; // CD added
}
// All added by CD
int main(int argc, char *argv[]) {
int tab0[8] = {0,0,0,0,0,0,0,0};
int tab1[8] = {0,0,0,0,0,0,0,0};
int tab2[8] = {0,0,0,0,0,0,0,0};
int tab3[8] = {0,0,0,0,0,0,0,0};
int tab4[8] = {0,0,0,0,0,0,0,0};
int tab5[8] = {0,0,0,0,0,0,0,0};
int tab6[8] = {0,0,0,0,0,0,0,0};
int tab7[8] = {0,0,0,0,0,0,0,0};
int *tab[8] = {tab0, tab1, tab2, tab3, tab4, tab5, tab6, tab7 };
node HeadNode = { 0, 0, NULL, NULL };
node *pHeadNode = &HeadNode;
int number = 0;
int result;
result = searchForMove(0, 0, tab, &pHeadNode, &number);
printAll(&pHeadNode);
return result;
}

Resources