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

来源:互联网 发布:如何升级linux 编译器 编辑:程序博客网 时间:2024/05/18 03:37

一、单链表从尾到头打印的四种方法。
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);  //打印链表}

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