CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
山寨机中的战斗机! 程序优化工程师到底对IT界有没有贡献
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  C/C++ >  C语言

01年下午程序员试题4,求教大侠,非常感谢你们的帮助

楼主zheliu(吉祥)2004-05-04 01:22:30 在 C/C++ / C语言 提问

再次请教一下各位兄弟,如下的双向循环列表是如何形成的,麻烦各位朋友了  
        并祝节日快乐  
         
      NODE   *building(   char   *s   )   /*生成双向循环链表*/  
   
  {   NODE   *p   =   NULL,   *q   ;  
   
          while   (   *s   ){  
   
                  q   =   (   NODE   *   )   malloc(   sizeof(   NODE   )   )   ;  
   
                  q   ->   ch   =   *s++   ;  
   
  if   (   p   ==   NULL   )   p   =   q   ->   fpt   =   q   ->   bpt   =   q   ;   //开始时插入的新节点的前趋指针   后继指针,p,q都指向新建节点  
                  else   {  
   
          p   ->   bpt   ->   fpt   =   q   ;   //请问接下来的p,q是如何变化的?   这行等价于p=q吗?  
   
                          q   ->   fpt   =   p   ;                                                 //这下面三行我有点糊涂了  
   
                          q   ->   bpt   =   p->bpt;              
   
                          p->bpt=q   ;                              
   
                  }  
   
          }  
   
          return   p;  
   
  }  
   
   
   
   
   
  -----------------------------------------------------------------  
        全部代码如下:在TC2.0下已调试正确。  
         
      (顺便说一下,人邮版那书错误连篇,几乎页页都有错误,老顽童       网站上此题代码也有至少两处错误  
   
  ,我要考完试,第一件事就是公布勘误大全,呵呵^-^)  
   
   
  试题四  
   
  阅读下列程序说明和C代码,将应填入__(n)__处的字句写在答题纸的对应栏内。  
   
  [程序4说明]  
   
  设一个环上有编号为   0~n-1   的   n   粒不同颜色的珠子(每粒珠子颜色用字母表示,   n   粒珠子颜色由输入的  
   
  字符串表示)。以环上某两粒珠子间为断点,从断点一方按顺时针方向取走连续同色的珠子,又从断点另一  
   
  方按逆时针方向对剩下珠子取走连续同色的珠子,两者之和为该断点可取走珠子的粒数。移动断点,能取走  
   
  的珠子数不尽相同。本程序找出可以取走最多的珠子数及断点的位置。程序中用双向链表存储字符串。例  
   
  如,编号为0-9的10粒珠子颜色的字符串为“aaabbbadcc",对应链表为:   (图可参见老顽童网站    
   
  http://oldchild.myrice.com/spks/cxy01x.htm   )  
   
  #include<stdio.h>  
   
  #include<string.h>  
   
  #include<malloc.h>  
   
  typedef   struct   node   {   char   ch   ;  
   
                  struct   node   *fpt   ;   /*后继指针*/  
   
                  struct   node   *bpt   ;   /*前趋指针*/  
   
          }NODE   ;  
   
  NODE   *building(   char   *s   )   /*生成双向循环链表*/  
   
  {   NODE   *p   =   NULL,   *q   ;  
   
          while   (   *s   ){  
   
                  q   =   (   NODE   *   )   malloc(   sizeof(   NODE   )   )   ;  
   
                  q   ->   ch   =   *s++   ;  
   
  if   (   p   ==   NULL   )   p   =   q   ->   fpt   =   q   ->   bpt   =   q   ;  
   
                  else   {  
   
                          p   ->   bpt   ->   fpt   =   q   ;  
   
                          q   ->   fpt   =   p   ;  
   
                          q   ->   bpt   =   p->bpt;                
   
                          p->bpt=q   ;                            
   
                  }  
   
          }  
   
          return   p;  
   
  }  
   
  int   count(   NODE   *start   ,   int   maxn   ,int   step   )   /*求可取走珠子粒数*/  
   
  {   int   color   ,c   ;  
   
          NODE   *p   ;  
   
          color   =   -1   ;   c   =   0   ;  
   
          for   (   p   =   start   ;   c   <maxn   ;   p   =   step   >   0   ?   p   ->   fpt:p   ->   bpt   ){  
   
                  if   (   color   ==   -1   )   color   =   p   ->   ch   ;  
   
                  else   if   (color!=p->ch)   break   ;  
   
  c++   ;  
   
          }  
   
          return     c;  
   
  }  
   
   
   
  int   find   (   char   *s   ,int   *cutpos   )   /*寻找取走珠子数最多的断点和粒数*/  
   
  {   int   i   ,   c   ,   cut   ,   maxc   =   0   ,len   =   strlen(s)   ;  
   
          NODE   *p   ;  
   
          if   (   (   p   =   building(s)   )   ==   NULL   ){   *cutpos   =   -1   ;   return   -1   ;   }  
   
          i   =   0   ;  
   
          do   {   c   =   count(   p   ,   len   ,1   )   ;  
   
                  c   =   c   +   count(p->bpt,len-c,-1);  
   
                  if   (   c   >   maxc   )   {   maxc   =   c   ;   cut   =   i   ;   }  
   
                  p=p->fpt;  
   
                  i++   ;  
   
          }   while   (i   <   len   )   ;  
   
          *   cutpos   =   cut   ;  
   
          return   maxc   ;  
   
  }  
   
   
  void   main()  
   
  {   int   cut   ,   max   ;  
   
          char   s[120]   ;  
   
          scanf(   "%s",   s   )   ;  
   
          max   =   find(   s   ,   &cut   )   ;  
   
          printf   (   "Cut   position   =   %d   ,   Number   =   %d.\n"   ,   cut   ,   max   )   ;  
   
  }  
   
   
   
   
  问题点数:40、回复次数:7Top

1 楼zheliu(吉祥)回复于 2004-05-04 01:26:55 得分 0

对不起,地址有误。应该是http://oldchild.nbc.net.cn/stcxy.htm  
    谢谢大家Top

2 楼zheliu(吉祥)回复于 2004-05-04 14:27:01 得分 0

请帮帮我。谢谢Top

3 楼cngdzhang()回复于 2004-05-04 15:12:01 得分 30

p   ->   bpt   ->   fpt   =   q   ;   //请问接下来的p,q是如何变化的?   这行等价于p=q吗?  
        q   ->   fpt   =   p   ;                                                 //这下面三行我有点糊涂了  
        q   ->   bpt   =   p->bpt;              
        p->bpt=q   ;                              
   
   
  这是插入多于一个节点的情形,q是待插入节点,p是头指针  
   
  p   ->   bpt   ->   fpt   =   q   ;     //q成为p的后继的前驱  
  q   ->   fpt   =   p   ;                   //p成为q的前驱  
  q   ->   bpt   =   p->bpt;           //p的后继成为q的后继  
  p->bpt=q   ;                           //q成为p的后继  
   
  这实际上是把新节点插入到了p和   p的原后继之间  
   
  画一个图会好理解一些  
   
  并不是p=q,这是为了插入节点时能保持前后继的索引,不至于丢失  
   
   
  Top

4 楼lbaby(春天来了...)回复于 2004-05-04 15:30:03 得分 10

看得人迷迷糊糊的  
  好像写程序的人把程序写的容易看明白一点就对不起这个世界似的  
  替换一下  
  typedef   struct   node    
                {    
                  char   ch   ;  
                  struct   node   *next;   /*后继指针*/  
                  struct   node   *prev;   /*前趋指针*/  
   
          }NODE   ;  
  /*   ...   */  
   
  NODE   *building(   char   *s   )    
  {    
        NODE   *node   =   NULL,   *new_node   ;  
   
          while   (   *s   )  
              {  
   
                  new_node   =   (   NODE   *   )   malloc(   sizeof(   NODE   )   )   ;  
   
                  new_node   ->   ch   =   *s++   ;  
   
                    if   (   node   ==   NULL   )    
                            {  
   
                                node   =   new_node   ->   next  
                                          =   new_node   ->   prev  
                                          =   new_node   ;    
                            }  
                    else    
                        {  
                          node   ->   prev   ->   next   =   new_node   ;   //这种写法是为了改变这个双向链表本身  
                                                                                              //的内容,而不是node的内容  
                                                                                              //你可以试试   改一下,node   =   new_node  
                                                                                              //看看最后的结果会是什么  
                          new_node   ->   next   =   node   ;                                              
                          new_node   ->   prev   =   node->prev;              
                          node->prev=new_node   ;                              
                      }  
   
          }  
   
          return   node;  
   
  }  
   
  另外,上边的代码没有对内存不足作出准备,如果内存不足的话...  
  Top

5 楼zheliu(吉祥)回复于 2004-05-04 21:13:34 得分 0

谢谢cngdzhang()   我画过图了,你的文字意思我看懂了,其实质确实是把新节点插入到了p和   p的原后继之间。  
    但我觉我的分析有误!  
    我对代码的理解是,在已有一个节点(p指向)时,分配一个新节点(q指向),发生如下变化:  
     
  p   ->   bpt   ->   fpt   =   q   ;   //q成为p的前驱的后继   即p指向的节点的后继指针指向新分配的节点  
  q   ->   fpt   =   p   ;                   //p成为q的后继  
  q   ->   bpt   =   p->bpt;           //p的前驱成为q的前驱   既新分配节点指向原来的老节点(p指向的)  
  p->bpt=q   ;                           //q成为p的前驱  
   
  我的问题现在变成了如果从字面上理解         p   ->   bpt   ->   fpt   =   q的意思是  
  q成为p的前驱的后继   还是   q成为p的后继的前驱?(虽然我知道后面的肯定是对的)  
   
  因为  
  题目上的规定struct   node   *fpt   ;   /*后继指针*/    
   
                          struct   node   *bpt   ;   /*前趋指针*/  
   
  To   lbaby(阳光下对着天使竖起中指)  
   
  您的意思     这种写法是为了改变这个双向链表本身的内容,而不是p的内容,您的意思我不太明白。  
   
  现在我发现p->bpt->fpt竟然不是p?   哎,绕死了  
  Top

6 楼cngdzhang()回复于 2004-05-04 21:22:17 得分 0

我没有看到你的题目啊  
  题目上的规定struct   node   *fpt   ;   /*后继指针*/    
   
                          struct   node   *bpt   ;   /*前趋指针*/  
   
   
  我的翻译是     *fpt             front   pointer     向前指针  
                          *bpt             back     pointer     向后指针  
   
  如果你要按题目去理解,那么把我的"前驱"换成"后继","后继"换成"前驱"就好了  
  都能达到插入节点的目的  
   
  Top

7 楼zheliu(吉祥)回复于 2004-06-08 17:05:44 得分 0

非常感谢你们Top

相关问题

  • 程序员试题
  • Microsoft程序员测试题
  • 微软程序员考试题
  • 某公司招VC程序员试题
  • 程序员试题,高手请进!!!
  • 经典LINUX程序员面试题:
  • .net程序员面试题集锦!
  • 求模拟试题(高级程序员)
  • 求,程序员面试试题!
  • 请问哪有高级程序员的试题下?

关键词

  • 指针
  • 节点
  • 断点
  • 代码
  • 循环
  • 内容
  • bpt
  • fpt
  • 珠子
  • 前驱

得分解答快速导航

  • 帖主:zheliu
  • cngdzhang
  • lbaby

相关链接

  • C/C++ Blog
  • C/C++类图书
  • C/C++类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
Copyright © 2000-2008, CSDN.NET, All Rights Reserved
GongshangLogo