A certain level of a binary tree to array - c

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.

Related

C Program bump into segmentation fault. (gdb) Cannot access memory at address

I am trying to write codes in C for dynamic array (vector), and it runs okay until I add another function pointer into the struct (line29: int (findEle)(vector, int) ), and initialize it (line 153: v->findEle = findEle) to point to the function implementation (line 125: int findEle(vector* v, int value)). The debugger starts returning segmentation fault every time I tried to run it. Please find the code below:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef int BOOL;
#define TRUE 1
#define FALSE 0
typedef struct Vector vector;
struct Vector
{
int currCapacity;
int currSize;
int *items;
// TODO: Try to add another int field, will cause seg fault
int (*size)(vector*);
int (*capacity)(vector*);
BOOL (*is_empty)(vector*);
void *(*at)(vector*, int);
void (*push)(vector*, int);
void (*insert)(vector*, int, int);
void (*resize)(vector*, size_t);
int (*pop)(vector*);
void (*removeValue)(vector*, int);
void (*delete_ele)(vector*, int);
int (*findEle)(vector*, int);
};
// Vector Functions
int size(vector *v)
{
return v->currSize;
}
int capacity(vector *v)
{
return v->currCapacity;
}
BOOL is_empty(vector *v)
{
if(v->currSize==0){ return TRUE; }
return FALSE;
}
void *at(vector *v, int index)
{
if(index >= v->currSize){return NULL;}
return (int*)(v->items+index);
}
void push(vector *v, int item)
{
if(v->currSize == v->currCapacity)
{
v->items = (int*)realloc(v->items, sizeof(int)* (v->currCapacity * 2));
v->currCapacity = v->currCapacity * 2;
}
*(v->items+v->currSize) = item;
v->currSize++;
}
void insert(vector* v, int index, int item)
{
printf("Inserting %d at index %d\n", item, index);
if(v->currSize == v->currCapacity)
{
v->items = (int*)realloc(v->items, sizeof(int)* (v->currCapacity * 2));
printf("v->items address: %p\n", v->items);
v->currCapacity = v->currCapacity * 2;
}
int* shift_ptr = v->items+index;
memmove(v->items+index+1, v->items+index, sizeof(int)*(v->currSize-index));
*(v->items+index) = item;
v->currSize++;
}
void resize(vector* v, size_t size)
{
printf("Resizing from %d to %d\n", v->currSize, size);
v->items = (int*)realloc(v->items, sizeof(int)* size);
}
int pop(vector* v)
{
int last = *(v->items + (v->currSize-1));
v->currSize--;
if(v->currSize*4 == v->currCapacity)
{
v->resize(v, v->currCapacity/2);
}
return last;
}
void delete_ele(vector* v, int index)
{
int *curr_ptr = v->items+index;
if(v->currSize*4 == v->currCapacity)
{
v->resize(v, v->currCapacity/2);
}
memmove(curr_ptr, curr_ptr+1, sizeof(int)*(v->currSize-(index+1)));
v->currSize--;
}
void removeValue(vector *v, int value)
{
for(int i=0; i<v->currSize; i++)
{
int ptr_value = *(v->items+i);
printf("%d->%d ", i, ptr_value);
if(ptr_value==value)
{
delete_ele(v, i);
--i;
}
}
printf("\n");
}
int findEle(vector* v, int value)
{
for(int i=0; i<v->currSize; i++)
{
if(*(v->items+i)==value)
{
return i;
}
}
return -1;
}
vector *initializeVector()
{
vector *v;
v->currSize = 0;
v->currCapacity = 2;
v->items = (int*)malloc(sizeof(int) * v->currCapacity);
v->size = size;
v->capacity = capacity;
v->is_empty = is_empty;
v->at = at;
v->push = push;
v->insert = insert;
v->pop = pop;
v->removeValue = removeValue;
v->delete_ele = delete_ele;
v->findEle = findEle;
return v;
}
int main()
{
vector *v = initializeVector();
v->push(v, 8);
v->push(v, 25);
v->push(v, 25);
v->push(v, 12);
printf("element 0 :%d\n", *(int*)v->at(v, 0));
printf("element 1 :%d\n", *(int*)v->at(v, 1));
printf("element 2 :%d\n", *(int*)v->at(v, 2));
printf("element 3 :%d\n", *(int*)v->at(v, 3));
v->insert(v, 1, 50);
printf("element 0 :%d\n", *(int*)v->at(v, 0));
printf("element 1 :%d\n", *(int*)v->at(v, 1));
printf("element 2 :%d\n", *(int*)v->at(v, 2));
printf("element 3 :%d\n", *(int*)v->at(v, 3));
printf("element 4 :%d\n", *(int*)v->at(v, 4));
//printf("%d\n", v->pop(v));
printf("%d\n", v->findEle(v, 25));
v->removeValue(v, 25);
for(int i=0; i<v->currSize; i++)
{
int ptr_value = *(v->items+i);
printf("%d->%d ", i, ptr_value);
}
free(v->items);
return 0;
}
I tried to debug using gdb, it returns the below message:
Program received signal SIGSEGV, Segmentation fault.
0x0040189a in initializeVector () at Vector.c:153
153 v->findEle = findEle;
When I tried to get the address of the stated function, it showed the message below:
(gdb) x v->findEle
Cannot access memory at address 0x620000
Can someone kindly advice if I have some issues on memory allocation? Or the issue might be due to some other causes? Thanks!
At least in these functions
void resize(vector* v, size_t size)
{
printf("Resizing from %d to %d\n", v->currSize, size);
v->items = (int*)realloc(v->items, sizeof(int)* size);
}
int pop(vector* v)
{
int last = *(v->items + (v->currSize-1));
v->currSize--;
if(v->currSize*4 == v->currCapacity)
{
v->resize(v, v->currCapacity/2);
}
return last;
}
void delete_ele(vector* v, int index)
{
int *curr_ptr = v->items+index;
if(v->currSize*4 == v->currCapacity)
{
v->resize(v, v->currCapacity/2);
}
memmove(curr_ptr, curr_ptr+1, sizeof(int)*(v->currSize-(index+1)));
v->currSize--;
}
you do not update data members currCapacity and currSize
And in this function
vector *initializeVector()
{
vector *v;
v->currSize = 0;
v->currCapacity = 2;
v->items = (int*)malloc(sizeof(int) * v->currCapacity);
v->size = size;
v->capacity = capacity;
v->is_empty = is_empty;
v->at = at;
v->push = push;
v->insert = insert;
v->pop = pop;
v->removeValue = removeValue;
v->delete_ele = delete_ele;
v->findEle = findEle;
return v;
}
there is used the uninitialized pointer v that has an indeterminate value that results in undefined behavior.
Also you need to check the value of the parameter index in each function where it is used.

having trouble with this c quick sort while using an array struct

The program doesn't crash, the build is successful, and it runs through the rest of main properly. The only problem is that the sort doesn't actually sort the array.
I left out the creation of the array and the rest of main simply because I've already tested them with another sort, and they work properly. However I'm supposed to use a higher level sort so I have to change things.
//struct for the array
typedef double darray_value_t;
typedef struct darray_t_tag {
darray_value_t *data;
size_t size;
size_t capacity;
} darray_t;
//top of main
quickSort(&dataset, 0, dataset.size - 1);
//rest of main
//functions used to for the quick sort
void quickSort(darray_t *dataset, int lowValue, int highValue) {
if (lowValue < highValue) {
int part = partition(dataset, lowValue, highValue);
quickSort(dataset, lowValue, part - 1);
quickSort(dataset, part + 1, highValue);
}
}
darray_value_t partition(darray_t *dataset, int lowValue, int highValue) {
int pivot = dataset->data[highValue];
int i = (lowValue - 1);
for (int j = lowValue; j < highValue; j++) {
if (dataset->data[j] <= pivot) {
i++;
swapValues(&dataset->data[i], &dataset->data[j]);
}
}
swapValues(&dataset->data[i + 1], &dataset->data[highValue]);
return (i + 1);
}
void swapValues(darray_value_t *a, darray_value_t *b) {
darray_value_t temp = *a;
*a = *b;
*b = temp;
}
There are multiple problems in your code:
the return value of partition should be int, not darray_value_t,
conversely, the type of pivot should be darray_value_t, not int.
Here is a modified version:
#include <stdio.h>
//struct for the array
typedef double darray_value_t;
typedef struct darray_t_tag {
darray_value_t *data;
size_t size;
size_t capacity;
} darray_t;
void swapValues(darray_value_t *a, darray_value_t *b) {
darray_value_t temp = *a;
*a = *b;
*b = temp;
}
int partition(darray_t *dataset, int lowValue, int highValue) {
darray_value_t pivot = dataset->data[highValue];
int i = lowValue;
for (int j = lowValue; j < highValue; j++) {
if (dataset->data[j] <= pivot) {
swapValues(&dataset->data[i++], &dataset->data[j]);
}
}
swapValues(&dataset->data[i], &dataset->data[highValue]);
return i;
}
//functions used to for the quick sort
void quickSort(darray_t *dataset, int lowValue, int highValue) {
if (lowValue < highValue) {
int part = partition(dataset, lowValue, highValue);
quickSort(dataset, lowValue, part - 1);
quickSort(dataset, part + 1, highValue);
}
}
int main() {
darray_value_t arr[] = { 2.0, 1.5, 4.5, -1 };
darray_t dataset = { arr, 4, 4 };
quickSort(&dataset, 0, dataset.size - 1);
for (size_t i = 0; i < dataset.size; i++) {
printf(" %g", dataset.data[i]);
}
printf("\n");
return 0;
}

how to stop the growing tree in C when BFS search element is equal to given input

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.

Trying heapsort by Cormen, but getting segmentation fault

I'm learning heap sort by Cormen.
When I'm trying to run heapsort on the array, there's a problem and the program crashes (segmentation fault). I tried to put some printf's in the heapsort function and printing the h->size and h->count values but they seem to changed in some way from 10 to 3 (!!!) without me touching them (try to print them before the loop in heap_sort and after)..
I really don't understand what is the problem. please help me.
using Eclipse on windows7.
main.c:
#include <stdio.h>
#include "heap.h"
void print_array2(int *a, int n)
{
int *end = a + n;
while (a < end)
printf("%d ", *a++);
printf("\n");
}
int main(void)
{
int a[] =
{ 4, 1, 3, 2, 16, 9, 10, 14, 8, 7 };
print_array2(a, 10);
heapsort(a, 10);
print_array2(a, 10);
return 0;
}
heap.c:
#include <stdlib.h>
#include <stdio.h>
#include "heap.h"
void heapify(heap *h, int i)
{
int largest, left = LEFT(i), right = RIGHT(i);
if (left < h->count && (*(h->a + left) > *(h->a + i)))
largest = left;
else
largest = i;
if (right < h->count && (*(h->a + right) > *(h->a + largest)))
largest = right;
if (largest != i)
{
swap(h->a + i, h->a + largest);
heapify(h, largest);
}
}
heap *build_heap(int *a, int size)
{
heap h = (heap
)
{ .size = size, .count = size, .a = a };
heap *ph = &h;
int i = size / 2;
while (i >= 0)
heapify(ph, i--);
return ph;
}
void heapsort(int *a, int size)
{
heap *h = build_heap(a, size);
int i;
for (i = h->size - 1; i >= 1; --i)
{
swap(h->a, h->a + i);
h->count--;
heapify(h, 0);
}
}
void print_heap(heap *h)
{
int *end = h->a + h->count, *arr = h->a;
while (arr < end)
printf("%d ", *arr++);
printf("\n");
}
void print_array(heap *h)
{
int *end = h->a + h->size, *arr = h->a;
while (arr < end)
printf("%d ", *arr++);
printf("\n");
}
static void swap(int *a, int *b)
{
int temp = *a;
*a = *b;
*b = temp;
}
heap.h:
#ifndef HEAP_H_
#define HEAP_H_
typedef struct
{
int size; //array size
int count; //heap size
int *a; //int array
} heap;
#define PARENT(x) ((x + 1) / 2)
#define LEFT(x) (2 * (x) + 1)
#define RIGHT(x) (2 * ( (x) + 1) )
void heapify(heap* h, int i);
heap *build_heap(int *a, int size);
void heapsort(int *a, int size);
void print_heap(heap *h);
void print_array(heap *h);
static void swap(int *a, int *b);
#endif /* HEAP_H_ */
#mafso is correct. I changed build_heap to return a copy of the heap instead of a pointer and it worked. Maybe not the best way but it works. Here is the code:
heap.h
#ifndef HEAP_H_
#define HEAP_H_
typedef struct
{
int size; //array size
int count; //heap size
int *a; //int array
} heap;
#define PARENT(x) ((x + 1) / 2)
#define LEFT(x) (2 * (x) + 1)
#define RIGHT(x) (2 * ( (x) + 1) )
void heapify(heap* h, int i);
heap build_heap(int *a, int size);
void heapsort(int *a, int size);
void print_heap(heap *h);
void print_array(heap *h);
static void swap(int *a, int *b);
#endif /* HEAP_H_ */
heap.c
#include <stdlib.h>
#include <stdio.h>
#include "heap.h"
void heapify(heap *h, int i)
{
int largest, left = LEFT(i), right = RIGHT(i);
if (left < h->count && (*(h->a + left) > *(h->a + i)))
largest = left;
else
largest = i;
if (right < h->count && (*(h->a + right) > *(h->a + largest)))
largest = right;
if (largest != i)
{
swap(h->a + i, h->a + largest);
heapify(h, largest);
}
}
heap build_heap(int *a, int size)
{
heap h;// = (heap) { .size = size, .count = size, .a = a };
h.size = size;
h.count = size;
h.a = a;
heap *ph = &h;
int i = size / 2;
while (i >= 0)
heapify(ph, i--);
return *ph;
}
void heapsort(int *a, int size)
{
heap h = build_heap(a, size);
int i;
for (i = h.size - 1; i >= 1; --i)
{
swap(h.a, h.a + i);
h.count--;
heapify(&h, 0);
}
}
void print_heap(heap *h)
{
int *end = h->a + h->count, *arr = h->a;
while (arr < end)
printf("%d ", *arr++);
printf("\n");
}
void print_array(heap *h)
{
int *end = h->a + h->size, *arr = h->a;
while (arr < end)
printf("%d ", *arr++);
printf("\n");
}
static void swap(int *a, int *b)
{
int temp = *a;
*a = *b;
*b = temp;
}
This was my output:
4 1 3 2 16 9 10 14 8 7
1 2 3 4 7 8 9 10 14 16

Trouble creating a descending heap sort in C

void heapSort(int list[], int last)
{
// Local Declarations
int sorted;
int holdData;
int walker;
// Statements
for (walker = 1; walker <= last; walker++)
reheapUp (list, walker);
// Min Heap created. Now to sort!
sorted = last;
while (sorted > 0)
{
holdData = list[0];
list[0] = list[sorted];
list[sorted] = holdData;
sorted--;
reheapDown (list, 0, sorted, moves, comparisons);
}
return;
}
void reheapUp (int heap[], int newNode)
{
// Local Declarations
int parent;
int hold;
// Create a min heap
// Statements
if (newNode)
{
parent = (newNode - 1) / 2;
if (heap[newNode] > heap[parent]) // Only change made from ascending order
{
hold = heap[parent];
heap[parent] = heap[newNode];
heap[newNode] = hold;
reheapUp (heap, parent);
}
}
return;
}
void reheapDown (int heap[], int root, int last)
{
// Local Declarations
int hold;
int leftKey;
int rightKey;
int largeChildKey;
int largeChildIndex;
// Statements
if ((root * 2 + 1) <= last)
{
// There is atleast one child
leftKey = heap[root * 2 + 1];
if ((root * 2 + 2) <= last) {
rightKey = heap[root * 2 + 2];
}
else
rightKey = -1;
// Determine which child is larger
if (leftKey > rightKey)
{
largeChildKey = leftKey;
largeChildIndex = root * 2 + 1;
}
else
{
largeChildKey = rightKey;
largeChildIndex = root * 2 + 2;
}
// Test if root > large subtree
if (heap[root] < heap[largeChildIndex])
{
// parent < child
hold = heap[root];
heap[root] = heap[largeChildIndex];
heap[largeChildIndex] = hold;
reheapDown(heap, largeChildIndex, last);
}
}
return;
}
I got ascending order to heap sort to function by creating a max heap. I read that to create a descending order heap sort I need to create a min heap which I did as shown by changing heap[newNode] < heap[parent] to heap[newNode] > heap[parent] as shown in the code. However, it is still out order. Therefore, I wanted to do what are the other steps? Do I need to alter reheapDown somehow as well?
You need to change all value comparisons you make like heap[root] < heap[largeChildIndex] you didn't mention you changed.
First of all you need to change every comparison operators accordingly, just take them all and think of the problem.
Secondly you only have to reheapUp to (last/2) to create the heap, because the key at (last/2+1) doesn't have any childs.
And I made some heap-sort in C before and I had way less lines of code, and only had one "heapify" function. You might want to look at your code and try to simplify things.
EDIT : if you want some inspiration here is what I did
void fixHeap(int position,int length)
{
int child = (2*position)+1;
int temp;
while (child<=length)
{
if (child<length && vector[child]<vector[child+1])
{
child++;
}
if (vector[position]<vector[child])
{
temp = vector[position];
vector[position] = vector[child];
vector[child] = temp;
position = child;
child = (2*position)+1;
}
else
{
return;
}
}
}
void heapSort(int vector[],int N)
{
int counter;
int temp;
for (counter=(N-1)/2; counter>=0; counter--)
{
fixHeap(counter,N-1);
}
for (counter=N-1; counter>0; counter--)
{
temp = vector[counter];
vector[counter] = vector[0];
vector[0] = temp;
fixHeap(0,counter-1);
}
}
Here is heap sort using min heap implementation. Have a look, if it helps!
#include "stdafx.h"
#define LEFT(i) (2 * (i))
#define RIGHT(i) (((2 * (i)) + 1))
#define PARENT(i) ((i) / 2))
void print_heap(int input[], int n)
{
int i;
printf("Printing heap: \n");
for (i = 0; i < n; i++)
printf("%d ", input[i]);
printf("\n");
}
void swap_nodes(int *a, int *b)
{
int tmp;
tmp = *a;
*a = *b;
*b = tmp;
}
void min_heapify(int input[], int i, int n)
{
int least;
int l = LEFT(i + 1) - 1; // Get 0 based array index
int r = RIGHT(i + 1) - 1; // Get 0 based array index
if (l < n && input[l] < input[i]) {
least = l;
} else {
least = i;
}
if (r < n && input[r] < input[least]) {
least = r;
}
if (least != i) {
swap_nodes(&input[i], &input[least]);
min_heapify(input, least, n);
}
}
void heapify(int input[], int n)
{
for (int i = n/2; i >= 0; i--)
min_heapify(input, i, n);
}
void heap_sort(int input[], int n)
{
heapify(input, n);
for (int i = n - 1; i >= 1; i--) {
swap_nodes(&input[0], &input[i]);
n = n - 1;
min_heapify(input, 0, n);
}
}
int _tmain(int argc, _TCHAR* argv[])
{
int input[] = {5, 3, 17, 10, 84, 19, 6, 22, 9, 1};
int n = sizeof(input) / sizeof(input[0]);
print_heap(input, n);
heap_sort(input, n);
print_heap(input, n);
return 0;
}

Resources