NULLPointerException,最让人头疼的问题
我写了几个类,实现了stack,经过测试,可以正常工作,构造了BinNode,Bintree类,
BinNode ,Bintree的代码没有问题,也是基本按照经典数据结构的叶子节点与树节点的方法实现的,这里旨在实现一个堆栈的操作,将一颗二叉树先根遍历,编译是没有问题,但是运行时,却出现了问题:
出错的代码如下:
public class Try{
public static Stack S=new Stack();
public static void visit(Bintree T){
BinNode temp=T.getRoot();
while(temp.getRight()!=null)temp=temp.getRight();
while(temp!=T.getRoot()){
if(temp.getLeft()==null)S.push(temp);//第19行
else visit(new Bintree(temp.getLeft()));
temp=T.father(temp,T.getRoot());
}
visit(new Bintree(temp.getLeft()));
S.push(temp);
}
public static void main(String[] args){
//Try my=new Try();
BinNode A=new BinNode("a");
BinNode B=new BinNode("b");
BinNode C=new BinNode("c");
BinNode D=new BinNode("d");
Bintree E=Bintree.setupTree("e",A,C);
Bintree F=Bintree.setupTree("f",B,D);
Bintree G=Bintree.setupTree("g",E,F);
visit(G);//第34行
while(!S.isEmpty())System.out.println(S.pop());
}
}
这是出错的信息:
java.lang.NullPointerException
at mybinnodetree.Try.visit(Try.java:19)
at mybinnodetree.Try.main(Try.java:36)
Exception in thread "main" push----d
行号已在代码上标出,怎么也看不出来,如果加上try,catch,经过测试,发现d已经推入了堆栈,而且可以弹出,问题到底出现在哪里呢?
请高手帮着分析一下。
问题点数:100、回复次数:25Top
1 楼haode(好的)回复于 2002-11-21 01:14:45 得分 10
我觉得会不会是这个原因
你的temp并没有给他在内存中开辟空间,也就是没有new一下
Top
2 楼baitianhai(hong)回复于 2002-11-21 18:37:34 得分 10
对阿,也就是说 你可能 对 null 操作了Top
3 楼xiachedan(瞎扯蛋)回复于 2002-11-21 18:40:24 得分 10
有空指针存在了!!!Top
4 楼tiger999(不吃肉的老虎)回复于 2002-11-21 18:42:02 得分 60
从第一个while中退出时 temp=null 了
BinNode pre=temp;
while(temp。getRight()!=null){
pre=temp;
temp=temp。getRight();
}
用以上代码代替原来的 while loop
并用 pre 代替第二个while 中的 temp
Top
5 楼migrant1119(候鸟)回复于 2002-11-21 18:59:08 得分 0
收到!Top
6 楼Iforgot(清风雨)回复于 2002-11-21 19:22:53 得分 10
已经搞定了?还是没有?搞定了,我就走了,如果没有我再看看我能不能帮忙!:)Top
7 楼mefaintII(我晕)回复于 2002-11-21 19:23:37 得分 0
对一个null的对象操作Top
8 楼migrant1119(候鸟)回复于 2002-11-21 22:38:18 得分 0
不好意思,校园网刚才上不了。还是不好使啊,错误信息一样。
我还是把源代码列一下吧。
-----------------------------------------------------
package mybinnodetree;
class Stack {
private List top;
public Stack(){
setup();
}
public Stack(int sz){
setup();
}
private void setup(){
top=null;
}
public void clear(){
top=null;
}
public void push(Object it){
top=new List(it,top);
System.out.println("push----"+it);
}
public Object pop(){
Object it=top.element();
top=top.next();
System.out.println("pop-----"+it);
return it;
}
public boolean isEmpty(){
return top==null;
}
public Object topValue(){
return top.element();
}
}
--------------------------------------------------
package mybinnodetree;
class List {
private Object element;
private List next;
List(Object it,List nextval)
{
element=it;
next=nextval;
}
List(List nextval){
next=nextval;
}
List next(){
return next;
}
Object element(){
return element;
}
void setNext(List nextval){
next=nextval;
}
void setObject(Object it){
element=it;
}
}//class List
-----------------------------------------------------
package mybinnodetree;
class BinNode {
private Object obj;
private BinNode left;
private BinNode right;
public BinNode() {
obj=null;
left=right=null;
}
public BinNode(Object obj){
this.obj=obj;
left=right=null;
}
public void setLeft(BinNode left){
this.left=left;
}
public void setRight(BinNode right){
this.right=right;
}
public BinNode getLeft(){
return left;
}
public BinNode getRight(){
return right;
}
public void setObj(Object obj){
this.obj=obj;
}
public Object getObj(){
return obj;
}
public void release(){
obj=null;
left=null;
right=null;
}
public String toString(){
return obj.toString();
}
}
--------------------------------------------------
package mybinnodetree;
class Bintree {
private BinNode root;
private BinNode cur;
public Bintree() {
root=cur=null;
}
public Bintree(BinNode T){
root=cur=T;
}
public BinNode getRoot(){
return root;
}
public BinNode getCur(){
return cur;
}
public static Bintree setupTree(Object T,Bintree t1,Bintree t2){
BinNode R=new BinNode(T);
R.setLeft(t1.getRoot());
R.setRight(t2.getRoot());
return new Bintree(R);
}
public static Bintree setupTree(Object T,BinNode b1,BinNode b2){
BinNode R=new BinNode(T);
R.setLeft(b1);
R.setRight(b2);
return new Bintree(R);
}
public BinNode father(BinNode R,BinNode T){
if(R==null)return null;
else if(father(R.getLeft(),T)!=null)return father(R.getLeft(),T);
else return father(R.getRight(),T);
}
public BinNode left(){return cur.getLeft();}
public BinNode right(){return cur.getRight();}
public Object curValue(){return cur.getObj();}
/*public void visit(Bintree T){
Stack S=new Stack();
Bintree temp=T;
while(temp.right()!=null)temp=temp.right();
*/
}
--------------------------------------------------
使不是有什么错误啊,
谢谢大家了。Top
9 楼tiger999(不吃肉的老虎)回复于 2002-11-22 00:20:23 得分 0
你是要交差还是学习?
要交差就帮你重编一个
要学习就帮你 bug !!Top
10 楼migrant1119(候鸟)回复于 2002-11-22 00:29:15 得分 0
谢谢,学习
我又修改了一下代码,
public class Try{
public static Stack S=new Stack();
public static void visit(Bintree T){
BinNode temp=T.getRoot();
while(temp.getRight()!=null){
temp=temp.getRight();
}
while(temp!=T.getRoot()){
if(temp.getLeft()==null)S.push(temp);
else visit(Bintree.copyTree((temp.getLeft())));
temp=T.father(temp,T.getRoot());
}
visit(Bintree.copyTree(temp));
S.push(temp);
}
public static void main(String[] args){
//Try my=new Try();
BinNode A=new BinNode("a");
BinNode B=new BinNode("b");
BinNode C=new BinNode("c");
BinNode D=new BinNode("d");
Bintree E=Bintree.setupTree("e",A,C);
Bintree F=Bintree.setupTree("f",B,D);
Bintree G=Bintree.setupTree("g",E,F);
visit(G);
while(!S.isEmpty())System.out.println(S.pop());
}
}
树与节点的代码中又加了东西。
public static Bintree copyTree(BinNode T){
Bintree copy=new Bintree();
copy.root=BinNode.copyNode(T);
copy.cur=copy.cur;
return copy
}
public static BinNode copyNode (BinNode T){
BinNode copy=new BinNode();
copy.obj=T.obj;
if(T.left==null)copy.left=null;
if(T.right==null)copy.right=null;
if(T.left!=null)
copy.left=copyNode(T.left);
if(T.right!=null)
copy.right=copyNode(T.right);
return copy;
}
可是还是那个信息,楼上的仁兄,麻烦你了。Top
11 楼ZXJ518(zou)回复于 2002-11-22 01:35:16 得分 0
外边是不是包了什么try,catch呀,
如果结果没问题,想办法处理一下,不要抛出这个异常好了
Top
12 楼tiger999(不吃肉的老虎)回复于 2002-11-22 02:55:36 得分 0
你的visit()写的不对
public static void visit(BinNode root){
if(root!=null)
{
S.push(root);
visit(root.getLeft());
visit(root.getRight());
}
}
程序虽然可以运行但你要好好学数据结构
树结构不是像你这么写的
有时间再和你探讨
Top
13 楼migrant1119(候鸟)回复于 2002-11-22 10:36:10 得分 0
我知道这种第归的算法,但要求是迭代的算法,有两种迭代,要么就是用两个while循环,要么就是这个第归加迭代的算法,前面那个已经测试过了,能行,这个不行,所以拿上来问问。而且前面那个版本用堆栈时没有问题,后面这个就不行了。Top
14 楼tiger999(不吃肉的老虎)回复于 2002-11-22 13:37:00 得分 0
前面那个是那一个?
这个又是那一个?Top
15 楼migrant1119(候鸟)回复于 2002-11-22 20:21:03 得分 0
前面的是两个while循环的,后一个是我写的这个。Top
16 楼tiger999(不吃肉的老虎)回复于 2002-11-22 23:56:50 得分 0
用二个while的能行?
我看不行吧
1 while(temp.getRight()!=null)temp=temp.getRight();
2 while(temp!=T.getRoot()){
if(temp.getLeft()==null)S.push(temp);//第19行
//这里 temp 已是 null 了!!!
//调用 temp.getLeft() 当然要出错!!!
else visit(new Bintree(temp.getLeft()));了
temp=T.father(temp,T.getRoot());
}
Top
17 楼migrant1119(候鸟)回复于 2002-11-23 16:37:58 得分 0
不是,我没说清楚,我的意思是只有两个while循环,而没有第归操作,上面列出的这个是指后一个。
我去,把符号写错了。
if(temp.getLeft()==null)S.push(temp);//第19行
中的==应该为!=才对,但还是执行不了,而且原因只有一个,就是拷贝函数的错误。build-in type成员的直接用clone就行,有一个嵌套类的重写一个clone就可以,但我这里是链表结构,怎么写,不会是一层一层判断,其内部前套是否为null,然后再分别调用obj的clone函数,来生成新的链表啊。以前看过类似的问题,是在csdn在是第六期的附属ibm的developer上看到的,可是找不到了,又忘了怎么写,请帮我把双链表结构的clone函数写一下。
Top
18 楼tiger999(不吃肉的老虎)回复于 2002-11-23 18:06:55 得分 0
先说这个问题
改成!=还是不行的
Top
19 楼migrant1119(候鸟)回复于 2002-11-23 21:58:29 得分 0
那找我的思路,我应该怎样呢?
Top
20 楼tiger999(不吃肉的老虎)回复于 2002-11-24 16:42:16 得分 0
关于clone:
一般来说, 不到万不得以,不使用clone.
本质上,clone 就是对象复制.在C++ 中,这是由copy constructor 实现的
但在java中,情况就不一样了.java中的对象都是从java.lang.Object
继承来的.Object中有一个protected Object clone()并提供了缺省的实现
但这个缺省的实现只是一个浅复制.象你的这种情况, 必须用深层复制.也就
是说如果有复制一棵子树,必须遍历该子树所有的节点并复制每个节点
在java中使用复制的另一个缺点是,如果其他人想继承你的类,他会分不清楚
你的类只是简单的公开了Object 的缺省实现还是有你的具体实现.
另外,我看不出有必要在你的程序中实现clone.还有,何为先根遍历?
我只知道树大概有四种遍历: preorder 先序遍历, inorder 中序遍历
postorder 后序遍历 levelorder 按层遍历.你说的是那一种?
Top
21 楼migrant1119(候鸟)回复于 2002-11-25 10:41:40 得分 0
呵呵,先根遍历就是先序遍历呀,以前上课的时候老师这么讲,于是大家都这么叫,叫惯了。另外,我不用clone,用先前那种方法行吗?先前我只用固定的节点产生不同的tree,而且并没有删除,所以应该没有问题。看来只是逻辑上的问题了,但是改成你提供的方法也不行,那我应该怎么改呢?Top
22 楼migrant1119(候鸟)回复于 2002-11-25 23:18:22 得分 0
我明白该怎么办了,里面确实有空指针问题。
public BinNode(Object obj){
this.obj=obj;
left=right=null;
}
这个构造器不对,应该改成这样:
public BinNode(Object obj){
this.obj=obj;
left=new BinNode();
right=new BinNode();
}
如果没有以外,这个肯定行,不用clone,直接用最开始的版本。
while部分也应该不用该。
“不吃肉的老虎”兄,请你帮我试一试吧,我的jbuilder中的扮演linking的部分坏了,PList,PStack类均不可见。重装也不行,最近正好要考试了,这个东西我暂时得放一放,要不考试挂了。
麻烦你了,呵呵。Top
23 楼migrant1119(候鸟)回复于 2002-11-25 23:19:35 得分 0
顺便,谢谢你的关照。交个朋友吧!Top
24 楼tiger999(不吃肉的老虎)回复于 2002-11-26 16:47:42 得分 0
你原来的构造器并没有错
你的新版构造器到有问题
BinNode()在那里(不是BinNode(Object obj))
再说,给leaf nodeTop
25 楼migrant1119(候鸟)回复于 2003-01-27 15:29:11 得分 0
呵呵,好久没来了,结贴了。Top




