簡體   English   中英

我的 C 語言二進制堆程序有問題

[英]I am having a problem with my binary heap program in C

我的 C 程序有問題,由於某種原因,它沒有返回我正在尋找的正確結果。 當我運行它時,它會顯示兩次指令,然后即使我沒有輸入選擇也說無效選擇,當我做了一個選擇時,它不會輸出我想要的東西,即使我相信代碼是正確的。

這是問題: 問題

這是程序給出的輸出: 在此處輸入圖片說明 代碼如下:

#include <stdio.h>
#include <stdlib.h>

int arr[100005];
int n;

void max(int index){
    if (index>=n)return;
    int left=2*index+1;
    int right = 2*index + 2;
    int mx_ind=index;
    if (left < n && arr[left]>arr[mx_ind]){
        mx_ind=left;
    }
    if (right < n && arr[left]>arr[mx_ind]){
        mx_ind=right;
    }
    if (mx_ind !=index){
    int tmp=arr[mx_ind];
    arr[mx_ind]=arr[index];
    arr[index]=tmp;
    max(mx_ind);
    }
}

int insert(int num,int location){
int p;
while (location>0)
{
    p=(location-1)/2;
    if(num>=arr[p])
    {
        arr[location]=arr[p];
    }
    else break;
    location=p;
    }
    arr[location]=num;
    return 0;
}


void del(int index){
arr[index]=arr[n-1];
n=n-1;
max(index);
}

void buildmaxheap(){
for (int i=n/2-1;i>=0;i--){
    max(i);
}
}


void display(){
for (int i=0;i<n;i++){
        printf("%d",arr[i]);
        printf("\n");
}
}
int returnmax(){
return arr[0];
}
int extractmax(){
int mx=arr[0];
del(0);
return mx;
}

int main()
{
    printf("enter num of elements");
    scanf("%d",&n);
    printf("enter value of elements");
    for(int i=0;i<n;i++){
        scanf("%d",&arr[i]);
    }
    buildmaxheap();
    int num,index;
    char choice;

    while(1){
     printf("1. extract max\n");
     printf("2. insert new key\n");
     printf("3. change key at A[i]\n");
     printf("4. delete key at A[i] \n");
     printf("5. return max\n");
     printf("6. exit\n");
     printf("Enter your choice:");
     scanf("%c",&choice);
     switch(choice)
     {
     case '1':
         printf("Max value is : %d\n", extractmax);
         break;

     case '2':
         scanf("%d",&num);
         insert(num,n);
         n++;
         printf("Content of array is:");
         display();
         break;

     case '3':
        scanf("%d %d",&index,&num);
         arr[index]=num;
         if (arr[(index-1)/2]>num)max(index);
         else insert(num,index);
         printf("content of array is : ");
         display();
         break;

     case '4':
         scanf("%d",&index);
         del(index);
         printf("Content of array is : \n");
         display();
         break;

     case '5':
         printf("Max value is : %d\n", extractmax);
         break;

     case '6':
         exit(1);
         break;
         default:printf("invalid choice\n");
     }
    }

return 0;
}

任何幫助,將不勝感激。

幾個問題:

  • 出現“無效選擇”輸出是因為choice將空格(換行符)作為值。 為避免選擇空格,請通過在scanf格式字符串前加上空格來排除它: scanf(" %c", &choice)

  • max您在第二個if條件中有一個錯誤。 您應該使用right作為索引而不是left

  • 對於某些操作,要求數組不為空。 應檢查此項以避免出現問題。

  • 在情況 3 中,當index為零時,表達式arr[(index - 1) / 2]無效。

此外,當用戶選擇 6 時,我建議不要調用exit(1) ,而是將其設為while條件。

這是一個更正的版本:

#include <stdio.h>
#include <stdlib.h>

int arr[100005];
int n;

void max(int index) {
    if (index >= n) return;
    int left = 2 * index + 1;
    int right = left + 1; 
    int mx_ind = index;
    if (left < n && arr[left] > arr[mx_ind]) {
        mx_ind = left;
    }
    if (right < n && arr[right] > arr[mx_ind]) { // bug fix
        mx_ind = right;
    }
    if (mx_ind != index) {
        int tmp = arr[mx_ind];
        arr[mx_ind] = arr[index];
        arr[index] = tmp;
        max(mx_ind);
    }
}

int insert(int num, int location){
    int p;
    while (location > 0) {
        p = (location - 1) / 2;
        if (num >= arr[p]) {
            arr[location] = arr[p];
        }
        else break;
        location = p;
    }
    arr[location] = num;
    return 0;
}


void del(int index) {
    arr[index] = arr[n - 1];
    n--;
    max(index);
}

void buildmaxheap() {
    for (int i = n / 2 - 1; i >= 0; i--) {
        max(i);
    }
}


void display() {
    for (int i = 0; i < n; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");
}

int returnmax() {
    return arr[0];
}

int extractmax() {
    int mx = arr[0];
    del(0);
    return mx;
}

int main() {
    printf("enter num of elements: ");
    scanf("%d", &n);
    printf("enter value of elements: ");
    for(int i = 0; i < n; i++) {
        scanf("%d", &arr[i]);
    }
    buildmaxheap();
    int num,index;
    char choice = ' ';

    while (choice != '6') { // Nicer to add the condition here
        // Maybe always start each iteration with this:
        printf("Content of array is: ");
        display();

        printf("1. extract max\n");
        printf("2. insert new key\n");
        printf("3. change key at A[i]\n");
        printf("4. delete key at A[i] \n");
        printf("5. return max\n");
        printf("6. exit\n");
        printf("Enter your choice: ");
        scanf(" %c", &choice); // Skip white space

        switch (choice) {
        case '1':
            if (n == 0) { // Add this protection
                printf("The array is empty\n");
            } else {
                // Should call the function
                printf("Max value is: %d\n", extractmax());
            }
            break;

        case '2':
            scanf("%d", &num);
            insert(num, n);
            n++;
            break;

        case '3':
            // Help the user:
            printf("Enter index and new value: ");
            scanf("%d %d", &index, &num);
            // Add this protection:
            if (index >= n) {
                printf("The array does not have this index\n");
            } else {
                arr[index] = num;
                // Add case for when index is 0
                if (index == 0 || arr[(index - 1) / 2] > num) max(index);
                else insert(num, index);
            }
            break;

        case '4':
            // Help the user:
            printf("Enter index: ");
            scanf("%d", &index);
            // Add this protection:
            if (index >= n) {
                printf("The array does not have this index\n");
            } else {
                del(index);
            }
            break;

        case '5':
            if (n == 0) { // Add this protection
                printf("The array is empty\n");
            } else {
                // Call the function, and the right one:
                printf("Max value is : %d\n", returnmax());
            }
            break;

        case '6':
            break; // Just break and use while condition to quit (no exit())

        default:
            printf("invalid choice '%c'\n", choice);
        }
    }

    return 0;
}

函數maxinsert的名稱具有誤導性。 max沒有返回最大值,並且insert沒有使列表更長。 將這些函數分別命名為siftDownsiftUp或類似的名稱更為常見。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM