【发布时间】:2015-05-18 22:02:21
【问题描述】:
当从我的“产品”二叉树中删除一个具有两个子节点的节点时,而不是将要删除的根替换为它的左子最右边的祖先,然后删除该后代,它只是用祖先值替换该根的值.我在那个祖先上调用了“free()”,但这似乎不起作用。所以我剩下的是两个相同值的节点。
我的代码:
#include <stdio.h>
#include <stdlib.h>
//Structures
typedef struct Node{
void *dataPtr;
struct Node *left;
struct Node *right;
}node;
typedef struct Product
{
int ProductCode;
char ProductName[30];
int QuantityOnHand;
double ProductCost;
double ProductRetail;
char ProductLocationCode[7];
}product;
//functions
int compareID(void *ptr1, void *ptr2)
{
int temp;
if (((product *)ptr1)->ProductCode > ((product *)ptr2)->ProductCode)
temp = 1;
else
if (((product *)ptr1)->ProductCode < ((product *)ptr2)->ProductCode)
temp = -1;
else
temp = 0;
return temp;
}
void insert(node ** root, node** val, int(*f)(void*,void*)){
if (!(*root)) {
//initalize a temporary node
node *temp = NULL;
temp = (node *)malloc(sizeof(node));
//make both right and left nodes for temp to be NULL
temp->left = NULL;
temp->right = NULL;
temp->dataPtr = (*val)->dataPtr;//store value you were looking for in temp
*root = temp;// root is now the temporary node
return;//end of function.
}
int result = f((*root)->dataPtr, (*val)->dataPtr);
if (result == 1) {//if the value is less than the current root node, go to the left connecting node
insert(&(*root)->left, &(*val), f);
}
else if (result == -1) {//if the value is more than the current root node, go to the right connecting node
insert(&(*root)->right, &(*val), f);
}
}
struct Node* deleteNode(struct Node *root, void *ptr, int(*cptr)(void*, void*))
{
struct Node *temp;
if (cptr(ptr, root->dataPtr) == 0)
{
if (root->left == NULL && root->right == NULL)//no children
{
free(root);
return NULL;
}
if (root->left != NULL && root->right == NULL)//left child
{
temp = root->left;
free(root);
return temp;
}
if (root->left == NULL && root->right != NULL)//right child
{
temp = root->right;
free(root);
return temp;
}
else //two children
{
struct Node* pred = root->left;//go left one of the node you're trying to delete
while (pred->right != NULL){//now get further right ancestor of that node
pred = pred->right;
}
root->dataPtr = pred->dataPtr; //make the original node the value of that right ancestor
return pred;//return that ancestor to delete it
}
}
else
{
int val = cptr(ptr, root->dataPtr);
if (val < 0)
{
root->left = deleteNode(root->left, ptr, cptr);
return root;
}
else
{
root->right = deleteNode(root->right, ptr, cptr);
return root;
}
}
}
void readData(struct Node** vptr, FILE *fp){
product* ptr = (product *)malloc(sizeof(product));
if (fp == stdin){
printf("Enter Product Code: ");
fscanf(fp, "%d", &(ptr->ProductCode));
fflush(stdin);
printf("Enter Name: ");
fscanf(fp, "%30[^\n]", ptr->ProductName);
fflush(stdin);
printf("Enter Quantity: ");
fscanf(fp, "%d", &(ptr->QuantityOnHand));
printf("Enter Cost: ");
fscanf(fp, "%lf", &(ptr->ProductCost));
fflush(stdin);
ptr->ProductRetail = (ptr->ProductCost / 0.7);
printf("Enter Location: ");
fscanf(fp, "%6[^\n]", &(ptr->ProductLocationCode));
fflush(stdin);
}
else{
fscanf(fp, "%d %29[^\n] %d %lf %6[^\n]", &(ptr->ProductCode), ptr->ProductName, &ptr->QuantityOnHand, &ptr->ProductCost, &ptr->ProductLocationCode);
ptr->ProductRetail = (ptr->ProductCost / 0.7);
}
(*vptr)->dataPtr = ptr;
}
int main()
{
int i = 0;
struct Node *newNode, *temp;
struct Node *root = NULL;
int(*compPtr)(void *, void *) = compareID;
for(i; i < 3; i++){
newNode = (struct Node *)malloc(sizeof(struct Node));
newNode->left = newNode->right = NULL;// missing this operation.
readData(&newNode, stdin); // this function call was missing.
insert(&root, &newNode, compPtr);
}
temp = (struct Node *)malloc(sizeof(struct Node));
temp->dataPtr = malloc(sizeof(struct Product));
printf("enter the product ID to delete : ");
fflush(stdin);
scanf("%d", &((struct Product *)temp->dataPtr)->ProductCode);
deleteNode(root, temp->dataPtr, compPtr);
free(temp->dataPtr);
free(temp);
return 0;
}
为什么这个祖先节点没有从内存中释放?我应该更改哪些内容才能确保将其删除?
【问题讨论】:
-
你的调试器向你展示了什么?
-
@StarPilot 尝试将 predecor 返回到 main 时,它没有释放内存中的正确点
-
所以您在调试器中看到了问题。您的调试器会向您显示哪些节点被选中?
标签: c data-structures binary-search-tree