二叉排列树问题(10月23日之前解决者优先给分)

zachary7833 2003-10-22 02:36:53
typedef struct node
{
int data;
struct node *lc,*rc;
}*bitreptr,*tpointer;
要求用turbo C
1.删除一节点,删除后还是二叉排列树(比如删除下面的12)
2.在屏幕上显示二叉树(能分层)如
12
10 20
8 15 11 30
...全文
78 24 打赏 收藏 转发到动态 举报
写回复
用AI写文章
24 条回复
切换为时间正序
请发表友善的回复…
发表回复
zachary7833 2003-10-29
  • 打赏
  • 举报
回复
终于解决了删除问题,
也实现按层遍历,
现在只剩按层输出了.
每层某一节点前空格个数(不要编号)满足什么关系
zachary7833 2003-10-28
  • 打赏
  • 举报
回复
我运行过了
create函数不能改变main函数中的root的值;
但是为什么调用完func2(root);main()中root->data的值为0;

按你的意思应该为1,在void func2(node* root)中root是局部变量,
调用完就消失,但实际却把main()中的root->data的值改掉
likangnian0128 2003-10-27
  • 打赏
  • 举报
回复
对了,注意main函数中这一句root = create();
你原先没有将create的返回值赋给root,这才是为什么你的root如果赋初值NULL就会出错的原因


你对函数的参数传递方面还是没有完全学懂。

我上面说的那个问题,在这里依然存在。
如果你的程序是这样:
node *root=NULL; // root的值是: NULL
create(root); // root的值还是…………: NULL
// create函数不能改变main函数中的root的值的~
output(root); // root值是NULL当然会出错


你运行一下这个程序,大概就明白了:

#include "stdlib.h"
#include "stdio.h"
typedef struct Node //这个定义和你的一样
{
struct Node *rc, *lc;
int data;
}node;

node *newnode(int x) //这个函数也和你的一样
{
node *tmp = (node*)malloc(sizeof(node));
tmp->lc = tmp->rc = NULL;
tmp->data = x;
return tmp;
}

void func(node* root) {
root = newnode(1000); //将root指向一个新的结构体
printf("in func, change root, and the root's data is %d\n", root->data);
}

void func2(node* root) {
root->data = 0; //改变root所指向的结构体中data成员的值
printf("in func2, change root->data, and the root's data is %d\n", root->data);
}

void main() {
node *root = newnode(1);
printf("in main, let root point to a new struct with value 1, the root's data is %d\n", root->data);

func(root);
printf("in main, after calling func, the root's data is %d\n", root->data);

func2(root);
printf("in main, after calling func2, the root's data is %d\n", root->data);

}
likangnian0128 2003-10-27
  • 打赏
  • 举报
回复
看了一下,算法上应该没有什么问题,出错全都来自程序细节上(对C还不够熟啊)。

改了一下,见下(其余函数没有改过):

node *create() //为什么要去掉root这个参数,自己反省一下:root这个参数起到什么用了?
//不过这个参数不去也不会出错
{
node *root = NULL; //create内部使用的root定义在这里
node *k, *q, *p;
int n,x,i,found=0;

printf("Input the account of the nums:");
scanf("%d",&n);

printf("Input a serials of nums:");
for(i=1;i<=n;i++)
{
scanf("%d",&x);
p = newnode(x);
if (root == NULL)
root=p;
//if 语句里面可以加continue了,对于第一个节点来说,后面那些插入判断是不必要的,不过,不加也不会出错。

q = root;

found = 0; //found每次必须重新置为0,原因自己想想
while (q != NULL&& !found)
{
k = q;
if (q->data > x) {
q = q->lc;
continue; //这里、
}
if (q->data < x) {
q = q->rc;
continue; //还有这里,就是程序出错的原因所在
}
/*假设我先输入3,生成一个3的节点;然后我再输入2,生成2的节点后,将2插入到以3为根的树中时:if (q->data > x) q = q->lc; 经过这一步,q已经指向NULL,但是你的程序继续运行
if (q->data < x) ,q可是NULL啊,q->data是什么??非法访问~~~
*/
if (q->data==x)
found=1;
}

if(q==NULL)
if (k->data > x)
k->lc = p;
else
k->rc = p;
}

return root;
}

int main()
{
node *root=NULL;//如果是 node *root=NULL;为什么会出错?
//这个错,是在你原先程序细节的错误上才会产生的错误。
//那个错改了,这个也就不会出错
root = create();
output(root);
printf("\n\n");
del(root,3);
output(root);
printf("\n");
free_tree(root);

return 0;
}

最后:赶快学学如何调试程序吧~~
zachary7833 2003-10-26
  • 打赏
  • 举报
回复
#include "stdlib.h"
#include "stdio.h"
typedef struct Node
{
struct Node *rc, *lc;
int data;
}node;
node *newnode(int x)
{
node *tmp = (node*)malloc(sizeof(node));
tmp->lc = tmp->rc = NULL;
tmp->data = x;
return tmp;
}
node *create(node *root)
{
node *k, *q, *p;
int n,x,i,found=0;
printf("Input the account of the nums:")
scanf("%d",&n);
printf("Input a serials of nums:");
for(i=1;i<=n;i++)
{
scanf("%d",&x);
p = newnode(x);
if (root == NULL)
root=p;
q = root;
while (q != NULL&&!found)
{
k = q;
if (q->data > x)
q = q->lc;
if(q->data < x)
q = q->rc;
if(q->data==x)
found=1;
}
if(q==NULL)
if (k->data > x)
k->lc = p;
else
k->rc = p;
}
return root;
}
void output(node *root)
{

if (root == NULL) return;
output(root->lc);
printf("%d ", root->data);
output(root->rc);
}
void free_tree(node *root)
{
if (root == NULL) return;
free_tree(root->lc);
free_tree(root->rc);
free(root);
}
int del(node * root,int x)
{
node *k=NULL,*p=root,*q;
while(p!=NULL&&p->data!=x)
{
if(x<p->data)
{
k=p;
p=p->lc;
}
if(x>p->data)
{
k=p;
p=p->rc;
}
}
if(p==NULL)
return 0;
if(p->rc!=NULL&&p->lc!=NULL)
{
q=p->lc;
while(q->rc!=NULL)
{
q=q->rc;
}
q->rc=p->rc;
p->rc=NULL;
}
if(k==NULL)
root=p->lc;
if(k->lc==p)
k->lc=p->lc;
if(k->rc==p)
k->rc=p->lc;
//free(p);
return 1;
}
int main()
{
node *root=newnode(1);//如果是 node *root=NULL;为什么会出错?
create(root);
output(root);
printf("\n\n");
//del(root,3);
output(root);
printf("\n");
free_tree(root);
return 0;
}
//为什么当输入 1 2 打头的一组数,输出错误,结果为 1
//而当输入 2 打头的一组数,输出错误,结果为 1 2
zachary7833 2003-10-26
  • 打赏
  • 举报
回复
to:回复人: likangnian0128(while(1);) ( ) 信誉:100 2003-10-23 22:08:00 得分:0
按你的改仍然不行,run后输出一大堆奇怪的数,
把root改为全局变量也不可以,
你能看出哪里错了吗?
ZhangYv 2003-10-23
  • 打赏
  • 举报
回复
这种东西搜一下不就有了??
http://cosoft.org.cn/snippet/detail.php?type=snippet&id=14
likangnian0128 2003-10-23
  • 打赏
  • 举报
回复
我的bitreptr 和 tpointer 是自定义指针类型
指针传值会该变值!
——————————————————————————————————————————
………………

我这样举例吧

#include "stdio.h"

void func(int *a, int *b) {
a = b;
}

void main() {
int *a = new int;
int *b = new int;
*a = 1;
*b = 0;
func(a, b);
printf("%d", *a);
}

你认为输出是1还是0?

虽然func的两个参数都是指针,但是func内部改变的是指针本身(a、b)的值,而不是指针所指向的地址的值(*a、*b)。
你的sorttree也一样,改变了root的值,但没有改变*root

likangnian0128 2003-10-23
  • 打赏
  • 举报
回复
把你老师的代码全帖出来看看~
zachary7833 2003-10-23
  • 打赏
  • 举报
回复
我的bitreptr 和 tpointer 是自定义指针类型
指针传值会该变值!
zachary7833 2003-10-23
  • 打赏
  • 举报
回复
我很奇怪,sorttree()是我老师写的.他却在tc中运行正常.我加了几个函数却出错?
zachary7833 2003-10-23
  • 打赏
  • 举报
回复
likangnian0128(while(1);) 大哥多谢!
likangnian0128 2003-10-23
  • 打赏
  • 举报
回复
上面我的sorttree写错了一些:
应该是:
int sorttree(bitreptr* root, tpointer* p)
{
if(*root==NULL)
*root=*p;
if((*p)->data < (*root)->data)
sorttree( &((*root)->lc), p); //这里
if((*p)->data > (*root)->data)
sorttree( &((*root)->rc), p); //这里
if( (*p)->data == (*root)->data)
return 0;
return 1;
}

likangnian0128 2003-10-23
  • 打赏
  • 举报
回复
为什么Output()函数有问题?
是创建二叉排序树有问题吗?
——————————————————————————————————————————

不,是你的 sorttree函数有问题:

int sorttree(bitreptr root,tpointer p)

好好复习一下C里面参数传递方面,C用传值调用,将变量A传给某个函数F,函数F中的形参A'和外面的A是不同的变量(sorttree中的root和creat中的root是两个不同变量),改变A'的值不能改变A的值(改变sorttree中的root不能改变creat中的root)。
你在sorttree里改变root的值,但是creat函数中root的值不会改变。

解决方法:
1。将sorttree的参数改用传址调用(C++支持,但我记不清楚C是否支持):
只需修改函数申明
int sorttree(bitreptr& root, tpointer& p)

2。使用指向root和p的指针
int sorttree(bitreptr* root, tpointer* p)
{
if(*root==NULL)
*root=*p;
if((*p)->data < (*root)->data)
sorttree(root->lc, p);
if((*p)->data > (*root)->data)
sorttree(root->rc, p);
if( (*p)->data == (*root)->data)
return 0;
return 1;
}

并且creat函数中调用sorttree的地方也需要修改:
sorttree( &root, &p);


ps:你的sorttree改过之后,创建bst树应该没有问题了,
但你的output输出创建的BST的前序周游,但是bst要按中序周游,输出的才是排过序的
按中序周游:
void Output(bitreptr p)
{
if(p!=NULL)
{
Output(p->lc); // 次序变一下
printf(" %d",p->data);
Output(p->rc);
}
}


最后:创建bst基本成功,继续努力~
zachary7833 2003-10-23
  • 打赏
  • 举报
回复
不好意思,上面的图 11和15 反了
我学visual c++已有好一段时间了,
最近学数据结构才知我的基础这么差.真是惭愧!
另:
#include "stdio.h"
#include "alloc.h"
typedef struct node
{
int data;
struct node *lc,*rc;
}*bitreptr,*tpointer;
int sorttree(bitreptr root,tpointer p)
{
if(root==NULL)
root=p;
if(p->data<root->data)
sorttree(root->lc,p);
if(p->data>root->data)
sorttree(root->rc,p);
if(p->data==root->data)
return 0;
return 1;
}
bitreptr Creat(bitreptr root,int n)
{
int x,i;
tpointer p;
root=NULL;
for(i=1;i<=n;i++)
{
scanf("%d",&x);
p=(tpointer)malloc(sizeof(tpointer));
p->data=x;
p->lc=p->rc=NULL;
sorttree(root,p);
}
return root;
}
void Output(bitreptr p)
{
if(p!=NULL)
{
printf(" %d",p->data);
Output(p->lc);
Output(p->rc);
}
}
main()
{
bitreptr root;
root=Creat(root,5);
Output(root);
}
为什么Output()函数有问题?
是创建二叉排序树有问题吗?
flc 2003-10-22
  • 打赏
  • 举报
回复
学习
ZhangYv 2003-10-22
  • 打赏
  • 举报
回复
去搜搜平衡树的插入删除运算看看,遍历就是用广度优先按层遍历.代码都有现成的.
likangnian0128 2003-10-22
  • 打赏
  • 举报
回复
上面“中序周游的最后一个节点”中,指N的左子树进行中序周游的最后一个节点。

找这个节点只要从左子树的根开始,进入右子树,直到遇到一个没有左子树的节点,就是了。

用N2代替N,也要注意维护N2为根的BST的结构(删除N2,然后用N2中的值代替N中的值就好了。当然,不要用递归调用来删除N2,因为以N2为根的树是不会有右子树的,删除N2比删除N要简单)
likangnian0128 2003-10-22
  • 打赏
  • 举报
回复
BST删除节点N:

N左子树非空:找N的左子树找最大值的节点N2(中序周游的最后一个节点),用N2代替N,删除N
N左子树空:删除N

没有太多的条件判别吧?


显示二叉树:
先判断一下二叉树的树高,并判断出最下一层最多有多少个节点。
每一层作为一行输出,然后就是计算每一个节点前需要给多少个空格的问题了。

PS:这种基础题目,还是自己动手吧
bluesprit007 2003-10-22
  • 打赏
  • 举报
回复
排除要删除的,留下的重新排序就可以了
加载更多回复(4)

69,374

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧