链表的从尾到头打印(四种方法)

一、单链表从尾到头打印的四种方法。
1、正常从尾到头打印。
用一个尾指针指到最后,尾指针每次前移移位,遇到尾指针则打印。

void EndToFirstPrintNode(SListNode*ps) //正常从尾到头打印
{
    SListNode *cur=ps;
    SListNode *tail=NULL;
    while (ps != tail)
    {
        cur=ps;
        while (tail != cur->_next)
            cur=cur->_next;

        printf("%d ",cur->_data);
        tail=cur;
    }
}

2、用动态顺序表。
先遍历一遍把链表的每个数保存在动态顺序表中,再逆序打印顺序表。

void EndToFirstPrintSListNode(SListNode *ps)  //链表的从尾到头打印,用动态顺序表保存数据。
{
    size_t i = 0;
    while (ps)
    {
         CheckFullSeqlist(&List);  //判容和扩容
         List.data[i++]=ps->_data;  //把链表数据赋给顺序表
         List.size++;
         ps=ps->_next;
    }
    PrintSList(&List);  //打印顺序表
}

3、用递归法打印

void EndToFirstPrintSListNodeR(SListNode *ps)//递归打印
{
    if (NULL != ps->_next) //递归结束条件
        EndToFirstPrintSListNodeR(ps->_next);  //子问题
    printf("%d ",ps->_data);
}

4、用链表逆置的方法打印
先逆置链表,再打印链表

void EndToFirstPrintSListNodeNon(SListNode *ps)  //逆置链表
{
    SListNode *prev;
    SListNode *cur;
    SListNode *tmp;
    cur=ps;  //保存头结点
    prev=cur->_next;  //保存下一个节点
    cur->_next=NULL;  //头结点变为尾节点,next=NULL
    while (NULL != prev)  
    {
        tmp=prev->_next;
        prev->_next=cur;
        cur=prev;
        prev=tmp;
    }
    ps=cur;  //尾节点变为头节点
    SListPrint(ps);  //打印链表
}

二、整体代码。

void EndToFirstPrintNode(SListNode*ps) //正常从尾到头打印
{
    SListNode *cur=ps;
    SListNode *tail=NULL;
    while (ps != tail)
    {
        cur=ps;
        while (tail != cur->_next)
            cur=cur->_next;

        printf("%d ",cur->_data);
        tail=cur;
    }
}
 typedef struct SeqList  //顺序表
  {
      DataType *data;
      size_t size;
      size_t capicity;
  }SeqList;
  SeqList List;

  void CheckFullSeqlist(SeqList *Seq)  //顺序表的判容和扩容
  {
      DataType *tmp;
      if (Seq->size==Seq->capicity)
      {
          tmp=(DataType*)realloc(Seq->data,2*Seq->capicity*sizeof(DataType)+3*sizeof(DataType));
          if (NULL==tmp)
          {
              printf("扩容失败!");
          }
          else
          {
              Seq->capicity=Seq->capicity*2+3;
              Seq->data=tmp;
          }
      }
  }

  void PrintSList(SeqList *Seq)  //打印顺序表
  {
      DataType i=0;
      for (i=Seq->size-1;i>=0;i--)
      {
          printf("%d ",Seq->data[i]);
      }
  }

 void SListPrint(SListNode* pHead)  //打印链表
{
    if (NULL==pHead)
    {
        printf("空链表\n");
    }
    else
    {
        while (pHead)
        {
            printf("%d ",pHead->_data);
            pHead=pHead->_next;
        }
        printf("\n");
    }
}

void EndToFirstPrintSListNode(SListNode *ps)  //链表的从尾到头打印,用动态顺序表保存数据。
{
    size_t i = 0;
    while (ps)
    {
         CheckFullSeqlist(&List);
         List.data[i++]=ps->_data;
         List.size++;
         ps=ps->_next;
    }
    PrintSList(&List);
}

void EndToFirstPrintSListNodeR(SListNode *ps)//递归打印
{
    if (NULL != ps->_next) //递归结束条件
        EndToFirstPrintSListNodeR(ps->_next);  //子问题
    printf("%d ",ps->_data);
}

void EndToFirstPrintSListNodeNon(SListNode *ps)  //逆置链表
{
    SListNode *prev;
    SListNode *cur;
    SListNode *tmp;
    cur=ps;  //保存头结点
    prev=cur->_next;  //保存下一个节点
    cur->_next=NULL;  //头结点变为尾节点,next=NULL
    while (NULL != prev)  
    {
        tmp=prev->_next;
        prev->_next=cur;
        cur=prev;
        prev=tmp;
    }
    ps=cur;  //尾节点变为头节点
    SListPrint(ps);  //打印链表
}

三、运行结果
这里写图片描述
四、链表的逆置这种方法容易出错,大家谨慎使用。

  • 7
    点赞
  • 53
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

龙跃十二

写的不错,给点鼓励

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值