╃無名草╃ 发表于 2004-11-28 18:02

《数据结构(c语言版)习题集》算法设计解决方案

<P >说明: <p></p></P>
<P><FONT size=3>1. <FONT face=宋体>本文是对严蔚敏《数据结构</FONT>(c<FONT face=宋体>语言版</FONT>)<FONT face=宋体>习题集》一书中所有算法设计题目的解决方案<p></p></FONT></FONT></P>
<P><FONT size=3>2. <FONT face=宋体>本解答中的所有算法均采用类</FONT>c<FONT face=宋体>语言描述</FONT>,<FONT face=宋体>设计原则为面向交流、面向阅读</FONT>,<FONT face=宋体>作者不保证程序能够上机正常运行</FONT>(<FONT face=宋体>这种保证实际上也没有任何意义</FONT>);<p></p></FONT></P>
<P><FONT size=3>3. <FONT face=宋体>本解答原则上只给出源代码以及必要的注释</FONT>,<FONT face=宋体>对于一些难度较高或思路特殊的题目将给出简要的分析说明</FONT>,<FONT face=宋体>对于作者无法解决的题目将给出必要的讨论</FONT>.<FONT face=宋体>目前尚未解决的题目有</FONT>: 5.20, 10.40;<p></p></FONT></P>
<P><FONT size=3>4. <FONT face=宋体>请读者在自己已经解决了某个题目或进行了充分的思考之后</FONT>,<FONT face=宋体>再参考本解答</FONT>,<FONT face=宋体>以保证复习效果</FONT>;<p></p></FONT></P>
<P><FONT size=3>5. <FONT face=宋体>由于作者水平所限</FONT>,<FONT face=宋体>本解答中一定存在不少这样或者那样的错误和不足</FONT>,<FONT face=宋体>希望读者们在阅读中多动脑、勤思考</FONT>,<FONT face=宋体>争取发现和纠正这些错误</FONT>,<FONT face=宋体>写出更好的算法来</FONT>.<p></p></FONT></P>
<P ><FONT face=宋体>第一章</FONT> <FONT face=宋体>绪论</FONT> <p></p></P>
<P><FONT size=3>1.16 <p></p></FONT></P>
<P><FONT size=3>void print_descending(int x,int y,int z)//<FONT face=宋体>按从大到小顺序输出三个数</FONT></FONT>
<FONT size=3>{
  scanf("%d,%d,%d",&amp;x,&amp;y,&amp;z);
  if(x&lt;y) x&lt;-&gt;y; //&lt;-&gt;</FONT><FONT size=3><FONT face=宋体>为表示交换的双目运算符</FONT>,<FONT face=宋体>以下同</FONT></FONT>
<FONT size=3>  if(y&lt;z) y&lt;-&gt;z;
  if(x&lt;y) x&lt;-&gt;y; //</FONT><FONT face=宋体 size=3>冒泡排序</FONT>
<FONT size=3>  printf("%d %d %d",x,y,z);
}//print_descending <p></p></FONT></P>
<P><FONT size=3>1.17 <p></p></FONT></P>
<P><FONT size=3>Status fib(int k,int m,int &amp;f)//<FONT face=宋体>求</FONT>k<FONT face=宋体>阶斐波那契序列的第</FONT>m<FONT face=宋体>项的值</FONT></FONT><FONT size=3>f
{
  int tempd;
  if(k&lt;2||m&lt;0) return ERROR;
  if(m&lt;k-1) f=0;
  else if (m==k-1) f=1;
  else
  {
    for(i=0;i&lt;=k-2;i++) temp=0;
    temp=1; //<FONT face=宋体>初始化</FONT></FONT>
<FONT size=3>    for(i=k;i&lt;=m;i++) //</FONT><FONT size=3><FONT face=宋体>求出序列第</FONT>k<FONT face=宋体>至第</FONT>m<FONT face=宋体>个元素的值</FONT></FONT>
<FONT size=3>    {
      sum=0;
      for(j=i-k;j&lt;i;j++) sum+=temp;
      temp=sum;
    }
    f=temp;
  }
  return OK;
}//fib
</FONT><FONT size=3><FONT face=宋体>分析</FONT>:<FONT face=宋体>通过保存已经计算出来的结果</FONT>,<FONT face=宋体>此方法的时间复杂度仅为</FONT>O(m^2).<FONT face=宋体>如果采用递归编程</FONT>(<FONT face=宋体>大多数人都会首先想到递归方法</FONT>),<FONT face=宋体>则时间复杂度将高达</FONT>O(k^m). <p></p></FONT></P>
<P><FONT size=3>1.18 <p></p></FONT></P>
<P><FONT size=3>typedef struct{
                    char *sport;
                    enum{male,female} gender;
                    char schoolname; //<FONT face=宋体>校名为</FONT>'A','B','C','D'<FONT face=宋体>或</FONT></FONT><FONT size=3>'E'
                    char *result;
                    int score;
                  } resulttype; <p></p></FONT></P>
<P><FONT size=3>typedef struct{
                    int malescore;
                    int femalescore;
                    int totalscore;
                  } scoretype; <p></p></FONT></P>
<P><FONT size=3>void summary(resulttype result[ ])//<FONT face=宋体>求各校的男女总分和团体总分</FONT>,<FONT face=宋体>假设结果已经储存在</FONT>result[ ]<FONT face=宋体>数组中</FONT></FONT>
<FONT size=3>{
  scoretype score;
  i=0;
  while(result.sport!=NULL)
  {
    switch(result.schoolname)
    {
      case 'A':
        score[ 0 ].totalscore+=result.score;
        if(result.gender==0) score[ 0 ].malescore+=result.score;
        else score[ 0 ].femalescore+=result.score;
        break;
      case 'B':
        score.totalscore+=result.score;
        if(result.gender==0) score.malescore+=result.score;
        else score.femalescore+=result.score;
        break;
      </FONT><FONT size=3><FONT face=宋体>……</FONT>    <FONT face=宋体>……</FONT>    <FONT face=宋体>……</FONT></FONT>
<FONT size=3>    }
    i++</FONT><FONT face=宋体 size=3>;</FONT>
<FONT size=3>  }
  for(i=0;i&lt;5;i++)
  {
    printf("School %d:\n",i);
    printf("Total score of male:%d\n",score.malescore);
    printf("Total score of female:%d\n",score.femalescore);
    printf("Total score of all:%d\n\n",score.totalscore);
  }
}//summary <p></p></FONT></P>
<P><FONT size=3>1.19 <p></p></FONT></P>
<P><FONT size=3>Status algo119(int a)//<FONT face=宋体>求</FONT>i!*2^i<FONT face=宋体>序列的值且不超过</FONT></FONT><FONT size=3>maxint
{
  last=1;
  for(i=1;i&lt;=ARRSIZE;i++)
  {
  a=last*2*i;
   if((a/last)!=(2*i)) reurn OVERFLOW;
   last=a;
   return OK;
  }
}//algo119
<FONT face=宋体>分析</FONT>:<FONT face=宋体>当某一项的结果超过了</FONT>maxint<FONT face=宋体>时</FONT>,<FONT face=宋体>它除以前面一项的商会发生异常</FONT>. <p></p></FONT></P>
<P><FONT size=3>1.20 <p></p></FONT></P>
<P><FONT size=3>void polyvalue()
{
  float ad;
  float *p=a;
  printf("Input number of terms:");
  scanf("%d",&amp;n);
  printf("Input the %d coefficients from a0 to a%d:\n",n,n);
  for(i=0;i&lt;=n;i++) scanf("%f",p++);
  printf("Input value of x:");
  scanf("%f",&amp;x);
  p=a;xp=1;sum=0; //xp<FONT face=宋体>用于存放</FONT>x<FONT face=宋体>的</FONT>i<FONT face=宋体>次方</FONT></FONT>
<FONT size=3>  for(i=0;i&lt;=n;i++)
  {
    sum+=xp*(*p++);
    xp*=x;
  }
  printf("Value is:%f",sum);
}//polyvalue<p></p></FONT></P>
<P ><p><FONT face="Times New Roman"> </FONT></p></P>

╃無名草╃ 发表于 2004-11-28 18:16

<P 0cm 0cm 0pt; TEXT-INDENT: 144pt; mso-char-indent-count: 9.0">第二章 线性表 <p></p></P><P><FONT size=3>2.10 <p></p></FONT></P><P><FONT size=3>Status DeleteK(SqList &amp;a,int i,int k)//<FONT face=宋体>删除线性表</FONT>a<FONT face=宋体>中第</FONT>i<FONT face=宋体>个元素起的</FONT>k<FONT face=宋体>个元素</FONT></FONT>
<FONT size=3>{
  if(i&lt;1||k&lt;0||i+k-1&gt;a.length) return INFEASIBLE;
  for(count=1;i+count-1&lt;=a.length-k;count++) //</FONT><FONT face=宋体 size=3>注意循环结束的条件</FONT>
<FONT size=3>    a.elem=a.elem;
  a.length-=k;
  return OK;
}//DeleteK <p></p></FONT></P><P><FONT size=3>2.11<p></p></FONT></P><P><FONT size=3>Status Insert_SqList(SqList &amp;va,int x)//<FONT face=宋体>把</FONT>x<FONT face=宋体>插入递增有序表</FONT>va<FONT face=宋体>中</FONT></FONT>
<FONT size=3>{
  if(va.length+1&gt;va.listsize) return ERROR;
  va.length++;
  for(i=va.length-1;va.elem&gt;x&amp;&amp;i&gt;=0;i--)
    va.elem=va.elem;
  va.elem=x;
  return OK;
}//Insert_SqList <p></p></FONT></P><P><FONT size=3>2.12 <p></p></FONT></P><P><FONT size=3>int ListComp(SqList A,SqList B)//<FONT face=宋体>比较字符表</FONT>A<FONT face=宋体>和</FONT>B,<FONT face=宋体>并用返回值表示结果</FONT>,<FONT face=宋体>值为正</FONT>,<FONT face=宋体>表示</FONT>A&gt;B;<FONT face=宋体>值为负</FONT>,<FONT face=宋体>表示</FONT>A&lt;B;<FONT face=宋体>值为零</FONT>,<FONT face=宋体>表示</FONT></FONT><FONT size=3>A=B
{
  for(i=1;A.elem||B.elem;i++)
    if(A.elem!=B.elem) return A.elem-B.elem;
  return 0;
}//ListComp <p></p></FONT></P><P><FONT size=3>2.13 <p></p></FONT></P><P><FONT size=3>LNode* Locate(LinkList L,int x)//<FONT face=宋体>链表上的元素查找</FONT>,<FONT face=宋体>返回指针</FONT></FONT>
<FONT size=3>{
  for(p=l-&gt;next;p&amp;&amp;p-&gt;data!=x;p=p-&gt;next);
  return p;
}//Locate <p></p></FONT></P><P><FONT size=3>2.14 <p></p></FONT></P><P><FONT size=3>int Length(LinkList L)//<FONT face=宋体>求链表的长度</FONT></FONT>
<FONT size=3>{
  for(k=0,p=L;p-&gt;next;p=p-&gt;next,k++);
  return k;
}//Length <p></p></FONT></P><P><FONT size=3>2.15 <p></p></FONT></P><P><FONT size=3>void ListConcat(LinkList ha,LinkList hb,LinkList &amp;hc)//<FONT face=宋体>把链表</FONT>hb<FONT face=宋体>接在</FONT>ha<FONT face=宋体>后面形成链表</FONT></FONT><FONT size=3>hc
{
  hc=ha;p=ha;
  while(p-&gt;next) p=p-&gt;next;
  p-&gt;next=hb;
}//ListConcat <p></p></FONT></P><P><FONT size=3>2.16 <p></p></FONT></P><P><FONT size=3><FONT face=宋体>见书后答案</FONT>. <p></p></FONT></P><P><FONT size=3>2.17 <p></p></FONT></P><P><FONT size=3>Status Insert(LinkList &amp;L,int i,int b)//<FONT face=宋体>在无头结点链表</FONT>L<FONT face=宋体>的第</FONT>i<FONT face=宋体>个元素之前插入元素</FONT></FONT><FONT size=3>b
{
  p=L;q=(LinkList*)malloc(sizeof(LNode));
  q.data=b;
  if(i==1)
  {
    q.next=p;L=q; //<FONT face=宋体>插入在链表头部</FONT></FONT>
<FONT size=3>  }
  else
  {
    while(--i&gt;1) p=p-&gt;next;
    q-&gt;next=p-&gt;next;p-&gt;next=q; //</FONT><FONT size=3><FONT face=宋体>插入在第</FONT>i<FONT face=宋体>个元素的位置</FONT></FONT>
<FONT size=3>  }
}//Insert <p></p></FONT></P><P><FONT size=3>2.18 <p></p></FONT></P><P><FONT size=3>Status Delete(LinkList &amp;L,int i)//<FONT face=宋体>在无头结点链表</FONT>L<FONT face=宋体>中删除第</FONT>i<FONT face=宋体>个元素</FONT></FONT>
<FONT size=3>{
  if(i==1) L=L-&gt;next; //</FONT><FONT face=宋体 size=3>删除第一个元素</FONT>
<FONT size=3>  else
  {
    p=L;
    while(--i&gt;1) p=p-&gt;next;
    p-&gt;next=p-&gt;next-&gt;next; //</FONT><FONT size=3><FONT face=宋体>删除第</FONT>i<FONT face=宋体>个元素</FONT></FONT>
<FONT size=3>  }
}//Delete <p></p></FONT></P><P><FONT size=3>2.19 <p></p></FONT></P><P><FONT size=3>Status Delete_Between(Linklist &amp;L,int mink,int maxk)//<FONT face=宋体>删除元素递增排列的链表</FONT>L<FONT face=宋体>中值大于</FONT>mink<FONT face=宋体>且小于</FONT>maxk<FONT face=宋体>的所有元素</FONT></FONT>
<FONT size=3>{
  p=L;
  while(p-&gt;next-&gt;data&lt;=mink) p=p-&gt;next; //p</FONT><FONT size=3><FONT face=宋体>是最后一个不大于</FONT>mink<FONT face=宋体>的元素</FONT></FONT>
<FONT size=3>  if(p-&gt;next)    //</FONT><FONT size=3><FONT face=宋体>如果还有比</FONT>mink<FONT face=宋体>更大的元素</FONT></FONT>
<FONT size=3>  {
    q=p-&gt;next;
    while(q-&gt;data&lt;maxk) q=q-&gt;next; //q</FONT><FONT size=3><FONT face=宋体>是第一个不小于</FONT>maxk<FONT face=宋体>的元素</FONT></FONT>
<FONT size=3>    p-&gt;next=q;
  }
}//Delete_Between <p></p></FONT></P><P><FONT size=3>2.20 <p></p></FONT></P><P><FONT size=3>Status Delete_Equal(Linklist &amp;L)//<FONT face=宋体>删除元素递增排列的链表</FONT>L<FONT face=宋体>中所有值相同的元素</FONT></FONT>
<FONT size=3>{
  p=L-&gt;next;q=p-&gt;next; //p,q</FONT><FONT face=宋体 size=3>指向相邻两元素</FONT>
<FONT size=3>  while(p-&gt;next)
  {
    if(p-&gt;data!=q-&gt;data)
    {
      p=p-&gt;next;q=p-&gt;next; //</FONT><FONT size=3><FONT face=宋体>当相邻两元素不相等时</FONT>,p,q<FONT face=宋体>都向后推一步</FONT></FONT>
<FONT size=3>    }
    else
    {
      while(q-&gt;data==p-&gt;data)
   {
     free(q);
     q=q-&gt;next;
   }
      p-&gt;next=q;p=q;q=p-&gt;next; //</FONT><FONT face=宋体 size=3>当相邻元素相等时删除多余元素</FONT>
<FONT size=3>    }//else
  }//while
}//Delete_Equal <p></p></FONT></P><P><FONT size=3>2.21 <p></p></FONT></P><P><FONT size=3>void reverse(SqList &amp;A)//<FONT face=宋体>顺序表的就地逆置</FONT></FONT>
<FONT size=3>{
  for(i=1,j=A.length;i&lt;j;i++,j--)
    A.elem&lt;-&gt;A.elem;
}//reverse <p></p></FONT></P><P><FONT size=3>2.22 <p></p></FONT></P><P><FONT size=3>void LinkList_reverse(Linklist &amp;L)//<FONT face=宋体>链表的就地逆置</FONT>;<FONT face=宋体>为简化算法</FONT>,<FONT face=宋体>假设表长大于</FONT></FONT><FONT size=3>2
{
  p=L-&gt;next;q=p-&gt;next;s=q-&gt;next;p-&gt;next=NULL;
  while(s-&gt;next)
  {
    q-&gt;next=p;p=q;
    q=s;s=s-&gt;next; //<FONT face=宋体>把</FONT>L<FONT face=宋体>的元素逐个插入新表表头</FONT></FONT>
<FONT size=3>  }
  q-&gt;next=p;s-&gt;next=q;L-&gt;next=s;
}//LinkList_reverse
</FONT><FONT size=3><FONT face=宋体>分析</FONT>:<FONT face=宋体>本算法的思想是</FONT>,<FONT face=宋体>逐个地把</FONT>L<FONT face=宋体>的当前元素</FONT>q<FONT face=宋体>插入新的链表头部</FONT>,p<FONT face=宋体>为新表表头</FONT>. <p></p></FONT></P><P><FONT size=3>2.23 <p></p></FONT></P><P><FONT size=3>void merge1(LinkList &amp;A,LinkList &amp;B,LinkList &amp;C)//<FONT face=宋体>把链表</FONT>A<FONT face=宋体>和</FONT>B<FONT face=宋体>合并为</FONT>C,A<FONT face=宋体>和</FONT>B<FONT face=宋体>的元素间隔排列</FONT>,<FONT face=宋体>且使用原存储空间</FONT></FONT>
<FONT size=3>{
  p=A-&gt;next;q=B-&gt;next;C=A;
  while(p&amp;&amp;q)
  {
    s=p-&gt;next;p-&gt;next=q; //</FONT><FONT size=3><FONT face=宋体>将</FONT>B<FONT face=宋体>的元素插入</FONT></FONT>
<FONT size=3>    if(s)
    {
      t=q-&gt;next;q-&gt;next=s; //</FONT><FONT size=3><FONT face=宋体>如</FONT>A<FONT face=宋体>非空</FONT>,<FONT face=宋体>将</FONT>A<FONT face=宋体>的元素插入</FONT></FONT>
<FONT size=3>    }
    p=s;q=t;
  }//while
}//merge1 <p></p></FONT></P><P><FONT size=3>2.24 <p></p></FONT></P><P><FONT size=3>void reverse_merge(LinkList &amp;A,LinkList &amp;B,LinkList &amp;C)//<FONT face=宋体>把元素递增排列的链表</FONT>A<FONT face=宋体>和</FONT>B<FONT face=宋体>合并为</FONT>C,<FONT face=宋体>且</FONT>C<FONT face=宋体>中元素递减排列</FONT>,<FONT face=宋体>使用原空间</FONT></FONT>
<FONT size=3>{
  pa=A-&gt;next;pb=B-&gt;next;pre=NULL; //pa</FONT><FONT size=3><FONT face=宋体>和</FONT>pb<FONT face=宋体>分别指向</FONT>A,B<FONT face=宋体>的当前元素</FONT></FONT>
<FONT size=3>  while(pa||pb)
  {
    if(pa-&gt;data&lt;pb-&gt;data||!pb)
    {
      pc=pa;q=pa-&gt;next;pa-&gt;next=pre;pa=q; //</FONT><FONT size=3><FONT face=宋体>将</FONT>A<FONT face=宋体>的元素插入新表</FONT></FONT>
<FONT size=3>    }
    else
    {
      pc=pb;q=pb-&gt;next;pb-&gt;next=pre;pb=q; //</FONT><FONT size=3><FONT face=宋体>将</FONT>B<FONT face=宋体>的元素插入新表</FONT></FONT>
<FONT size=3>    }
    pre=pc;
  }
  C=A;A-&gt;next=pc; //</FONT><FONT face=宋体 size=3>构造新表头</FONT>
<FONT size=3>}//reverse_merge
</FONT><FONT size=3><FONT face=宋体>分析</FONT>:<FONT face=宋体>本算法的思想是</FONT>,<FONT face=宋体>按从小到大的顺序依次把</FONT>A<FONT face=宋体>和</FONT>B<FONT face=宋体>的元素插入新表的头部</FONT>pc<FONT face=宋体>处</FONT>,<FONT face=宋体>最后处理</FONT>A<FONT face=宋体>或</FONT>B<FONT face=宋体>的剩余元素</FONT>. <p></p></FONT></P><P><FONT size=3>2.25 <p></p></FONT></P><P><FONT size=3>void SqList_Intersect(SqList A,SqList B,SqList &amp;C)//<FONT face=宋体>求元素递增排列的线性表</FONT>A<FONT face=宋体>和</FONT>B<FONT face=宋体>的元素的交集并存入</FONT>C<FONT face=宋体>中</FONT></FONT>
<FONT size=3>{
  i=1;j=1;k=0;
  while(A.elem&amp;&amp;B.elem)
  {
    if(A.elem&lt;B.elem) i++;
    if(A.elem&gt;B.elem) j++;
    if(A.elem==B.elem)
    {
      C.elem[++k]=A.elem; //</FONT><FONT size=3><FONT face=宋体>当发现了一个在</FONT>A,B<FONT face=宋体>中都存在的元素</FONT></FONT><FONT size=3>,
      i++;j++; //<FONT face=宋体>就添加到</FONT>C<FONT face=宋体>中</FONT></FONT>
<FONT size=3>    }
  }//while
}//SqList_Intersect <p></p></FONT></P><P><FONT size=3>2.26 <p></p></FONT></P><P><FONT size=3>void LinkList_Intersect(LinkList A,LinkList B,LinkList &amp;C)//<FONT face=宋体>在链表结构上重做上题</FONT></FONT>
<FONT size=3>{
  p=A-&gt;next;q=B-&gt;next;
  pc=(LNode*)malloc(sizeof(LNode));
  while(p&amp;&amp;q)
  {
    if(p-&gt;data&lt;q-&gt;data) p=p-&gt;next;
    else if(p-&gt;data&gt;q-&gt;data) q=q-&gt;next;
    else
    {
      s=(LNode*)malloc(sizeof(LNode));
      s-&gt;data=p-&gt;data;
      pc-&gt;next=s;pc=s;
      p=p-&gt;next;q=q-&gt;next;
    }
  }//while
  C=pc;
}//LinkList_Intersect <p></p></FONT></P><P><FONT size=3>2.27 <p></p></FONT></P><P><FONT size=3>void SqList_Intersect_True(SqList &amp;A,SqList B)//<FONT face=宋体>求元素递增排列的线性表</FONT>A<FONT face=宋体>和</FONT>B<FONT face=宋体>的元素的交集并存回</FONT>A<FONT face=宋体>中</FONT></FONT>
<FONT size=3>{
  i=1;j=1;k=0;
  while(A.elem&amp;&amp;B.elem)
  {
    if(A.elem&lt;B.elem) i++;
    else if(A.elem&gt;B.elem) j++;
    else if(A.elem!=A.elem)
    {
      A.elem[++k]=A.elem; //</FONT><FONT size=3><FONT face=宋体>当发现了一个在</FONT>A,B<FONT face=宋体>中都存在的元素</FONT></FONT>
<FONT size=3>      i++;j++; //</FONT><FONT size=3><FONT face=宋体>且</FONT>C<FONT face=宋体>中没有</FONT>,<FONT face=宋体>就添加到</FONT>C<FONT face=宋体>中</FONT></FONT>
<FONT size=3>    }
  }//while
  while(A.elem) A.elem=0;
}//SqList_Intersect_True <p></p></FONT></P><P><FONT size=3>2.28 <p></p></FONT></P><P><FONT size=3>void LinkList_Intersect_True(LinkList &amp;A,LinkList B)//<FONT face=宋体>在链表结构上重做上题</FONT></FONT>
<FONT size=3>{
  p=A-&gt;next;q=B-&gt;next;pc=A;
  while(p&amp;&amp;q)
  {
    if(p-&gt;data&lt;q-&gt;data) p=p-&gt;next;
    else if(p-&gt;data&gt;q-&gt;data) q=q-&gt;next;
    else if(p-&gt;data!=pc-&gt;data)
    {
      pc=pc-&gt;next;
      pc-&gt;data=p-&gt;data;
      p=p-&gt;next;q=q-&gt;next;
    }
  }//while
}//LinkList_Intersect_True <p></p></FONT></P><P><FONT size=3>2.29 <p></p></FONT></P><P><FONT size=3>void SqList_Intersect_Delete(SqList &amp;A,SqList B,SqList C)
{
  i=0;j=0;k=0;m=0;    //i<FONT face=宋体>指示</FONT>A<FONT face=宋体>中元素原来的位置</FONT>,m<FONT face=宋体>为移动后的位置</FONT></FONT>
<FONT size=3>  while(i&lt;A.length&amp;&amp;j&lt;B.length&amp;&amp; k&lt;C.length)
  {
    if(B.elem&lt;C.elem) j++;
    else if(B.elem&gt;C.elem) k++;
    else
    {
      same=B.elem;                   //</FONT><FONT face=宋体 size=3>找到了相同元素</FONT><FONT size=3>same
      while(B.elem==same) j++;
      while(C.elem==same) k++;     //j,k<FONT face=宋体>后移到新的元素</FONT></FONT>
<FONT size=3>      while(i&lt;A.length&amp;&amp;A.elem&lt;same)
        A.elem=A.elem;            //</FONT><FONT face=宋体 size=3>需保留的元素移动到新位置</FONT>
<FONT size=3>      while(i&lt;A.length&amp;&amp;A.elem==same) i++;       //</FONT><FONT face=宋体 size=3>跳过相同的元素</FONT>
<FONT size=3>    }
  }//while
  while(i&lt;A.length)
    A.elem=A.elem;      //A</FONT><FONT face=宋体 size=3>的剩余元素重新存储。</FONT>
<FONT size=3>  A.length=m;
}// SqList_Intersect_Delete
</FONT><FONT size=3><FONT face=宋体>分析</FONT>:<FONT face=宋体>先从</FONT>B<FONT face=宋体>和</FONT>C<FONT face=宋体>中找出共有元素</FONT>,<FONT face=宋体>记为</FONT>same,<FONT face=宋体>再在</FONT>A<FONT face=宋体>中从当前位置开始</FONT>, <FONT face=宋体>凡小于</FONT>same<FONT face=宋体>的</FONT></FONT>
<FONT size=3><FONT face=宋体>元素均保留</FONT>(<FONT face=宋体>存到新的位置</FONT>),<FONT face=宋体>等于</FONT>same<FONT face=宋体>的就跳过</FONT>,<FONT face=宋体>到大于</FONT>same<FONT face=宋体>时就再找下一个</FONT>same. <p></p></FONT></P><P><FONT size=3>2.30 <p></p></FONT></P><P><FONT size=3>void LinkList_Intersect_Delete(LinkList &amp;A,LinkList B,LinkList C)//<FONT face=宋体>在链表结构上重做上题</FONT></FONT>
<FONT size=3>{
  p=B-&gt;next;q=C-&gt;next;r=A-next;
  while(p&amp;&amp;q&amp;&amp;r)
  {
    if(p-&gt;data&lt;q-&gt;data) p=p-&gt;next;
    else if(p-&gt;data&gt;q-&gt;data) q=q-&gt;next;
    else
    {
      u=p-&gt;data; //</FONT><FONT face=宋体 size=3>确定待删除元素</FONT><FONT size=3>u
      while(r-&gt;next-&gt;data&lt;u) r=r-&gt;next; //<FONT face=宋体>确定最后一个小于</FONT>u<FONT face=宋体>的元素指针</FONT></FONT><FONT size=3>r
      if(r-&gt;next-&gt;data==u)
      {
        s=r-&gt;next;
        while(s-&gt;data==u)
        {
          t=s;s=s-&gt;next;free(t); //<FONT face=宋体>确定第一个大于</FONT>u<FONT face=宋体>的元素指针</FONT></FONT><FONT size=3>s
        }//while
        r-&gt;next=s; //<FONT face=宋体>删除</FONT>r<FONT face=宋体>和</FONT>s<FONT face=宋体>之间的元素</FONT></FONT>
<FONT size=3>      }//if
      while(p-&gt;data=u) p=p-&gt;next;
      while(q-&gt;data=u) q=q-&gt;next;
    }//else
  }//while
}//LinkList_Intersect_Delete <p></p></FONT></P><P><FONT size=3>2.31 <p></p></FONT></P><P><FONT size=3>Status Delete_Pre(CiLNode *s)//<FONT face=宋体>删除单循环链表中结点</FONT>s<FONT face=宋体>的直接前驱</FONT></FONT>
<FONT size=3>{
  p=s;
  while(p-&gt;next-&gt;next!=s) p=p-&gt;next; //</FONT><FONT size=3><FONT face=宋体>找到</FONT>s<FONT face=宋体>的前驱的前驱</FONT></FONT><FONT size=3>p
  p-&gt;next=s;
  return OK;
}//Delete_Pre <p></p></FONT></P><P><FONT size=3>2.32 <p></p></FONT></P><P><FONT size=3>Status DuLNode_Pre(DuLinkList &amp;L)//<FONT face=宋体>完成双向循环链表结点的</FONT>pre<FONT face=宋体>域</FONT></FONT>
<FONT size=3>{
  for(p=L;!p-&gt;next-&gt;pre;p=p-&gt;next) p-&gt;next-&gt;pre=p;
  return OK;
}//DuLNode_Pre <p></p></FONT></P><P><FONT size=3>2.33 <p></p></FONT></P><P><FONT size=3>Status LinkList_Divide(LinkList &amp;L,CiList &amp;A,CiList &amp;B,CiList &amp;C)//<FONT face=宋体>把单链表</FONT>L<FONT face=宋体>的元素按类型分为三个循环链表</FONT>.CiList<FONT face=宋体>为带头结点的单循环链表类型</FONT></FONT><FONT size=3>.
{
  s=L-&gt;next;
  A=(CiList*)malloc(sizeof(CiLNode));p=A;
  B=(CiList*)malloc(sizeof(CiLNode));q=B;
  C=(CiList*)malloc(sizeof(CiLNode));r=C; //<FONT face=宋体>建立头结点</FONT></FONT>
<FONT size=3>  while(s)
  {
    if(isalphabet(s-&gt;data))
    {
      p-&gt;next=s;p=s;
    }
    else if(isdigit(s-&gt;data))
    {
      q-&gt;next=s;q=s;
    }
    else
    {
      r-&gt;next=s;r=s;
    }
  }//while
  p-&gt;next=A;q-&gt;next=B;r-&gt;next=C; //</FONT><FONT face=宋体 size=3>完成循环链表</FONT>
<FONT size=3>}//LinkList_Divide <p></p></FONT></P><P><FONT size=3>2.34 <p></p></FONT></P><P><FONT size=3>void Print_XorLinkedList(XorLinkedList L)//<FONT face=宋体>从左向右输出异或链表的元素值</FONT></FONT>
<FONT size=3>{
  p=L.left;pre=NULL;
  while(p)
  {
    printf("%d",p-&gt;data);
    q=XorP(p-&gt;LRPtr,pre);
    pre=p;p=q; //</FONT><FONT size=3><FONT face=宋体>任何一个结点的</FONT>LRPtr<FONT face=宋体>域值与其左结点指针进行异或运算即得到其右结点指针</FONT></FONT>
<FONT size=3>  }
}//Print_XorLinkedList <p></p></FONT></P><P><FONT size=3>2.35 <p></p></FONT></P><P><FONT size=3>Status Insert_XorLinkedList(XorLinkedList &amp;L,int x,int i)//<FONT face=宋体>在异或链表</FONT>L<FONT face=宋体>的第</FONT>i<FONT face=宋体>个元素前插入元素</FONT></FONT><FONT size=3>x
{
  p=L.left;pre=NULL;
  r=(XorNode*)malloc(sizeof(XorNode));
  r-&gt;data=x;
  if(i==1) //<FONT face=宋体>当插入点在最左边的情况</FONT></FONT>
<FONT size=3>  {
    p-&gt;LRPtr=XorP(p.LRPtr,r);
    r-&gt;LRPtr=p;
    L.left=r;
    return OK;
  }
  j=1;q=p-&gt;LRPtr; //</FONT><FONT face=宋体 size=3>当插入点在中间的情况</FONT>
<FONT size=3>  while(++j&lt;i&amp;&amp;q)
  {
    q=XorP(p-&gt;LRPtr,pre);
    pre=p;p=q;
  }//while //</FONT><FONT size=3><FONT face=宋体>在</FONT>p,q<FONT face=宋体>两结点之间插入</FONT></FONT>
<FONT size=3>  if(!q) return INFEASIBLE; //i</FONT><FONT face=宋体 size=3>不可以超过表长</FONT>
<FONT size=3>  p-&gt;LRPtr=XorP(XorP(p-&gt;LRPtr,q),r);
  q-&gt;LRPtr=XorP(XorP(q-&gt;LRPtr,p),r);
  r-&gt;LRPtr=XorP(p,q); //</FONT><FONT face=宋体 size=3>修改指针</FONT>
<FONT size=3>  return OK;
}//Insert_XorLinkedList <p></p></FONT></P><P><FONT size=3>2.36 <p></p></FONT></P><P><FONT size=3>Status Delete_XorLinkedList(XorlinkedList &amp;L,int i)//<FONT face=宋体>删除异或链表</FONT>L<FONT face=宋体>的第</FONT>i<FONT face=宋体>个元素</FONT></FONT>
<FONT size=3>{
  p=L.left;pre=NULL;
  if(i==1) //</FONT><FONT face=宋体 size=3>删除最左结点的情况</FONT>
<FONT size=3>  {
    q=p-&gt;LRPtr;
    q-&gt;LRPtr=XorP(q-&gt;LRPtr,p);
    L.left=q;free(p);
    return OK;
  }
  j=1;q=p-&gt;LRPtr;
  while(++j&lt;i&amp;&amp;q)
  {
    q=XorP(p-&gt;LRPtr,pre);
    pre=p;p=q;
  }//while //</FONT><FONT face=宋体 size=3>找到待删结点</FONT><FONT size=3>q
  if(!q) return INFEASIBLE; //i<FONT face=宋体>不可以超过表长</FONT></FONT>
<FONT size=3>  if(L.right==q) //q</FONT><FONT face=宋体 size=3>为最右结点的情况</FONT>
<FONT size=3>  {
    p-&gt;LRPtr=XorP(p-&gt;LRPtr,q);
    L.right=p;free(q);
    return OK;
  }
  r=XorP(q-&gt;LRPtr,p); //q</FONT><FONT size=3><FONT face=宋体>为中间结点的情况</FONT>,<FONT face=宋体>此时</FONT>p,r<FONT face=宋体>分别为其左右结点</FONT></FONT>
<FONT size=3>  p-&gt;LRPtr=XorP(XorP(p-&gt;LRPtr,q),r);
  r-&gt;LRPtr=XorP(XorP(r-&gt;LRPtr,q),p); //</FONT><FONT face=宋体 size=3>修改指针</FONT>
<FONT size=3>  free(q);
  return OK;
}//Delete_XorLinkedList <p></p></FONT></P><P><FONT size=3>2.37 <p></p></FONT></P><P><FONT size=3>void OEReform(DuLinkedList &amp;L)//<FONT face=宋体>按</FONT>1,3,5,...4,2<FONT face=宋体>的顺序重排双向循环链表</FONT>L<FONT face=宋体>中的所有结点</FONT></FONT>
<FONT size=3>{
  p=L.next;
  while(p-&gt;next!=L&amp;&amp;p-&gt;next-&gt;next!=L)
  {
    p-&gt;next=p-&gt;next-&gt;next;
    p=p-&gt;next;
  } //</FONT><FONT size=3><FONT face=宋体>此时</FONT>p<FONT face=宋体>指向最后一个奇数结点</FONT></FONT>
<FONT size=3>  if(p-&gt;next==L) p-&gt;next=L-&gt;pre-&gt;pre;
  else p-&gt;next=l-&gt;pre;
  p=p-&gt;next; //</FONT><FONT size=3><FONT face=宋体>此时</FONT>p<FONT face=宋体>指向最后一个偶数结点</FONT></FONT>
<FONT size=3>  while(p-&gt;pre-&gt;pre!=L)
  {
    p-&gt;next=p-&gt;pre-&gt;pre;
    p=p-&gt;next;
  }
  p-&gt;next=L; //</FONT><FONT size=3><FONT face=宋体>按题目要求调整了</FONT>next<FONT face=宋体>链的结构</FONT>,<FONT face=宋体>此时</FONT>pre<FONT face=宋体>链仍为原状</FONT></FONT>
<FONT size=3>  for(p=L;p-&gt;next!=L;p=p-&gt;next) p-&gt;next-&gt;pre=p;
  L-&gt;pre=p; //</FONT><FONT size=3><FONT face=宋体>调整</FONT>pre<FONT face=宋体>链的结构</FONT>,<FONT face=宋体>同</FONT>2.32<FONT face=宋体>方法</FONT></FONT>
<FONT size=3>}//OEReform
</FONT><FONT size=3><FONT face=宋体>分析</FONT>:next<FONT face=宋体>链和</FONT>pre<FONT face=宋体>链的调整只能分开进行</FONT>.<FONT face=宋体>如同时进行调整的话</FONT>,<FONT face=宋体>必须使用堆栈保存偶数结点的指针</FONT>,<FONT face=宋体>否则将会破坏链表结构</FONT>,<FONT face=宋体>造成结点丢失</FONT>. <p></p></FONT></P><P><FONT size=3>2.38 <p></p></FONT></P><P><FONT size=3>DuLNode * Locate_DuList(DuLinkedList &amp;L,int x)//<FONT face=宋体>带</FONT>freq<FONT face=宋体>域的双向循环链表上的查找</FONT></FONT>
<FONT size=3>{
  p=L.next;
  while(p.data!=x&amp;&amp;p!=L) p=p-&gt;next;
  if(p==L) return NULL; //</FONT><FONT face=宋体 size=3>没找到</FONT>
<FONT size=3>  p-&gt;freq++;q=p-&gt;pre;
  while(q-&gt;freq&lt;=p-&gt;freq) q=q-&gt;pre; //</FONT><FONT face=宋体 size=3>查找插入位置</FONT>
<FONT size=3>  if(q!=p-&gt;pre)
  {
    p-&gt;pre-&gt;next=p-&gt;next;p-&gt;next-&gt;pre=p-&gt;pre;
    q-&gt;next-&gt;pre=p;p-&gt;next=q-&gt;next;
    q-&gt;next=p;p-&gt;pre=q; //</FONT><FONT face=宋体 size=3>调整位置</FONT>
<FONT size=3>  }
  return p;
}//Locate_DuList <p></p></FONT></P><P><FONT size=3>2.39 <p></p></FONT></P><P><FONT size=3>float GetValue_SqPoly(SqPoly P,int x0)//<FONT face=宋体>求升幂顺序存储的稀疏多项式的值</FONT></FONT>
<FONT size=3>{
  PolyTerm *q;
  xp=1;q=P.data;
  sum=0;ex=0;
  while(q-&gt;coef)
  {
    while(ex&lt;q-&gt;exp) xp*=x0;
    sum+=q-&gt;coef*xp;
    q++;
  }
  return sum;
}//GetValue_SqPoly <p></p></FONT></P><P><FONT size=3>2.40 <p></p></FONT></P><P><FONT size=3>void Subtract_SqPoly(SqPoly P1,SqPoly P2,SqPoly &amp;P3)//<FONT face=宋体>求稀疏多项式</FONT>P1<FONT face=宋体>减</FONT>P2<FONT face=宋体>的差式</FONT></FONT><FONT size=3>P3
{
  PolyTerm *p,*q,*r;
  Create_SqPoly(P3); //<FONT face=宋体>建立空多项式</FONT></FONT><FONT size=3>P3
  p=P1.data;q=P2.data;r=P3.data;
  while(p-&gt;coef&amp;&amp;q-&gt;coef)
  {
    if(p-&gt;exp&lt;q-&gt;exp)
    {
      r-&gt;coef=p-&gt;coef;
      r-&gt;exp=p-&gt;exp;
      p++;r++;
    }
    else if(p-&gt;exp&lt;q-&gt;exp)
    {
      r-&gt;coef=-q-&gt;coef;
      r-&gt;exp=q-&gt;exp;
      q++;r++;
    }
    else
    {
      if((p-&gt;coef-q-&gt;coef)!=0) //<FONT face=宋体>只有同次项相减不为零时才需要存入</FONT>P3<FONT face=宋体>中</FONT></FONT>
<FONT size=3>      {
        r-&gt;coef=p-&gt;coef-q-&gt;coef;
        r-&gt;exp=p-&gt;exp;r++;
      }//if
      p++;q++;
    }//else
  }//while
  while(p-&gt;coef) //</FONT><FONT size=3><FONT face=宋体>处理</FONT>P1<FONT face=宋体>或</FONT>P2<FONT face=宋体>的剩余项</FONT></FONT>
<FONT size=3>  {
    r-&gt;coef=p-&gt;coef;
    r-&gt;exp=p-&gt;exp;
    p++;r++;
  }
  while(q-&gt;coef)
  {
    r-&gt;coef=-q-&gt;coef;
    r-&gt;exp=q-&gt;exp;
    q++;r++;
  }
}//Subtract_SqPoly <p></p></FONT></P><P><FONT size=3>2.41 <p></p></FONT></P><P><FONT size=3>void QiuDao_LinkedPoly(LinkedPoly &amp;L)//<FONT face=宋体>对有头结点循环链表结构存储的稀疏多项式</FONT>L<FONT face=宋体>求导</FONT></FONT>
<FONT size=3>{
  p=L-&gt;next;
  if(!p-&gt;data.exp)
  {
    L-&gt;next=p-&gt;next;p=p-&gt;next; //</FONT><FONT face=宋体 size=3>跳过常数项</FONT>
<FONT size=3>  }
  while(p!=L)
  {
    p-&gt;data.coef*=p-&gt;data.exp--;//</FONT><FONT face=宋体 size=3>对每一项求导</FONT>
<FONT size=3>    p=p-&gt;next;
  }
}//QiuDao_LinkedPoly <p></p></FONT></P><P><FONT size=3>2.42 <p></p></FONT></P><P><FONT size=3>void Divide_LinkedPoly(LinkedPoly &amp;L,&amp;A,&amp;B)//<FONT face=宋体>把循环链表存储的稀疏多项式</FONT>L<FONT face=宋体>拆成只含奇次项的</FONT>A<FONT face=宋体>和只含偶次项的</FONT></FONT><FONT size=3>B
{
  p=L-&gt;next;
  A=(PolyNode*)malloc(sizeof(PolyNode));
  B=(PolyNode*)malloc(sizeof(PolyNode));
  pa=A;pb=B;
  while(p!=L)
  {
    if(p-&gt;data.exp!=2*(p-&gt;data.exp/2))
    {
      pa-&gt;next=p;pa=p;
    }
    else
    {
      pb-&gt;next=p;pb=p;
    }
    p=p-&gt;next;
  }//while
  pa-&gt;next=A;pb-&gt;next=B;
}//Divide_LinkedPoly<p></p></FONT></P>

布赖 发表于 2004-12-18 00:28

<P>很长呀</P><P>不过还是十分感谢</P>

铜豆子 发表于 2007-6-20 21:54

不是实习题的答案啊
页: [1]
查看完整版本: 《数据结构(c语言版)习题集》算法设计解决方案