你这个贪吃的蛇有人实现了,你可以到www.chinajavaworld.com去,就在首页上。

解决方案 »

  1.   

    你这是链表,跟java有什么关系
    而程序很正常,有什么可能是死循环
    这样看行不:
    if (--i > 0)
      next = new Snake(i, (char)(x + 1)); //问题1。
    else
      next = null;
      

  2.   

    这个程序没有什么问题啊!
    next = new Snake(i, (char)(x + 1))
    next我认为应该是指向你新生成的snake的一个指针!
    每一个next都是如此!
    在内存中就象是一个链表结构的!
    呵呵,我也是新手,如果有错请指出
      

  3.   

    谢谢,这个程序一点问题也没有,就是不明白其中的几个问题!!!
    TO:gdsean(摇滚java) (  ) 信誉:100 
         不好意思,我对链表不太清楚,给解释一下吗?
    TO:zjcxx(云啸) (  ) 信誉:100 
       next既然是指向新生成的Snake的一个指针(或是句柄,不知道对不对),经过“next = new Snake(i, (char)(x + 1));”这个递归构建,那么最终next指向的是第一个生成的对象的句柄(刚才提出的问题中想错了),后面是其它snake对象的句柄(即链表)。
      不知道上面说的对不对(如果正确,那我有点理解了)。
      可我还是不明白问题2:
      问题2、我认为这是一个无限死循环,因为next不可能为null啊!!!
        它指向的是Snake(5,'a').
    谢谢!!!   
      

  4.   

    你的toString方法并没有执行啊 因为你没有调用它
      

  5.   

    1问题一
    你忽略了next = new Snake(i, (char)(x + 1));的前提条件是
    if (--i > 0)
    既是只执行了4次。2问题二
      上面的问题,你如果能理解,这个就不难了,如楼上所说System.out.println(s)其实是5个Snake对象存的字符变量(a,b,c,d,e)3问题三
      s += next.toString(); 
      是因为对作为class的next进行强制类型转换时发生的。
      

  6.   

    你用debug的方式,看一下程序的执行过程就会明白了。
      

  7.   

    谢谢:chinajava(chinajava) (  ) 信誉:100 
    谢谢:MagicJohn(默克) (  ) 信誉:100 
       debug怎么使啊,呵呵!没有学过:(
       另外,谁能告诉我有没有java的调试工具呀!!!
      

  8.   

    链表是一种很有用的数据结构,它由一个一个数据单元组成,就像蛇的一节一节。每一个数据单元由一个数据体和一个“指针”构成。指针指向下一个单元内的数据体,就这样延长下去。最后一个单元内的指针指向NULL。(我是初学者,有什么说的不对的请各位指出,谢谢:)  )
      

  9.   

    因为你每次new一个snake对象他的next被初始化的值是default的
    是null
      

  10.   

    //============我的理解===========
    class Snake{
    private Snake SnakeNext;//节点中指向下一个节点的指针
    private char c;//节点独一无二的标记(a,b,c...)
    Snake(char x){ //构造函数
    c=x;
    SnakeNext=null;
    }

    Snake(char x,Snake Next){
    c=x;
    SnakeNext=Next;
    } char getX(){  //获得节点的标记
    return c;
    }
    Snake getNext(){   //获得节点的指针
    return SnakeNext;
    }
    void setX(char Character){ //修改节点的标记
    c=Character;
    }
    void setNext(Snake next){ //修改节点的指针
    SnakeNext=next;
    }
    }class LinkSnake{  //定义一个链表
    Snake FirstSnake;//链表中的第一个节点
    LinkSnake(){  //建立一个空链表
    FirstSnake=null;
    }

    LinkSnake(char c){  //建立只有一个节点的链表
    FirstSnake=new Snake(c);
    }
    String visitAllSnake(){  //遍历整个链表的节点,将每个节点的标记串成一个字符串
    Snake next=FirstSnake;  //从第一个节点开始
    String s="";
    while(next!=null){  //一直查找到最后一个节点
    s=s+next.getX();
    next=next.getNext(); //指向下一个节点,因为每个节点都还有指向下一个节点的指针
    }
    return s;
    }

    void insertSnakeAtBegin(char c){
    if(FirstSnake==null)
    FirstSnake=new Snake(c);
    else
    FirstSnake=new Snake(c,FirstSnake);//将新的节点放于链表的第一个

    }
    }public class UseLinkSnake{
    public static void main(String args[]){
    LinkSnake list=new LinkSnake();
    for(int i=0;i<5;i++){
    list.insertSnakeAtBegin((char)('a'+i));
    System.out.println(list.visitAllSnake());
    }
    System.out.println("s="+list.visitAllSnake());
    }
    }/*
    你好,我也是名初学者,看到了你的问题恰恰也是我这段时间想的。我把我的理解写在了上面。
    我个人认为你看不明白的原因是因为Snake这个类没有封装好。我将其重新封装了,我理解Snake类作为链表中的一个节点需要具备两个成员:
    本身独特的字符和指向下一个节点的指针,原来的封装不是很清楚表达这一特性,新的Snake类的构建器只含有字符和指针,生成五个节点
    我用了专门的方法insertSnakeAtBegin();将新生成的节点放于最前面。
    结果和你的有点差异,但是本质相同:
    a
    ba
    cba
    dcba
    edcba
    s=edcba*/
      

  11.   

    对不起!请恕我说:“ 你的基本功不好!”这是一个典型的链表。
    第一个问题:
    if (--i > 0)
    next = new Snake(i, (char)(x + 1)); //问题1。
    这两句的意思是将 i 先减一,然后如果i的新值仍大于 0 ,创建一个新的Snake对象并将它的句柄赋给 next 变量。
    如果你有C++基础,你可以认为next 是指向一个新Snake对象的指针。
    当你执行
    Snake s = new Snake(5,'a');时
    会产生5个Snake对象 
    s(c ='a',next)
               |->(c='b',next)
                           |->(c='c',next)
                                       |->(c='d',next)
                                                   |->(c='e',next='null')
    ps: 在最后一个对象的构造函数中 i 已经等于 0 了。所以next = new Snake(i, (char)(x + 1)); 不会被执行。同时因为一个对象如果没有赋值的话它的缺省值是null,所以 next 的值是一个null。(这是你的第二个问题)
    第三个问题:
    关键在 s += next.toString(); 
    如果你理解了以上二个问题,这个问题将迎刃而解。main函数中的
    System.out.println("s = " + s);
    执行了
    S.toString它分别调用了第二,三,四,五个对象的toSting。
    则s 变量的变化过程是
    :a
    :a:b
    :a:b:c
    :a:b:c:d
    :a:b:c:d:e
    你满意以上的答案吗??
      

  12.   

    C++的连表就把我搞的头都大了
    最后决定改学java 了,怎么这里还有连表啊!!!
    看不懂啊,怎么办?
    :(
      

  13.   

    /*
    哈哈,终于明白了,谢谢各位。
    刚开始看大家的解释的时候,说实在的,不是很明白。就是不明白真的是没有办法呀,非常苦恼。
    今天中午躺在床上,脑中突然闪过一个念头,豁然开朗,一下子明白过来了,谢谢各位的解释。!!!谢谢: chinajava(chinajava),woowindicej(黑山老妖)
    谢谢 zxnice(宁宁) ,你说的很对,很受启发。
    也谢谢 lxj_guitar(小林) 
    TO:hanson_yi() (  ) ,不用说对不起,我的基础真的是不好,以前自己看C语言的时候,接触过一点链表,但没有学好,
      谢谢,明白多了。看来我真得学点基础的东西了,得学点数据结构吧,呵呵!
    TO:JavaGir1(JavaGirl),呵呵,学C++很累吧,没接触过。
      不用担心,有这么多好朋友帮助我们,你还担心什么呀,我们共同努力吧,呵呵!  
    再次谢谢iamcyh(蓝色虾)与hanson_yi() (  )!!!
    */ /*以下是对iamcyh(蓝色虾)给我的回答的理解
    注:##标志是我的理解##
      **标志是我添加的语句**
    */ //============我的理解===========
    class Snake{
    private Snake SnakeNext;//节点中指向下一个节点的指针
    private char c;//节点独一无二的标记(a,b,c...)

    Snake(char x){ //构造函数
    c=x;
    SnakeNext=null; //
    } Snake(char x,Snake Next){//##用于多节点的构造函数##
    c=x;
    SnakeNext=Next;
    }

    char getX(){ //获得节点的标记
    return c; 
    }

    Snake getNext(){ //获得节点的指针,##指向下一个结点的指针##
    return SnakeNext; 
    } void setX(char Character){ //修改节点的标记,##"Character"是char的封装类的关键字,
    c=Character; //很奇怪编译没有问题且运行正常,不明白:)##
    } void setNext(Snake next){ //修改节点的指针,##指向下一个结点的指针##
    SnakeNext=next; 
    }
    }class LinkSnake{ //定义一个链表
    Snake FirstSnake;//链表中的第一个节点
    Snake LastSnake; //**,链表中的最后一个节点,用于追加节点** LinkSnake(){ //建立一个空链表
    FirstSnake=null;
    LastSnake = null;//****
    } LinkSnake(char c){ //建立只有一个节点的链表
    FirstSnake=new Snake(c);
    LastSnake = FirstSnake;//**第一个也是最后一个**
    } String visitAllSnake(){ //遍历整个链表的节点,将每个节点的标记串成一个字符串
    Snake next=FirstSnake; //从第一个节点开始
    String s="";
    while(next!=null){ //一直查找到最后一个节点
    s=s+next.getX();
    next=next.getNext(); //指向下一个节点,因为每个节点都还有指向下一个节点的指针
    }
    return s;
    }

    void insertSnakeAtBegin(char c){//##插入节点##
    if(FirstSnake==null)
    FirstSnake=new Snake(c); //##创建单结点的对象##
    else
    FirstSnake=new Snake(c,FirstSnake);//将新的节点放于链表的第一个
    }

    //**追加结点**
    void appendSnakeAtEnd(char c){
    if (FirstSnake == null){
    FirstSnake = new Snake(c);
    LastSnake = FirstSnake;//**第一个也是最后一个**
    }
    else
    {
    Snake Last = new Snake(c); //创建一个新的单节点的Snake
    LastSnake.setNext(Last); //设置原链表中最后一个节点指向下一个结点的指针为新刚新建的结点
    LastSnake = Last; //也就是说,追加了新的节点
    }
    }
    //**追加结点方法结束**
    }
    public class UseLinkSnake{
    public static void main(String args[]){
    //插入方式
    LinkSnake list=new LinkSnake();
    for(int i=0;i<5;i++){
    list.insertSnakeAtBegin((char)('a'+i));
    System.out.println(list.visitAllSnake());
    }
    System.out.println("s="+list.visitAllSnake());

    //**追加方式测试**
    LinkSnake list2 = new LinkSnake();
    for (int i = 0;i < 5 ;i++){
    list2.appendSnakeAtEnd((char)('a' + i));
    System.out.println(list2.visitAllSnake());
    }
    System.out.println("s2=" + list2.visitAllSnake());
    //**追加方式测试完毕**
    }
    }/*
    你好iamcyh(蓝色虾),谢谢!
    看了你的程序很受启发,现在这个程序比我原来的好理解多了!历害呀,:)根据我现在的理解,
    我加了一个方法,appendSnakeAtEnd()用于把新建的结点追加在最后,虽然实现了我原来的
    想法,但总觉得有点不妥,你可以看一看。希望以后多交流,^_^
    以下是运行的结果:
    a
    ba
    cba
    dcba
    edcba
    s=edcba
    a
    ab
    abc
    abcd
    abcde
    s2=abcde
    */
      

  14.   

    /*如果你的意思是不能够实现单个打印的话,我把程序新加一个visitOneSnake()的方法。程序如下:*/class Snake{
    private Snake SnakeNext;//节点中指向下一个节点的指针
    private char c;//节点独一无二的标记(a,b,c...)Snake(char x){ //构造函数
    c=x;
    SnakeNext=null; //
    }Snake(char x,Snake Next){//##用于多节点的构造函数##
    c=x;
    SnakeNext=Next;
    }char getX(){ //获得节点的标记
    return c; 
    }Snake getNext(){ //获得节点的指针,##指向下一个结点的指针##
    return SnakeNext; 
    }void setX(char Character){ //修改节点的标记,##"Character"是char的封装类的关键字,
    c=Character; //很奇怪编译没有问题且运行正常,不明白:)##
    }void setNext(Snake next){ //修改节点的指针,##指向下一个结点的指针##
    SnakeNext=next; 
    }
    }class LinkSnake{ //定义一个链表
    Snake FirstSnake;//链表中的第一个节点
    Snake LastSnake; //**,链表中的最后一个节点,用于追加节点**LinkSnake(){ //建立一个空链表
    FirstSnake=null;
    LastSnake = null;//****
    }LinkSnake(char c){ //建立只有一个节点的链表
    FirstSnake=new Snake(c);
    LastSnake = FirstSnake;//**第一个也是最后一个**
    }char visitOneSnake(){ //遍历整个链表的节点,将每个节点的标记串成一个字符串
    Snake next=FirstSnake; //从第一个节点开始
    char s2;
    s2=next.getX();
    next=next.getNext(); //指向下一个节点,因为每个节点都还有指向下一个节点的指针
    return s2;
    }String visitAllSnake(){ //遍历整个链表的节点,将每个节点的标记串成一个字符串
    Snake next=FirstSnake; //从第一个节点开始
    String s="";
    while(next!=null){ //一直查找到最后一个节点
    s=s+next.getX();
    next=next.getNext(); //指向下一个节点,因为每个节点都还有指向下一个节点的指针
    }
    return s;
    }void insertSnakeAtBegin(char c){//##插入节点##
    if(FirstSnake==null)
    FirstSnake=new Snake(c); //##创建单结点的对象##
    else
    FirstSnake=new Snake(c,FirstSnake);//将新的节点放于链表的第一个
    }//**追加结点**
    void appendSnakeAtEnd(char c){
    if (FirstSnake == null){
    FirstSnake = new Snake(c);
    LastSnake = FirstSnake;//**第一个也是最后一个**
    }
    else
    {
    Snake Last = new Snake(c); //创建一个新的单节点的Snake
    LastSnake.setNext(Last); //设置原链表中最后一个节点指向下一个结点的指针为新刚新建的结点
    LastSnake = Last; //也就是说,追加了新的节点
    }
    }
    //**追加结点方法结束**
    }
    public class UseLinkSnake{
    public static void main(String args[]){
    //插入方式
    LinkSnake list=new LinkSnake();
    System.out.println("以下为反向连续打印");
    for(int i=0;i<5;i++){
    list.insertSnakeAtBegin((char)('a'+i));
    System.out.println(list.visitAllSnake());
    }
    System.out.println("以下为单个打印");
    for(int i=0;i<5;i++){
    list.insertSnakeAtBegin((char)('a'+i));
    System.out.println(list.visitOneSnake());}
    System.out.println("以下为全部打印");
    System.out.println("s="+list.visitAllSnake());//**追加方式测试**
    LinkSnake list2 = new LinkSnake();
    System.out.println("以下为正向连续打印");
    for (int i = 0;i < 5 ;i++){
    list2.appendSnakeAtEnd((char)('a' + i));
    System.out.println(list2.visitAllSnake());
    }
    System.out.println("以下为正向全部打印");
    System.out.println("s2=" + list2.visitAllSnake());
    }
    }/* 这样就实现了原来的程序的全部功能了,由于这是一个链表,所以从一个节点寻找下一个节点很方便,但是从一个节点寻找指向它的节点就有点麻烦了(可以用一个Snake对象跟着一个Snake对象的方法,如果从参考书上没有看到这种实现的方法,你留言我会贴出来),所以这里的单个打印我只在首部添加节点实现。