程序员补课笔记(19)

来源:互联网 发布:软文自助发布平台源码 编辑:程序博客网 时间:2024/05/04 23:18
大家应该没有忙了今天是什么节日了吧?我想大家应该没有吧。因为这是我小时候最刺激的时候了,因为我和我的兄弟们都忙着准备那晚的东西,在街上捡些石头啊,线子啊,木棒啊。有什么用?当然就是用来打鬼的啊!(我们太大胆了吧!?)真奇怪当时会这么勇呢。但同样是该节的今天(什么?真的不知道今天是什么日子?那就是7月14鬼节啊!),我又约好朋友一齐去玩了,但屈指一数今年都已经18了,长大了,当然不能和小时候一样年少无知。所以我们什么也没有拿,只拿了最重要的一样东西,当然是钱啊,"有钱使的鬼推磨"。不过我们还是很快的喝了些东西就马上回家了,望路上没有什么东西跟着我回去吧。
  也就是因为这样今晚要写的补课日记也误了,只好今天(23号)把它补回吧。其实从前天开始已经是开始接触程序员的考试的试题了,希望大家在我讲的时候也能自己先做做。下面我们开始写下这道2001年程序员考试的试题,如下:
阅读下列程序说明和C代码,将应填入__(n)__处的字句写在答题纸的对应栏内。
[程序说明]
  本程序中的函数 first_insert() 的功能是在已知链表的首表元之前插入一个指定值的表元;函数 reverse_copy() 的功能是按已知链表复制出一个新链表,但新链表的表元链接顺序与已知链表的表元链接顺序相反;函数 print_link() 用来输出链表中各表元的值;函数 free_link()用来释放链表全部表元空间。
[程序2〕
#include〈stdip.h〉
#include〈malloc.h〉
typedef struct node
{
  int val;
  struct node *next;
} NODE;
void first_insert( NODE **p,int v)
{
  NODE *q = (NODE *) malloc( sizeof(NODE));
  q -> va1 = v;__(1)__; *p = __(2)__;
}
NODE *reverse_copy(NODE *p)
{
  NODE *u;
  for( u = NULL ; p ; p = p ->next ) first_insert(__(3)__);
  return u;
}
void print_link( NODE *p )
{
  for( ;__(4)__) printf ("%d/t" , p -> val);
  printf("/n");
}
void free_link(NODE*p)
{
  NODE *u;
  while( p != NULL){ u=p-〉next;free( p );__(5)__;}
}
void main()
{
  NODE *link1 , *link2;
  int I ;linkl = NULL ;
  for( I = 1;I <= 10 ; i++ )
    first insert( &link1,I );
  link2 = revere_ copy(link1);
  print_link(link1);freeJink(linkl);
  print_link(link2);free_link(link2);
}
  这个就是链表的问题了,其实我们知道每天基本上都会有一题链表的题目,所以大家也要准备好把这15分拿走喔。对于链表之前我也有说过了,这里就不再赘述。大家先做好这些填空好,我们一齐来分析讨论。

void first_insert( NODE **p,int v)
{
  NODE *q = (NODE *) malloc( sizeof(NODE));
  q -> va1 = v;__(1)__; *p = __(2)__;
}
  这个函数等于建立一个链表,不过这里最特别的就是用了指向指针的指针。其实也没有什么大不了,因为指针也是变量啊,当然就是有地址嘛!那么我们只是定义另一个指针指向这个指针罢了。利用指针的因素是因为这个函数没有返回值,我们想要返回头地址上去调用那里,就要用到地址传递了。看看第一个空,整个函数的功能是插入一个新结点在链表头,那么填这个空就当然好办啦,就是q->next=*p ,为什么p是地址还要加上*号呢?上面不是说明了这个是指向指针的指针嘛,这里当然就是要取得链表头指针,把链表头链上新的结点。第二个空也实在是太简单了,因为我们是要用返回链表头地指的所以就把新加入的结点变成头结点,即填q就行了。

NODE *reverse_copy(NODE *p)
{
  NODE *u;
  for( u = NULL ; p ; p = p ->next ) first_insert(__(3)__);
  return u;
}
  这个空同样道理,复制一个新的反序链表。因为first_insert()参数是指向指针的形式,所以我们就要用&取地址符把u的地址赋传入函数里了。还有另一个参数是数据,数据就是刚好循环里的p指针的数据。现在可以把这个空也填上了&u,p->val,就这样完成了。

void print_link( NODE *p )
{
  for( ;__(4)__) printf ("%d/t" , p -> val);
  printf("/n");
}
  如果算了链表连这个输出也不会我没有话好说了,答案是p;p=p->next。

void free_link(NODE*p)
{
  NODE *u;
  while( p != NULL){ u=p->next;free( p );__(5)__;}
}

  这个也比较简单的问题,很容易可以看出来,因为链表不能断开,所以删除也要一个一个的按顺序来,不是的话就可以删到中途就往下删不了。一定要一个临时的变量来到保存好链表的完整性才可以完整的删除链表,答案也是很简单p=u就行了。
  虽然说难不难,但是没有搞懂链表的朋友也得借些机会慢慢的体会一下了。如果有什么问题的话可以发E-mail过来,E-mail是zhgpa@sohu.com不过在这里说明我也是初学者,愿和大家共同进步。