提问人:Albert Jojo 提问时间:11/13/2023 最后编辑:Albert Jojo 更新时间:11/13/2023 访问量:32
在 C 语言中对指向结构的指针数组进行排序 - 合并排序未按预期工作
Sorting an Array of Pointers to Structs in C - Merge Sort Not Working As Expected
问:
我正在开发一个 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 函数添加了调试语句,并且它返回了预期值。但是,排序未按预期工作。
有人可以查看代码并提供有关排序可能无法正常工作的原因的见解吗?任何帮助或建议将不胜感激。
答: 暂无答案
下一个:如何计算三角射线交点的坐标?
评论