我需要使用方法inorder_tree_walk
,tree_search
,tree_minimum
,tree_successor
,tree_insert
和tree_delete
构建二叉树。当我尝试编译我的程序时,我得到了异常mytree was nullptr
。我可能在插入和删除方法方面遇到问题,程序的其他部分工作正常。我根据Cormen写了这段代码。我需要任何建议,谢谢。
#include "stdafx.h"
#include <stdlib.h>
struct tree {
int key;
struct tree *parent, *left, *right;
struct tree *root;
};
void inorder_tree_walk(struct tree *x) {
if (x != NULL) {
inorder_tree_walk(x->left);
printf("%d ", x->key);
inorder_tree_walk(x->right);
}
}
struct tree *tree_search(struct tree *x, int key) {
if (x == NULL || key == x->key)
return x;
if (key < (x->key)) {
return tree_search(x->left, key);
} else {
return tree_search(x->right, key);
}
}
struct tree *tree_minimum(struct tree *x) {
while (x->left != NULL)
x = x->left;
return x;
}
struct tree *tree_successor(struct tree *x) {
struct tree *y;
if (x->right != NULL) {
return tree_minimum(x->right);
}
y = x->parent;
while (y != NULL && x == y->right) {
x = y;
y = y->parent;
return y;
}
}
struct tree *tree_insert(struct tree *mytree, int key) {
struct tree *x = NULL;
struct tree *z = NULL;
struct tree *y = NULL;
x = mytree->root;
while (x != NULL) {
y = x;
if (z->key < x->key)
x = x->left;
else
x = x->right;
}
z->parent = y;
if (y == NULL) {
mytree->root = z;
} else
if (z->key < y->key)
y->left = z;
else
y->right = z;
return 0;
}
struct tree *tree_delete(struct tree *tree, int key) {
struct tree *z = NULL;
struct tree *x;
struct tree *y;
if (z->left == NULL || z->right == NULL) {
y = z;
} else
y = tree_successor(z);
if (y->left != NULL)
x = y->left;
else
x = y->right;
if (x != NULL)
x->parent = y->parent;
if (y->parent = NULL)
tree->root = x;
else
if (y = y->parent->left)
y->parent->left = x;
else
y->parent->right = x;
if (y != z)
z->key = y->key;
return y;
}
int main() {
tree *root = NULL;
root = tree_insert(root, 7);
root = tree_insert(root, 13);
root = tree_insert(root, 8);
root = tree_insert(root, 23);
root = tree_insert(root, -7);
root = tree_insert(root, 13);
root = tree_insert(root, 31);
root = tree_insert(root, 5);
inorder_tree_walk(root);
printf("\n\n");
tree *tmp;
tmp = tree_minimum(root);
printf("minimum = %d\n", tmp->key);
root = tree_delete(root, 8);
root = tree_delete(root, -7);
root = tree_delete(root, 31);
inorder_tree_walk(root);
printf("\n\n");
tmp = tree_search(root, 13);
if (tmp == NULL) {
printf("not found\n");
} else {
printf("found\n");
}
getchar();
}
答案 0 :(得分:2)
功能deserializeUser
的{{1}}循环中存在问题。您应该从while
中取出while块:
tree_successor()
return
调用未定义的行为,因为struct tree *tree_successor(struct tree *x) {
struct tree *y;
if (x->right != NULL) {
return tree_minimum(x->right);
}
y = x->parent;
while (y != NULL && x == y->right) {
x = y;
y = y->parent;
}
return y;
}
在第一个循环中被取消引用时为tree_insert
。应使用具有正确键值的新分配节点初始化z
。
NULL
有更多问题,你根本不从根节点走树。
答案 1 :(得分:1)
对于初学者,您应该从结构定义中删除数据成员root
。
struct tree {
int key;
struct tree *parent, *left, *right;
struct tree *root;
^^^^^^^^^^^^^^^^^
};
拥有这样的数据成员是没有意义的。
所以结构看起来像
struct tree {
int key;
struct tree *parent, *left, *right;
};
函数tree_insert
错误。至少它必须在返回0时返回指向树的根节点的指针。
struct tree *tree_insert(struct tree *mytree, int key) {
//...
return 0;
^^^^^^^^
}
参数mytree
也可以等于NULL但你忽略了这种情况。
我会按照以下方式编写函数
struct tree * tree_insert(struct tree *root, int key)
{
struct tree *parent = NULL;
struct tree **current = &root;
while (*current != NULL)
{
parent = *current;
if (key < ( *current )->key)
{
current = &( *current )->left;
}
else
{
current = &(*current)->right;
}
}
*current = (struct tree *)malloc(sizeof(struct tree));
(*current)->key = key;
(*current)->parent = parent;
(*current)->left = NULL;
(*current)->right = NULL;
return root;
}
使用此功能,您最后可以向树中添加节点并输出树。:)
您的树实施中还有其他错误。但是添加新节点的能力将简化您调试代码的能力。:)
这是一个测试程序
#include <stdlib.h>
#include <stdio.h>
struct tree * tree_insert(struct tree *root, int key)
{
struct tree *parent = NULL;
struct tree **current = &root;
while (*current != NULL)
{
parent = *current;
if (key < ( *current )->key)
{
current = &( *current )->left;
}
else
{
current = &(*current)->right;
}
}
*current = (struct tree *)malloc(sizeof(struct tree));
(*current)->key = key;
(*current)->parent = parent;
(*current)->left = NULL;
(*current)->right = NULL;
return root;
}
void inorder_tree_walk( const struct tree *root )
{
if (root != NULL)
{
inorder_tree_walk(root->left);
printf("%d ", root->key);
inorder_tree_walk(root->right);
}
}
int main( void )
{
tree *root = NULL;
root = tree_insert(root, 7);
root = tree_insert(root, 13);
root = tree_insert(root, 8);
root = tree_insert(root, 23);
root = tree_insert(root, -7);
root = tree_insert(root, 13);
root = tree_insert(root, 31);
root = tree_insert(root, 5);
inorder_tree_walk(root);
printf("\n\n");
}
程序输出
-7 5 7 8 13 13 23 31
它对应于以下树
7
/\
/ \
/ \
-7 13
\ / \
\ / \
6 8 23
/ \
/ \
13 31