在 C 语言中对指向结构的指针数组进行排序 - 合并排序未按预期工作

Sorting an Array of Pointers to Structs in C - Merge Sort Not Working As Expected

提问人:Albert Jojo 提问时间:11/13/2023 最后编辑:Albert Jojo 更新时间:11/13/2023 访问量:32

问:

我正在开发一个 C 程序,该程序涉及使用合并排序对指向结构的指针数组进行排序。该程序管理着客户的二叉搜索树,我想根据客户的忠诚度对客户进行排序。

问题在于排序过程没有产生预期的结果。使用 inorder 函数打印客户是正确的,但排序的数组似乎不正确。

我已经提供了代码的相关部分。

int main(void){
    tree_node *my_root = NULL;
    int num_operations;
   
    printf("Enter # of operations: "); // For testing purposes, remove after completion(Remove when submitting)
    scanf("%d", &num_operations);

    for(int i=0; i< num_operations; i++){
        char operation[20];
        char name[MAXLEN + 1];
        int points;
        tree_node *recent_customer = NULL;

        scanf("%s", operation);

        if(strcmp(operation, "add") == 0){
            scanf("%s %d", name, &points);
            // Checking if the customer already exists
            searchResult *result = search(my_root, name);
            if(result!=NULL && result->tPtr!= NULL){
                result->tPtr->cPtr->points += points; // If customer exists then you update the points
                printf("%s %d\n", result->tPtr->cPtr->name, result->tPtr->cPtr->points); //Printing customer if they exist
                free(result); // Free searchResult after usage
            }else{
                customer *new_customer = (customer *)malloc(sizeof(customer));
                if(new_customer == NULL){
                    fprintf(stderr,"Memory Allocation Failed\n");
                    exit(1);
                }
                recent_customer = (tree_node*)malloc(sizeof(tree_node));
                 
                //Populating customer 
                strncpy(new_customer->name, name, MAXLEN);
                new_customer->points = points;

                //Adding customer to tree
                tree_node *temp_node = create_node(new_customer);
                my_root = insert(my_root, temp_node);

                recent_customer ->cPtr = new_customer;
                
                //Reallocate memory for new customers
                customers = (customer **)realloc(customers, (num_customers + 1)  * sizeof(customer*));
                if(customers == NULL){
                    fprintf(stderr, "Memory Allocation failed");
                    exit(1);
                }
                //Store the customer pointer in array
                customers[num_customers] = new_customer;
                num_customers++;

                printf("%s %d\n", recent_customer->cPtr->name, recent_customer->cPtr->points);
            }
        }else if(strcmp(operation, "sub") == 0){
            char customer_name[MAXLEN + 1];
            int subtractPoints;

            //Taking input
            scanf("%s %d" ,customer_name, &subtractPoints);

            //Searching for customer
            searchResult *result = search(my_root, customer_name);

            if(result!=NULL && result->tPtr !=NULL){
                //Subtract Points
                if(subtractPoints >= result->tPtr->cPtr->points){
                    result->tPtr->cPtr->points = 0;
                    printf("%s %d\n", result->tPtr->cPtr->name,result->tPtr->cPtr->points);
                }else{
                    result->tPtr->cPtr->points -= subtractPoints;
                    //Update points in the customer array
                    for(int i=0; i<num_customers; i++){
                        if(customers[i]==result->tPtr->cPtr){
                            customers[i]->points = result->tPtr->cPtr->points;
                            break;
                        }
                    }
                    printf("%s %d\n", result->tPtr->cPtr->name, result->tPtr->cPtr->points);
                }
                free(result);
            }else{
                printf("%s not found\n", customer_name);
            }       
        }else if(strcmp(operation, "search") == 0){
            scanf("%s", name);

            printf("Searching for customer:\n"); //Debugging purposes
            searchResult *result = search(my_root, name);

            if(result!=NULL && result->tPtr!=NULL){
                printf("%s %d %d\n", result->tPtr->cPtr->name, result->points, result->depth); //Prints out name, loyalty points and depth
                free(result);
            }else{
                printf("%s not found\n", name);
                free(result); // Free searchResult after usage
            }

        }else if(strcmp(operation, "del") == 0){
            char name[MAXLEN + 1];
            scanf("%s", name);

            // Searching for customer
            searchResult *result = search(my_root, name);

            if (result != NULL && result->tPtr != NULL) {
                // Customer found, proceed with deletion
                my_root = delete(my_root, name);
                printf("%s deleted\n", name);

                // Remove the customer pointer from the array
                for (int i = 0; i < num_customers; i++) {
                    if (customers[i] == result->tPtr->cPtr) {
                        // Shift remaining elements to fill the gap
                        for (int j = i; j < num_customers - 1; j++) {
                            customers[j] = customers[j + 1];
                        }
                        num_customers--;
                        break;
                    }
                }
                free(result);
            } else {
                // Customer not found
                printf("%s not found\n", name);
                free(result);
            }
        }else if(strcmp(operation, "count_smaller") == 0){
            char name[MAXLEN + 1];
            scanf("%s", name);
            int count = count_smaller(my_root, name);
            printf("%d\n", count);
        }
    }
    printf("Inorder traversal of the final tree:\n");
    inorder(my_root);
    
    printf("Sorted Array based on points\n");
    
    mergeSort(customers, 0 , (num_customers -1 ));
    
    for(int i = 0; i<num_customers;i++){
        printf("Name: %s  Points: %d\n", customers[i]->name, customers[i]->points);
    }
    
    for(int i =0; i<num_customers; i++){
        free(customers[i]);
    }
    free(customers);
    
    
}
int compareByPoints(const customer *customer1, const customer *customer2) {
    return customer2->points - customer1->points;
}
//Merge Sort
void mergeSort(customer **arr, int left, int right){
    if(left < right){
        int mid = left + (right - left)/2;
        mergeSort(arr, left, mid);
        mergeSort(arr, mid + 1, right);
        merge(arr,left, mid, right);
    }
}
//Merge
void merge(customer **arr, int left, int mid, int right){
    int sizeL = (mid - left) + 1;
    int sizeR = (right -  mid);

    customer **leftArray = (customer**)malloc(sizeL * sizeof(customer*));
    customer **rightArray = (customer**)malloc(sizeR * sizeof(customer*));

    for(int i =0; i<sizeL; i++){
        leftArray[i] = arr[left + i];
    }
    for(int i = 0; i<sizeR; i++){
        rightArray[i] = arr[mid + 1 + i];
    }
    int i, j=0;
    int k = left;

    while(i < sizeL && j < sizeR){
        if(compareByPoints(leftArray[i], rightArray[j]) >= 0){
            arr[k] = leftArray[i];
            i++;
        }else{
            arr[k] = rightArray[j];
            j++;
        }
        k++;
    }
    while(i<sizeL){
        arr[k] = leftArray[i];
        i++;
        k++;
    }
    while(j<sizeR){
        arr[k] = rightArray[j];
        j++;
        k++;
    }
    free(leftArray);
    free(rightArray);

}

我已经向 compareByPoints 函数添加了调试语句,并且它返回了预期值。但是,排序未按预期工作。

有人可以查看代码并提供有关排序可能无法正常工作的原因的见解吗?任何帮助或建议将不胜感激。

c 数学

评论


答: 暂无答案