2017-05-06 82 views
1

這是我的代碼。我對c和指針很陌生,所以很可能是指針錯誤。算法檢查泛型類型的數組是否是MaxHeap

#include<stdio.h> 
#include <stdbool.h> 

typedef int (*comparatorPtr)(void*, void*); 
bool isMaxHeap(void **heap, int index, int length, comparatorPtr comparator); 

/** 
* comparator with pointers (the mistake could be here) 
*/ 
int comparator_integer(void* e1, void* e2) { 
    int i1 = *(int *) e1; 
    int i2 = *(int *) e2; 

    //print 2 elements of array/heap 
    printf("I1 heap: %d\n", i1); 
    printf("I2 heap: %d\n", i2); 
    printf("***************************\n"); 

    if (i1 == i2) return 0; 
    else if (i1 > i2) return 1; 
    else return -1; 
} 

/** 
* Function for check if the array is or isn't a maxHeap 
*/ 
bool isMaxHeap(void **heap, int index, int length, comparatorPtr comparator) { 
    if (index > length - 1) return true; 

    printf("I'm calling comparator 1 \n%d value index1\n",index); 
    if (length > index * 2 && comparator((heap + index), (heap + (index * 2))) < 0) return false; 

    printf("I'm calling comparator 2 \n%d value index2\n",index); 
    printf("Value lenght %d\n", length); 
    if (length > index * 2 + 1 && comparator((heap + index), (heap + ((index * 2) + 1))) < 0) return false; 

    printf("I'm calling comparator 3 \n"); 
    if (index == 0) return isMaxHeap(heap, 1, length, comparator) && isMaxHeap(heap, 2, length, comparator); 

    else return isMaxHeap(heap, index * 2, length, comparator) && isMaxHeap(heap, index * 2 + 1, length, comparator); 
} 

int main() { 
    int array[6] = {90, 15, 10, 7, 12, 2}; //maxHeap array 
    int length = sizeof(array)/ sizeof(array[0]); 
    int index = 0; 

    printf("element in position 1: %d\n",*(array + (index*2)+1)); 
    printf("length %d\n", length); 

    isMaxHeap((void **) &array, index, length, &comparator_integer) ? printf("Yes"): printf("No"); 
return 0; 
} 

陣列是一個MaxHeap,但我不知道爲什麼我的代碼返回 號(printf的在這裏只是爲了嘗試捕捉錯誤)

感謝

+2

'void **'用於指針數組,而不是數組元素。 – Barmar

+0

'isMaxHeap'需要知道數組每個元素的大小,然後將指針轉換爲'char *',並添加乘以大小的索引。 – Barmar

回答

1

你不應該將陣列投射到void **。如果你有一個指針數組,那將是適當的,但你只是有一個數組數組。

您需要將每個數組元素的大小傳遞給函數。該函數然後需要將數組指針強制轉換爲char *以訪問數組元素。它需要將大小乘以數組索引以獲得傳遞給比較函數的數組元素的偏移量(這是在爲類型化數組建立索引時會自動發生的情況,但是您必須在函數中模擬它,因爲它在通用數組)。

您還在爲子節點使用錯誤的索引。左邊的孩子在index * 2 + 1,右邊的孩子在index * 2 + 2

在最後進行遞歸調用時,不需要爲index == 0設置特殊情況。

調用isMaxHeap()時,不需要使用&array,因爲當用作函數參數時,數組自動衰減爲指針。

#include<stdio.h> 
#include <stdbool.h> 

typedef int (*comparatorPtr)(void*, void*); 
bool isMaxHeap(void *heap, int index, int length, size_t size, comparatorPtr comparator); 

/** 
* comparator with pointers (the mistake could be here) 
*/ 
int comparator_integer(void* e1, void* e2) { 
    int i1 = *(int *) e1; 
    int i2 = *(int *) e2; 

    //print 2 elements of array/heap 
    printf("I1 heap: %d\n", i1); 
    printf("I2 heap: %d\n", i2); 
    printf("***************************\n"); 

    if (i1 == i2) return 0; 
    else if (i1 > i2) return 1; 
    else return -1; 
} 

/** 
* Function for check if the array is or isn't a maxHeap 
*/ 
bool isMaxHeap(void *heap, int index, int length, size_t size, comparatorPtr comparator) { 
    char *heapbase = heap; 
    if (index >= length) { 
     return true; 
    } 

    printf("I'm calling comparator 1 \n%d value index1\n",index); 
    if (length > index * 2 + 1 && comparator(heapbase + index * size, heapbase + (index * 2 + 1) * size) < 0) { 
     return false; 
    } 

    printf("I'm calling comparator 2 \n%d value index2\n",index); 
    printf("Value lenght %d\n", length); 
    if (length > index * 2 + 2 && comparator(heapbase + index * size, heapbase + (index * 2 + 2) * size) < 0) { 
     return false; 
    } 

    printf("I'm calling comparator 3 \n"); 
    return isMaxHeap(heap, index * 2 + 1, length, size, comparator) && isMaxHeap(heap, index * 2 + 2, length, size, comparator); 
} 

int main() { 
    int array[6] = {90, 15, 10, 7, 12, 2}; //maxHeap array 
    int length = sizeof(array)/ sizeof(array[0]); 
    int index = 0; 

    printf("element in position 1: %d\n",*(array + (index*2)+1)); 
    printf("length %d\n", length); 

    isMaxHeap(array, index, length, sizeof array[0], comparator_integer) ? printf("Yes\n"): printf("No\n"); 
    return 0; 
} 
+0

這部分*(int *)e1 - 我不是很清楚。所以e1會作爲void的指針進入。它是一個mem地址。 (int *)e1會將其轉換爲內存地址的整數值。 *(int *)e1取消引用該內存地址。那是對的嗎? –

+0

此外,大小變量的目的是這樣的,數組可以是任何類型。它是否正確? –

+0

'(int *)e1'將void指針轉換爲指向'int'的指針。然後使用'*'取消引用它來獲得整數值。你對'size'變量的用途是正確的。 – Barmar

相關問題