• 算法(3)—— 链表习题 完结


    注: 链表有头结点,教科书上的答案会忽略头结点的存在,通过 PrintList  ( List L)就能发现这样的算法存在的问题,解决这个问题需要做两点:(1) 创建节点时候,用 MakeEmpty ( List L ) 创建带头结点的链表; (2) 对链表进行操作的时候,从有数据部分进行操作,即 函数调用参数 为 ( List -> Next)。

    1. 给定两个已经排序好的链表 P 和 L ,求二者的交集。 ( 注意,二者未必长度相等 )

     1 #include <stdio.h>
     2 #include "list.c"
     3 
     4 
     5 List ListJiaoJi (List P, List L)  {
     6   if  (P == NULL || L == NULL )
     7     Error ("Out of space");
     8   Position   Ppos =  First (P);
     9   Position   Lpos =  First (L);
    10   
    11   List R = MakeEmpty (NULL);
    12   Position Rpos = Header(R);
    13  
    14   while ( Ppos != NULL  && Lpos != NULL )  {
    15 
    16     if  ( Retrieve(Ppos) < Retrieve(Lpos) ) 
    17       Ppos = Advance (Ppos);
    18     else
    19       if ( Retrieve(Ppos) > Retrieve (Lpos)) 
    20     Lpos = Advance (Lpos);
    21       else {
    22     Insert ( Retrieve (Lpos),R,Rpos);
    23     Lpos = Advance (Lpos);
    24     Ppos = Advance (Ppos);
    25     Rpos = Advance (Rpos);
    26       }
    27   }
    28   return R;
    29 }
    30 
    31 int main(int argc, char *argv[])   {
    32 
    33   
    34   List L;
    35   Position Lpos;
    36   List P;
    37   Position Ppos;
    38   
    39   int i;
    40   P = MakeEmpty (NULL);
    41   L = MakeEmpty( NULL );
    42 
    43   Ppos = Header( P );
    44   Lpos = Header (L);
    45 
    46   for( i = 0; i < 10; i++ ) {
    47     Insert( i, L, Lpos );
    48   
    49     Lpos = Advance( Lpos );
    50   }
    51   PrintList( L );
    52   
    53   Insert (3,P,Ppos);
    54   Ppos = Advance (Ppos);
    55 
    56   Insert (5,P,Ppos);
    57 
    58   PrintList (P);
    59   List R = MakeEmpty(NULL);
    60   R =  ListJiaoJi (P,L);
    61   PrintList (R);
    62   
    63   return 0;
    64 }
    SamePart.c

    2.给定两个已经排序好的链表  P 和 L, 求两者的并集。 ( 注意,二者长度未必相等 )

     1 #include <stdio.h>
     2 #include "list.c"
     3 
     4 
     5 List ListJiaoJi (List P, List L)  {
     6   if  (P == NULL || L == NULL )
     7         Error ("Out of space");
     8   Position   Ppos =  First (P);
     9   Position   Lpos =  First (L);
    10   
    11   List R = MakeEmpty (NULL);
    12   Position Rpos = Header(R);
    13   //PrintList (R);
    14 
    15   while ( Ppos != NULL  && Lpos != NULL )  {
    16 
    17     if  ( Retrieve(Ppos) < Retrieve(Lpos) )  {
    18       Insert(Retrieve(Ppos),R,Rpos);
    19       Ppos = Advance (Ppos);
    20       Rpos = Advance (Rpos);
    21     }
    22   
    23     else if ( Retrieve(Ppos) > Retrieve (Lpos))  {
    24       Insert ( Retrieve (Lpos),R,Rpos);
    25       Lpos = Advance (Lpos) ;
    26       Rpos = Advance (Rpos);
    27     }
    28 
    29     else {
    30       Insert ( Retrieve (Lpos),R,Rpos);
    31       Lpos = Advance (Lpos);
    32       Ppos = Advance (Ppos);
    33       Rpos = Advance (Rpos);
    34     }
    35   }
    36     
    37   while ( Lpos != NULL)  {  
    38     Insert (Retrieve(Lpos),R,Rpos);
    39     Lpos = Advance  (Lpos);
    40     Rpos = Advance (Rpos);
    41   }
    42 
    43   while ( Ppos != NULL)  {      
    44     Insert  (Retrieve (Ppos),R,Rpos);
    45     Ppos = Advance (Ppos);
    46     Rpos = Advance (Rpos);
    47   }
    48 
    49  
    50   return R;
    51 }
    52 
    53 int main(int argc, char *argv[])   {
    54 
    55   
    56   List L;
    57   Position Lpos;
    58   List P;
    59   Position Ppos;
    60   
    61   int i;
    62   P = MakeEmpty (NULL);
    63   L = MakeEmpty( NULL );
    64 
    65   Ppos = Header( P );
    66   Lpos = Header (L);
    67 
    68   for( i = 0; i < 10; i++ ) {
    69     Insert( i, L, Lpos );
    70   
    71     Lpos = Advance( Lpos );
    72   }
    73   PrintList( L );
    74   
    75   Insert (3,P,Ppos);
    76   Ppos = Advance (Ppos);
    77 
    78   Insert (5,P,Ppos);
    79 
    80   PrintList (P);
    81   List R = MakeEmpty(NULL);
    82   R =  ListJiaoJi (P,L);
    83   PrintList (R);
    84   
    85   return 0;
    86 }
    UnionList.c

    3.不用递归方法,反转链表。

    树上的答案翻转后的链表并没有头结点,我给改进了一下。

     1 #include "list.c"
     2 
     3 
     4 /* 
     5 
     6    NOTE: book's answer will just return cur,if do this, the reverselist will not have a head node ,PrintList will not work as hoped.I think it is wrong.It is my method's (as follow) output:
     7    1 2
     8    2 1
     9    1 2 
    10 */
    11 List ReverseList (List L)  {
    12 
    13   Position pre,cur,nex;
    14 
    15   pre = NULL;
    16   cur = L->Next;
    17   nex = First(L)->Next;
    18   while (nex != NULL )  {
    19     cur-> Next = pre;
    20     pre = cur;
    21     cur = nex;
    22     nex = Advance(nex);
    23   }
    24   cur->Next = pre;       //return cur; 
    25   nex = MakeEmpty (NULL);
    26   nex -> Next = cur;
    27 
    28   return nex;
    29 }
    30 
    31 
    32 
    33 int main()  {
    34   List L = MakeEmpty (NULL);
    35   Position Pos = Header( L);
    36 
    37   Insert (1,L,Pos);
    38   Pos = Advance (Pos);
    39 
    40   Insert (2,L,Pos);
    41 
    42   Pos = Advance (Pos);
    43 
    44   PrintList(L);
    45 
    46   List RL =  MakeEmpty(NULL);
    47   RL = ReverseList (L);
    48   PrintList (RL);
    49 
    50   List RRL = ReverseList(RL);
    51 
    52   PrintList (RRL);
    53 
    54   return 0;
    55 }
    ReverseList.c

    4. 使用递归实现链表的翻转。

     1 #include "list.c"
     2 
     3 List  ReverseList (Position P)  {
     4 
     5   if ( P->Next == NULL )  {
     6      List LR = MakeEmpty (NULL);
     7      LR -> Next = P;
     8      return LR;
     9   }
    10 
    11   List RL = MakeEmpty(NULL);
    12   RL = ReverseList (P->Next);
    13   P->Next->Next = P;
    14   P->Next = NULL;
    15   return RL;
    16 }    
    17 
    18 int main()  {
    19   List L = MakeEmpty (NULL);
    20   Position Pos = Header( L);
    21 
    22   Insert (1,L,Pos);
    23   Pos = Advance (Pos);
    24 
    25   Insert (2,L,Pos);
    26 
    27   Pos = Advance (Pos);
    28 
    29   PrintList(L);
    30 
    31   List RL =  MakeEmpty(NULL);
    32   RL = ReverseList (L->Next);
    33   PrintList (RL);
    34 
    35  
    36 
    37   return 0;
    38 }
    ReviseListRec.c
  • 相关阅读:
    [转载]Oracle查看当前用户权限
    [转载]Oracle查看当前用户权限
    UltraEdit实用技巧
    _splitpath,_makepath分析路径
    [ZT]让你的软件界面更漂亮(1、2)
    [book]程序员修炼之道
    考考你的C++水平
    将*.STL转换成顶点索引格式
    JBuilder 2006 企业完整版
    [book]道法自然
  • 原文地址:https://www.cnblogs.com/hanxinle/p/7414774.html
Copyright © 2020-2023  润新知