前言

由于是出成绩后一段时间写的,已经有点遗忘当时遇到的情况,同时该代码不是最优解,需要精简代码的同学可以想想办法解决奇偶长度和有时候头结点不为空的问题,这样就可以极大程度上解决我这个代码的冗余。

 

题目

【202201007】试写一算法,从某个结点p开始,双向交错遍历一条双向循环链表。规定如下:

  1. 先从p的next指针域方向最先开始访问;然后访问p的prior域;再访问p的next域...。
  2. 已知每个结点的data域只含一个字符。每访问一个结点,就将该结点的data域打印出来。必须使用"%c"格式的printf函数打印。
  3. 不打印头结点的data域。如果遍历到头结点,则需沿当前遍历方向,继续前进至下一个结点,并打印该结点的data域。
  4. 结点p的data域最后打印,但是如果p是指向头结点,则不打印。
  5. 请勿使用printf函数打印其它多余字符,否则可能会导致输出校验出错

举例:规定头结点为第0个结点,例如从下表中第3个结点开始遍历时:打印结果为:TLAQRCMF

0 1 2 3 4 5 6 7 8
  Q L F T A R M C

实现以下函数:从结点p开始,双向交错遍历L。

void InterleavedTravelDuCirLinkList(DuCirLinkList L, DuLNode* p)

已知双向循环链表的结构体定义:

typedef char  ElemType;

typedef struct DuLNode {

ElemType  data;

struct DuLNode  *prior, *next; //分别指向直接前驱和直接后继

} DuLNode, *DuLinkList; //双向链表

typedef DuLinkList DuCirLinkList; // 双向循环链表

 

解析

以下为我模糊的回忆:

在一开始我考虑到了奇偶的问题,用的do...while语句来进行指针移动的,后面碰到一些奇奇怪怪的问题就全部重写了一遍。

首先考虑空链表和只有一个元素的链表

于是可以写出以下代码:

if(L->next==L)
return;

if(L->next->next==L)
{
  printf("%c",L->next->data);
  return;
}

虽说这个也有些问题,在anyview系统中,生成的测试数据是有没有头结点的情况存在的,也就是说下一个元素和上一个元素都是自己。可以考虑再加一个或者合并在之前的代码。

if(L->next==L)
{
  printf("%c",L->data);
  return;
}

 

接着便是处理正常的情况

我这里偷懒了不想想太多,遍历得到整个链表的长度

int sum=0;    //链表长度
int search=0;    //遍历元素个数
DuLinkList length,pre,rear;
length=L->next;
pre=p->prior;
rear=p->next;

while(length!=L)
{
  sum++;
  length=length->next;
}

获得链表长度后可以开始遍历了,这里依旧偷懒,反正就是当两个指针相遇就结束

while(1)
{
  if(rear==pre && pre==L && rear==L)
  break;
  
  if(rear==L)
  rear=rear->next;    //因为偷懒不考虑奇偶长度问题,所以每次移动指针都要检查是否相遇
  if(pre==rear)
  break;
  printf("%c",rear->data);
  search++;
  rear=rear->next;
    
  if(pre==rear)
  break;
  if(pre==L)
  pre=pre->prior;
  if(pre==rear)
  break;
  printf("%c",pre->data);
  search++;
  pre=pre->prior;
    
  if(pre==rear)
  break;
}

 最后就是对最后一个元素输出做处理

if(sum-2==search)
{
  printf("%c",pre->data);
  search++;
}
if(search==sum-1 && p==L)
printf("%c",pre->data);

if(search==sum-1 && p!=L)
printf("%c",p->data);

 

测试数据

双向循环链表:QQYQQQ,起始结点位置(头结点位标为【0】):【0】
你的结果:QQQQYQ
系统结果:QQQQYQ
========RIGHT========
双向循环链表:QQYQQQ,起始结点位置(头结点位标为【0】):【1】
你的结果:QQYQQQ
系统结果:QQYQQQ
========RIGHT========
双向循环链表:QQYQQQ,起始结点位置(头结点位标为【0】):【2】
你的结果:YQQQQQ
系统结果:YQQQQQ
========RIGHT========
双向循环链表:QQYQQQ,起始结点位置(头结点位标为【0】):【3】
你的结果:QQQQQY
系统结果:QQQQQY
========RIGHT========
双向循环链表:QQYQQQ,起始结点位置(头结点位标为【0】):【4】
你的结果:QYQQQQ
系统结果:QYQQQQ
========RIGHT========
双向循环链表:QQYQQQ,起始结点位置(头结点位标为【0】):【5】
你的结果:QQQYQQ
系统结果:QQQYQQ
========RIGHT========
双向循环链表:QQYQQQ,起始结点位置(头结点位标为【0】):【6】
你的结果:QQQQYQ
系统结果:QQQQYQ
========RIGHT========
双向循环链表:OODODOO,起始结点位置(头结点位标为【0】):【0】
你的结果:OOOODDO
系统结果:OOOODDO
========RIGHT========
双向循环链表:OODODOO,起始结点位置(头结点位标为【0】):【1】
你的结果:OODOODO
系统结果:OODOODO
========RIGHT========
双向循环链表:OODODOO,起始结点位置(头结点位标为【0】):【2】
你的结果:DOOODOO
系统结果:DOOODOO
========RIGHT========
双向循环链表:OODODOO,起始结点位置(头结点位标为【0】):【3】
你的结果:OODOOOD
系统结果:OODOOOD
========RIGHT========
双向循环链表:OODODOO,起始结点位置(头结点位标为【0】):【4】
你的结果:DDOOOOO
系统结果:DDOOOOO
========RIGHT========
双向循环链表:OODODOO,起始结点位置(头结点位标为【0】):【5】
你的结果:OOODOOD
系统结果:OOODOOD
========RIGHT========
双向循环链表:OODODOO,起始结点位置(头结点位标为【0】):【6】
你的结果:ODOOODO
系统结果:ODOOODO
========RIGHT========
双向循环链表:OODODOO,起始结点位置(头结点位标为【0】):【7】
你的结果:OOODDOO
系统结果:OOODDOO
========RIGHT========
双向循环链表:WWWORQR,起始结点位置(头结点位标为【0】):【0】
你的结果:WRWQWRO
系统结果:WRWQWRO
========RIGHT========
双向循环链表:WWWORQR,起始结点位置(头结点位标为【0】):【1】
你的结果:WRWQORW
系统结果:WRWQORW
========RIGHT========
双向循环链表:WWWORQR,起始结点位置(头结点位标为【0】):【2】
你的结果:WWORRQW
系统结果:WWORRQW
========RIGHT========
双向循环链表:WWWORQR,起始结点位置(头结点位标为【0】):【3】
你的结果:OWRWQRW
系统结果:OWRWQRW
========RIGHT========
双向循环链表:WWWORQR,起始结点位置(头结点位标为【0】):【4】
你的结果:RWQWRWO
系统结果:RWQWRWO
========RIGHT========
双向循环链表:WWWORQR,起始结点位置(头结点位标为【0】):【5】
你的结果:QORWWWR
系统结果:QORWWWR
========RIGHT========
双向循环链表:WWWORQR,起始结点位置(头结点位标为【0】):【6】
你的结果:RRWOWWQ
系统结果:RRWOWWQ
========RIGHT========
双向循环链表:WWWORQR,起始结点位置(头结点位标为【0】):【7】
你的结果:WQWRWOR
系统结果:WQWRWOR
========RIGHT========
双向循环链表:CJCCCTCW,起始结点位置(头结点位标为【0】):【0】
你的结果:CWJCCTCC
系统结果:CWJCCTCC
========RIGHT========
双向循环链表:CJCCCTCW,起始结点位置(头结点位标为【0】):【1】
你的结果:JWCCCTCC
系统结果:JWCCCTCC
========RIGHT========
双向循环链表:CJCCCTCW,起始结点位置(头结点位标为【0】):【2】
你的结果:CCCWCCTJ
系统结果:CCCWCCTJ
========RIGHT========
双向循环链表:CJCCCTCW,起始结点位置(头结点位标为【0】):【3】
你的结果:CJCCTWCC
系统结果:CJCCTWCC
========RIGHT========
双向循环链表:CJCCCTCW,起始结点位置(头结点位标为【0】):【4】
你的结果:CCTJCCWC
系统结果:CCTJCCWC
========RIGHT========
双向循环链表:CJCCCTCW,起始结点位置(头结点位标为【0】):【5】
你的结果:TCCCWJCC
系统结果:TCCCWJCC
========RIGHT========
双向循环链表:CJCCCTCW,起始结点位置(头结点位标为【0】):【6】
你的结果:CCWCCCJT
系统结果:CCWCCCJT
========RIGHT========
双向循环链表:CJCCCTCW,起始结点位置(头结点位标为【0】):【7】
你的结果:WTCCJCCC
系统结果:WTCCJCCC
========RIGHT========
双向循环链表:CJCCCTCW,起始结点位置(头结点位标为【0】):【8】
你的结果:CCJTCCCW
系统结果:CCJTCCCW
========RIGHT========
双向循环链表:FRRRRR,起始结点位置(头结点位标为【0】):【0】
你的结果:FRRRRR
系统结果:FRRRRR
========RIGHT========
双向循环链表:FRRRRR,起始结点位置(头结点位标为【0】):【1】
你的结果:RRRRRF
系统结果:RRRRRF
========RIGHT========
双向循环链表:FRRRRR,起始结点位置(头结点位标为【0】):【2】
你的结果:RFRRRR
系统结果:RFRRRR
========RIGHT========
双向循环链表:FRRRRR,起始结点位置(头结点位标为【0】):【3】
你的结果:RRRFRR
系统结果:RRRFRR
========RIGHT========
双向循环链表:FRRRRR,起始结点位置(头结点位标为【0】):【4】
你的结果:RRRRFR
系统结果:RRRRFR
========RIGHT========
双向循环链表:FRRRRR,起始结点位置(头结点位标为【0】):【5】
你的结果:RRFRRR
系统结果:RRFRRR
========RIGHT========
双向循环链表:FRRRRR,起始结点位置(头结点位标为【0】):【6】
你的结果:FRRRRR
系统结果:FRRRRR
========RIGHT========
双向循环链表:ZZAXZDZ,起始结点位置(头结点位标为【0】):【0】
你的结果:ZZZDAZX
系统结果:ZZZDAZX
========RIGHT========
双向循环链表:ZZAXZDZ,起始结点位置(头结点位标为【0】):【1】
你的结果:ZZADXZZ
系统结果:ZZADXZZ
========RIGHT========
双向循环链表:ZZAXZDZ,起始结点位置(头结点位标为【0】):【2】
你的结果:AZXZZDZ
系统结果:AZXZZDZ
========RIGHT========
双向循环链表:ZZAXZDZ,起始结点位置(头结点位标为【0】):【3】
你的结果:XZZZDZA
系统结果:XZZZDZA
========RIGHT========
双向循环链表:ZZAXZDZ,起始结点位置(头结点位标为【0】):【4】
你的结果:ZADZZZX
系统结果:ZADZZZX
========RIGHT========
双向循环链表:ZZAXZDZ,起始结点位置(头结点位标为【0】):【5】
你的结果:DXZAZZZ
系统结果:DXZAZZZ
========RIGHT========
双向循环链表:ZZAXZDZ,起始结点位置(头结点位标为【0】):【6】
你的结果:ZZZXZAD
系统结果:ZZZXZAD
========RIGHT========
双向循环链表:ZZAXZDZ,起始结点位置(头结点位标为【0】):【7】
你的结果:ZDZZAXZ
系统结果:ZDZZAXZ
========RIGHT========
双向循环链表:S,起始结点位置(头结点位标为【0】):【0】
你的结果:S
系统结果:S
========RIGHT========
双向循环链表:S,起始结点位置(头结点位标为【0】):【1】
你的结果:S
系统结果:S
========RIGHT========
双向循环链表:空双向循环链表,起始结点位置(头结点位标为【0】):【0】
你的结果:
系统结果:
========RIGHT========

 

完整代码

void InterleavedTravelDuCirLinkList(DuCirLinkList L, DuLNode* p)
{ 
if(L->next==L)
    return;

    if(L->next->next==L)
    {
      printf("%c",L->next->data);
      return;
    }

    if(L->next==L)
    {
      printf("%c",L->data);
      return;
    }

    int sum=0;
    int search=0;
    DuLinkList length,pre,rear;
    length=L->next;
    pre=p->prior;
    rear=p->next;

    while(length!=L)
    {
      sum++;
      length=length->next;
    }

    while(1)
    {
      if(rear==pre && pre==L && rear==L)
          break;
      if(rear==L)
          rear=rear->next;
      if(pre==rear)
          break;
      printf("%c",rear->data);
      search++;
      rear=rear->next;
      if(pre==rear)
          break;
      if(pre==L)
          pre=pre->prior;
      if(pre==rear)
          break;
      printf("%c",pre->data);
      search++;
      pre=pre->prior;
      if(pre==rear)
          break;
    }

    if(sum-2==search)
    {
      printf("%c",pre->data);
      search++;
    }

    if(search==sum-1 && p==L)
    printf("%c",pre->data);

    if(search==sum-1 && p!=L)
    printf("%c",p->data);
}