LinkedList Union (LinkedList la, lb) ∥la,lb分别是带头结点的两个单链表的头指针,链表中的元素值按递增序排列,本算法 将两链表合并成一个按元素值递减次序排列的单链表 (pa=1a->next;pb=1b->next;∥pa,pb分别是链表la和1b的工作指针 la->next=null ∥1a作结果链表的头指针,先将结果链表初始化为 Whie(pa!=null&&pb!=nu1)∥当两链表均不为空时作 if(pa->data<=pb->data) i r=pa->next ∥将pa的后继结点暂存于r pa->next=1a->next;∥将pa结点链于结果表中,同时逆置。 Ia->next=pa ∥恢复pa为当前待比较结点。 else r=pb->next;∥将pb的后继结点暂存于r pb->next=1a->next;∥将pb结点链于结果表中,同时逆置 pb=r;∥恢复pb为当前待比较结点 while(pa!=null)∥将la表的剩余部分链入结果表,并逆置。 [r=pa>next: pa->next=la->next: la->next [r=pb->next: pb->next=la->next: la->next=pb; pb=r }∥算法 Union结束 [算法讨论]上面两链表均不为空的表达式也可简写为 while(pa&kpb),两递增有序表 合并成递减有序表时,上述算法是边合并边逆置。也可先合并完,再作链表逆置。后者不如 前者优化。算法中最后两个 while语句,不可能执行两个,只能二者取一,即哪个表尚未到 尾,就将其逆置到结果表中,即将剩余结点依次前插入到结果表的头结点后面。 与本题类似的其它题解答如下: (1)[问题分析]与上题类似,不同之处在于:一是链表无头结点,为处理方便,给 加上头结点,处理结束再删除之;二是数据相同的结点,不合并到结果链表中;三是hb链 表不能被破坏,即将hb的结点合并到结果链表时,要生成新结点。 LinkedList Union(LinkedList ha, hb) ∥ha和hb是两个无头结点的数据域值递增有序的单链表,本算法将hb中并不出现在ha 中的数据合并到ha中,合并中不能破坏hb链表。 (LinkedList la a=(LinkedList)malloc(sizeof (LNode)) la->next=ha;∥申请头结点,以便操作。 ∥pa是ha链表的工作指针 ∥pb是hb链表的工作指针 pre=la ∥pre指向当前待合并结点的前驱。 while(pa&&pb) if(pa-data<pb->data)∥处理ha中数据 Ipre->next=pa: pre=pa; pa=pa-next: K
LinkedList Union(LinkedList la,lb) ∥la,lb 分别是带头结点的两个单链表的头指针,链表中的元素值按递增序排列,本算法 将两链表合并成一个按元素值递减次序排列的单链表。 { pa=la->next; pb=lb->next;∥pa,pb 分别是链表 la 和 lb 的工作指针 la->next=null; ∥la 作结果链表的头指针,先将结果链表初始化为 空。 while(pa!=null && pb!=null) ∥当两链表均不为空时作 if(pa->data<=pb->data) { r=pa->next; ∥将 pa 的后继结点暂存于 r。 pa->next=la->next; ∥将 pa 结点链于结果表中,同时逆置。 la->next=pa; pa=r; ∥恢复 pa 为当前待比较结点。 } else {r=pb->next;∥ 将 pb 的后继结点暂存于 r。 pb->next=la->next; ∥将 pb 结点链于结果表中,同时逆置。 la->next=pb; pb=r; ∥恢复 pb 为当前待比较结点。 } while(pa!=null) ∥将 la 表的剩余部分链入结果表,并逆置。 {r=pa->next; pa->next=la->next; la->next=pa; pa=r; } while(pb!=null) {r=pb->next; pb->next=la->next; la->next=pb; pb=r; } }∥算法 Union 结束。 [算法讨论]上面两链表均不为空的表达式也可简写为 while(pa&&pb),两递增有序表 合并成递减有序表时,上述算法是边合并边逆置。也可先合并完,再作链表逆置。后者不如 前者优化。算法中最后两个 while 语句,不可能执行两个,只能二者取一,即哪个表尚未到 尾,就将其逆置到结果表中,即将剩余结点依次前插入到结果表的头结点后面。 与本题类似的其它题解答如下: (1)[问题分析]与上题类似,不同之处在于:一是链表无头结点,为处理方便,给 加上头结点,处理结束再删除之;二是数据相同的结点,不合并到结果链表中;三是 hb 链 表不能被破坏,即将 hb 的结点合并到结果链表时,要生成新结点。 LinkedList Union(LinkedList ha, hb) ∥ha 和 hb 是两个无头结点的数据域值递增有序的单链表,本算法将 hb 中并不出现在 ha 中的数据合并到 ha 中,合并中不能破坏 hb 链表。 {LinkedList la; la=(LinkedList)malloc(sizeof(LNode)); la->next=ha;∥申请头结点,以便操作。 pa=ha; ∥pa 是 ha 链表的工作指针 pb=hb; ∥pb 是 hb 链表的工作指针 pre=la; ∥pre 指向当前待合并结点的前驱。 while(pa&&pb) if(pa->data<pb->data)∥处理 ha 中数据 {pre->next=pa;pre=pa;pa=pa->next;}
else if(pa->data>pb->data)∥处理hb中数据 r=( Linkedlist) malloc( sizeof( L Node);∥/申请空间 r->data=pb->data; pre->next=r pre=r;∥将新结点链入结果链表 pb=pb->next;∥hb链表中工作指针后移 else∥/处理pa->data=pb->dat ipre->next=pa: pre=pa pa=pa->next;∥两结点数据相等时,只将ha的数据链入。 pb=pb->next;∥不要hb的相等数据 if(pa!=null)pre->next=pa;∥将两链表中剩余部分链入结果链表 free(la);∥释放头结点.ha,hb指针未被破坏 }∥算法nion结束 2)本题与上面两题类似,要求结果指针为lc,其核心语句段如下: pa=la->next: pb=hb->next Ic=(LinkedList )malloc(sizeof(LNode)) pc=lc;∥pc是结果链表中当前结点的前驱 while(pa&&pb) if(pa->data<pb->data) Ipc->next=pa: pc=pa; pa=pa->next: I else [pc->next=pb; pc=pb; pb=pb->next: 1 if(pa)pc->next=pa; else pc->next=pb free(la);free(lb);∥释放原来两链表的头结点。 算法时间复杂度为0(m+n),其中m和n分别为链表1a和1b的长度。 2.[题目分析]本组题有6个,本质上都是链表的合并操作,合并中有各种条件。与前 组题不同的是,叙述上是用线性表代表集合,而操作则是求集合的并、交、差(AUB,A ∩B,A-B)等。 本题与上面1.(2)基本相同,不同之处1.(2)中链表是“非递减有序”,(可能包含 相等元素),本题是元素“递增有序”(不准有相同元素)。因此两表中合并时,如有元素值 相等元素,则应删掉一个。 LinkedList Union (LinkedList ha, hb) ∥线性表A和B代表两个集合,以链式存储结构存储,元素递增有序。ha和hb分别 是其链表的头指针。本算法求A和B的并集AUB,仍用线性表表示,结果链表元 素也是递增有序。 pa=ha->next;pb=hb->next;∥设工作指针pa和pb pc=ha;∥pc为结果链表当前结点的前驱指针 while(pa&&pb) if(pa->data<pb->data) (pc->next=pa: pc=pa; pa=pa->next: I lse if(pa->data>pb->data) Ipc->next=pb; pc=pb; pb=pb->next: I else∥处理pa-data=pb->data
else if(pa->data>pb->data)∥处理 hb 中数据。 {r=(LinkedList)malloc(sizeof(LNode));∥申请空间 r->data=pb->data; pre->next=r; pre=r;∥将新结点链入结果链表。 pb=pb->next;∥hb 链表中工作指针后移。 } else∥处理 pa->data=pb->data; {pre->next=pa; pre=pa; pa=pa->next;∥两结点数据相等时,只将 ha 的数据链入。 pb=pb->next;∥不要 hb 的相等数据 } if(pa!=null)pre->next=pa;∥将两链表中剩余部分链入结果链表。 else pre->next=pb; free(la);∥释放头结点.ha,hb 指针未被破坏。 }∥算法 nion 结束。 (2)本题与上面两题类似,要求结果指针为 lc,其核心语句段如下: pa=la->next;pb=hb->next; lc=(LinkedList )malloc(sizeof(LNode)); pc=lc;∥pc 是结果链表中当前结点的前驱 while(pa&&pb) if(pa->data<pb->data) {pc->next=pa;pc=pa;pa=pa->next;} else {pc->next=pb;pc=pb;pb=pb->next;} if(pa)pc->next=pa; else pc->next=pb; free(la);free(lb);∥释放原来两链表的头结点。 算法时间复杂度为 O(m+n),其中 m 和 n 分别为链表 la 和 lb 的长度。 2.[题目分析]本组题有 6 个,本质上都是链表的合并操作,合并中有各种条件。与前 组题不同的是,叙述上是用线性表代表集合,而操作则是求集合的并、交、差(A∪B,A ∩B,A-B)等。 本题与上面 1.(2)基本相同,不同之处 1.(2)中链表是“非递减有序”,(可能包含 相等元素),本题是元素“递增有序”(不准有相同元素)。因此两表中合并时,如有元素值 相等元素,则应删掉一个。 LinkedList Union(LinkedList ha,hb) ∥线性表 A 和 B 代表两个集合,以链式存储结构存储,元素递增有序。ha 和 hb 分别 是其链表的头指针。本算法求 A 和 B 的并集 A∪B,仍用线性表表示,结果链表元 素也是递增有序。 { pa=ha->next;pb=hb->next;∥设工作指针 pa 和 pb。 pc=ha;∥pc 为结果链表当前结点的前驱指针。 while(pa&&pb) if(pa->data<pb->data) {pc->next=pa;pc=pa;pa=pa->next;} else if(pa->data>pb->data) {pc->next=pb;pc=pb;pb=pb->next;} else∥处理 pa->data=pb->data
Ipc->next=pa: pc=pa: pa=pa->next: >next: free(u): h if(pa)pc->next=pa;∥若ha表未空,则链入结果表 else pc->next=pb;∥若hb表未空,则链入结果表。 free(hb);∥释放hb头结点 return(ha) }∥算法 Union结束 与本题类似的其它几个题解答如下 (1)解答完全同上2。 (2)本题是求交集,即只有同时出现在两集合中的元素才出现在结果表中。其核心语句 段如下: pa=la->next;pb=1b->next;∥设工作指针pa和pb; pc=la;∥结果表中当前合并结点的前驱的指针。 if(pa->data==pb->data)∥交集并入结果表中 i pc->next=pa: pc=pa: pa=pa->next u=pb: pb=pb->next; free(u): 1 lse if(pa->datapb->data)fu u);} free(u): I whie(pa){u=pa;pa=pa->next;free(u);}∥释放结点空间 while(pb){u=pb;pb=pb->next;free(u);}∥释放结点空间 pc->next=nu1l;∥置链表尾标记 free(b);∥注:本算法中也可对B表不作释放空间的处理 (3)本题基本与(2)相同,但要求无重复元素,故在算法中,待合并结点数据要与其前 驱比较,只有在与前驱数据不同时才并入链表。其核心语句段如下。 pa=L1-next;pb=L2->next;∥pa、pb是两链表的工作指针 pc=L1;∥L1作结果链表的头指针 while(pa&&pl f(pa->data<pb->data){u=pa;pa=pa->next;free(u);}∥删除L1表多余元素 else if(pa->data>pb->data)pb=pb-next;∥pb指针后移 else∥处理交集元素 {if(pc=L1){pc-next=pa;pc=pa;pa=pa->next;}∥处理第一个相等的元 else if(pc-data=pa->data){u=pa;pa=pa->next;free(u);}∥重复元 素不进入L1表。 lse{pc->next=pa;pc=pa;pa=pa->next;}∥交集元素并入结果表 ∥ while while(pa){u=pa;pa=pa->next;free(u);}∥删L1表剩余元素 pc->next=null;∥置结果链表尾 注:本算法中对L2表未作释放空间的处理 (4)本题与上面(3)算法相同,只是结果表要另辟空间。 (5)[题目分析]本题首先求B和C的交集,即求B和C中共有元素,再与A求并集,同 时删除重复元素,以保持结果A递增。 LinkedList union (LinkedList A, B, C)
{pc->next=pa;pc=pa;pa=pa->next; u=pb;pb=pb->next;free(u);} if(pa) pc->next=pa;∥ 若 ha 表未空,则链入结果表。 else pc->next=pb;∥若 hb 表未空,则链入结果表。 free(hb); ∥释放 hb 头结点 return(ha); }∥算法 Union 结束。 与本题类似的其它几个题解答如下: (1) 解答完全同上 2。 (2) 本题是求交集,即只有同时出现在两集合中的元素才出现在结果表中。其核心语句 段如下: pa=la->next;pb=lb->next;∥设工作指针 pa 和 pb; pc=la;∥结果表中当前合并结点的前驱的指针。 while(pa&&pb) if(pa->data==pb->data)∥交集并入结果表中。 { pc->next=pa;pc=pa;pa=pa->next; u=pb;pb=pb->next;free(u);} else if(pa->data<pb->data) {u=pa;pa=pa->next;free(u);} else {u=pb; pb=pb->next; free(u);} while(pa){ u=pa; pa=pa->next; free(u);}∥ 释放结点空间 while(pb) {u=pb; pb=pb->next; free(u);}∥释放结点空间 pc->next=null;∥置链表尾标记。 free(lb); ∥注: 本算法中也可对 B 表不作释放空间的处理 (3)本题基本与(2)相同,但要求无重复元素,故在算法中,待合并结点数据要与其前 驱比较,只有在与前驱数据不同时才并入链表。其核心语句段如下。 pa=L1->next;pb=L2->next;∥pa、pb 是两链表的工作指针。 pc=L1;∥L1 作结果链表的头指针。 while(pa&&pb) if(pa->data<pb->data) {u=pa;pa=pa->next;free(u);}∥删除 L1 表多余元素 else if (pa->data>pb->data) pb=pb->next; ∥pb 指针后移 else ∥处理交集元素 {if(pc==L1) {pc->next=pa;pc=pa;pa=pa->next;} ∥处理第一个相等的元 素。 else if(pc->data==pa->data){ u=pa;pa=pa->next;free(u);} ∥重复元 素不进入 L1 表。 else{ pc->next=pa;pc=pa;pa=pa->next;} ∥交集元素并入结果表。 } ∥while while(pa) {u=pa;pa=pa->next;free(u);} ∥ 删 L1 表剩余元素 pc->next=null; ∥置结果链表尾。 注: 本算法中对 L2 表未作释放空间的处理。 (4) 本题与上面(3)算法相同,只是结果表要另辟空间。 (5) [题目分析]本题首先求 B 和 C 的交集,即求 B 和 C 中共有元素,再与 A 求并集,同 时删除重复元素,以保持结果 A 递增。 LinkedList union(LinkedList A,B,C)
∥A,B和C均是带头结点的递增有序的单链表,本算法实现A=AU(B∩C),使求解结 构保持递增有序 pa=A->next;pb=B->next;pc=C->next;∥设置三个工作指针 pre=A;∥pre指向结果链表中当前待合并结点的前驱。 if(pa->data<pb-> datal lpa->data<pc-data)∥A中第一个元素为结果表的第一元 素 else while(pb&&pc) ∥找B表和C表中第一个公共元素。 if(pb->data<pc->data)pb=pb->next else if (pb->data)pc->data)pc=pc->next else break;∥找到B表和C表的共同元素就退出 while循环 if(pb&&pc)∥因共同元素而非B表或C表空而退出上面 while循环。 if(pa->data>pb->data)∥A表当前元素值大于B表和C表的公共元素,先将B 表元素链入 pre->next=pb;pe=pb;pb=pb->next;pc=pc->next;}∥B,C公共元素为结果 表第一元素。 }∥结東了结果表中第一元素的确定 while(pa&&pb&& Iwhile(pb&&pc) if(pb->data<pc->data) pb=pb->next else if(pb->data>pc->data)pc=pc->next else break;∥B表和C表有公共元素。 if(pb&&pc) while(pa&&pa->data<pb->data)∥先将A中小于B,C公共元素部分链入。 (pre->next=pa pre=pa; pa=pa->next; 1 if(pre->data!=pb->data)pre->next=pb; pre=pb; pb=pb->next: pc=pc->next: K ese{pb=pb->next;pc=pc->next;}∥若A中已有B,C公共元素,则不再存 入结果表 }∥ while(pa&pb&pc) if(pa)pre-next=pa;∥当B,C无公共元素(即一个表已空),将A中剩余链入。 }∥算法 Union结東 [算法讨论]本算法先找结果链表的第一个元素,这是因为题目要求结果表要递増有序 (即删除重复元素)。这就要求当前待合并到结果表的元素要与其前驱比较。由于初始pre=A (头结点的头指针),这时的data域无意义,不能与后继比较元素大小,因此就需要确定第 一个元素。当然,不要这样作,而直接进入下面循环也可以,但在链入结点时,必须先判断 pre是否等于A,这占用了过多的时间。因此先将第一结点链入是可取的。 算法中的第二个问题是要求时间复杂度为0(A|+|B|+C)。这就要求各个表的工作指 针只能后移(即不能每次都从头指针开始査找)。本算法满足这一要求 最后一个问题是,当B,C有一表为空(即B和C已无公共元素时),要将A的剩余部分 链入结果表。 3.[题目分析]循环单链表L1和L2数据结点个数分别为m和n,将二者合成一个循环 单链表时,需要将一个循环链表的结点(从第一元素结点到最后一个结点)插入到另一循环
∥A,B 和 C 均是带头结点的递增有序的单链表,本算法实现 A= A∪(B∩C),使求解结 构保持递增有序。 {pa=A->next;pb=B->next;pc=C->next;∥设置三个工作指针。 pre=A; ∥pre 指向结果链表中当前待合并结点的前驱。 if(pa->data<pb->data||pa->data<pc->data)∥A 中第一个元素为结果表的第一元 素。 {pre->next=pa;pre=pa;pa=pa->next;} else{while(pb&&pc) ∥找 B 表和 C 表中第一个公共元素。 if(pb->data<pc->data)pb=pb->next; else if(pb->data>pc->data)pc=pc->next; else break; ∥找到 B 表和 C 表的共同元素就退出 while 循环。 if(pb&&pc)∥ 因共同元素而非 B 表或 C 表空而退出上面 while 循环。 if(pa->data>pb->data)∥A 表当前元素值大于 B 表和 C 表的公共元素,先将 B 表元素链入。 {pre->next=pb;pre=pb;pb=pb->next;pc=pc->next;}∥ B,C 公共元素为结果 表第一元素。 }∥结束了结果表中第一元素的确定 while(pa&&pb&&pc) {while(pb&&pc) if(pb->data<pc->data) pb=pb->next; else if(pb->data>pc->data) pc=pc->next; else break; ∥B 表和 C 表有公共元素。 if(pb&&pc) {while(pa&&pa->data<pb->data) ∥先将 A 中小于 B,C 公共元素部分链入。 {pre->next=pa;pre=pa;pa=pa->next;} if(pre->data!=pb->data){pre->next=pb;pre=pb;pb=pb->next;pc=pc->next;} else{pb=pb->next;pc=pc->next;}∥ 若 A 中已有 B,C 公共元素,则不再存 入结果表。 } }∥ while(pa&&pb&&pc) if(pa) pre->next=pa; ∥当 B,C 无公共元素(即一个表已空),将 A 中剩余链入。 }∥算法 Union 结束 [算法讨论]本算法先找结果链表的第一个元素,这是因为题目要求结果表要递增有序 (即删除重复元素)。这就要求当前待合并到结果表的元素要与其前驱比较。由于初始 pre=A (头结点的头指针),这时的 data 域无意义,不能与后继比较元素大小,因此就需要确定第 一个元素。当然,不要这样作,而直接进入下面循环也可以,但在链入结点时,必须先判断 pre 是否等于 A,这占用了过多的时间。因此先将第一结点链入是可取的。 算法中的第二个问题是要求时间复杂度为 O(|A|+|B|+|C|)。这就要求各个表的工作指 针只能后移(即不能每次都从头指针开始查找)。本算法满足这一要求。 最后一个问题是,当 B,C 有一表为空(即 B 和 C 已无公共元素时),要将 A 的剩余部分 链入结果表。 3.[题目分析]循环单链表 L1 和 L2 数据结点个数分别为 m 和 n ,将二者合成一个循环 单链表时,需要将一个循环链表的结点(从第一元素结点到最后一个结点)插入到另一循环
链表的第一元素结点前即可。题目要求“用最快速度将两表合并“,因此应找结点个数少的 链表查其尾结点。 LinkedList Union (LinkedList Ll, L2:int m, n) ∥L1和L2分别是两循环单链表的头结点的指针,m和n分别是L1和L2的长度 ∥本算法用最快速度将L1和L2合并成一个循环单链表。 if(m<o|n<o){ printf(“表长输入错误\n”);exit(0);} if(m<n) ∥若m<n,则查L1循环单链表的最后一个结点。 {if(m=0) return(L2);∥L1为空表 elsp=Ll while(p->next!=1)p=p->next;∥查最后一个元素结点 p->next=L2->next;∥将L1循环单链表的元素结点插入到L2的第一元素结点 free(L1);∥释放无用头结点。 }∥处理完m<n情况 else∥下面处理L2长度小于等于L1的情况 if(n=0) return(L1);∥L2为空表 lsep while(p->next!=2)p=p->next;∥查最后元素结点。 p>next=L1->next;∥将L2的元素结点插入到L1循环单链表的第一元素结 LI->next=L2->next ree(L2);∥释放无用头结点 }∥算法结束。 类似本题叙述的其它题解答如下: (1)[题目分析]本题将线性表la和1b连接,要求时间复杂度为0(1),且占用辅助空 间尽量小。应该使用只设尾指针的单循环链表。 LinkedList Union (LinkedList la, 1b ∥1a和1b是两个无头结点的循环单链表的尾指针,本算法将lb接在la后,成为一 个单循环链表 (g=la->next ∥q指向1a的第一个元素结点。 la->next=1b->next;∥将lb的最后元素结点接到Ib的第一元素 Ib->next=q ∥将1b指向la的第一元素结点,实现了1b接在1a后 ∥返回结果单循环链表的尾指针1b }∥算法结束 [算法讨论]若循环单链表带有头结点,则相应算法片段如下: :lb->next ∥q指向1b的头结点 1b-next=a->next;∥lb的后继结点为la的头结点。 la->next=q-next;∥la的后继结点为lb的第一元素结点 ∥释放1b的头结点 return(1b);∥返回结果单循环链表的尾指针1b (2)[题目分析]本题要求将单向链表ha和单向循环链表hb合并成一个单向链表,要求
链表的第一元素结点前即可。题目要求“用最快速度将两表合并“,因此应找结点个数少的 链表查其尾结点。 LinkedList Union(LinkedList L1,L2;int m,n) ∥L1 和 L2 分别是两循环单链表的头结点的指针,m 和 n 分别是 L1 和 L2 的长度。 ∥本算法用最快速度将 L1 和 L2 合并成一个循环单链表。 {if(m<0||n<0) {printf(“表长输入错误\n”);exit(0);} if(m<n) ∥若 m<n,则查 L1 循环单链表的最后一个结点。 {if(m==0)return(L2);∥L1 为空表。 else{p=L1; while(p->next!=L1) p=p->next;∥查最后一个元素结点。 p->next=L2->next;∥将 L1 循环单链表的元素结点插入到 L2 的第一元素结点 前。 L2->next=L1->next; free(L1);∥释放无用头结点。 } }∥处理完 m<n 情况 else∥ 下面处理 L2 长度小于等于 L1 的情况 {if(n==0)return(L1);∥L2 为空表。 else{p=L2; while(p->next!=L2) p=p->next;∥查最后元素结点。 p->next=L1->next;∥将 L2 的元素结点插入到 L1 循环单链表的第一元素结 点前。 L1->next=L2->next; free(L2);∥释放无用头结点。 } }∥算法结束。 类似本题叙述的其它题解答如下: (1)[题目分析]本题将线性表 la 和 lb 连接,要求时间复杂度为 O(1),且占用辅助空 间尽量小。应该使用只设尾指针的单循环链表。 LinkedList Union(LinkedList la,lb) ∥la 和 lb 是两个无头结点的循环单链表的尾指针,本算法将 lb 接在 la 后,成为一 个单循环链表。 { q=la->next; ∥q 指向 la 的第一个元素结点。 la->next=lb->next; ∥将 lb 的最后元素结点接到 lb 的第一元素。 lb->next=q; ∥将 lb 指向 la 的第一元素结点,实现了 lb 接在 la 后。 return(lb); ∥返回结果单循环链表的尾指针 lb。 }∥算法结束。 [算法讨论]若循环单链表带有头结点,则相应算法片段如下: q=lb->next; ∥q 指向 lb 的头结点; lb->next=la->next; ∥lb 的后继结点为 la 的头结点。 la->next=q->next; ∥la 的后继结点为 lb 的第一元素结点。 free(q); ∥释放 lb 的头结点 return(lb); ∥返回结果单循环链表的尾指针 lb。 (2)[题目分析]本题要求将单向链表 ha 和单向循环链表 hb 合并成一个单向链表,要求