一、单链表从尾到头打印的四种方法。
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); //打印链表
}
三、运行结果
四、链表的逆置这种方法容易出错,大家谨慎使用。