倒序打印数据:我们一般采用先遍历一遍数据,找到最后一个数据,然后从尾到头打印的方式,但是由于单链表的不可逆性,因此倒序打印单链表不能采用普通的方式打印。首先我们要解决一个问题:怎么在打印完一个数据后,可以找到前一个数据。解决这个问题后我们就可以进行倒序打印了。
明确问题后我们就开始解决问题,这里我将提供三种方法。
1 . 数组法
很简单的思路,就是构建一个DataType
类型的数组,将单链表的所有数据保存下来,再将这个数组倒序输出就可以了,但是这个方法的缺点就是数组大小不能改变,因此只能在开始取一个大数,确保数据能够全部放下,因此对于较长的单链表不适用,切对于较短的单链表,不需要的数组个数较多,浪费空间,所以测方法仅供参考,并不推荐。
void PrintListFromTail2Head(PNode pHead)
{
DataType arr[100];
int i = 0;
while (pHead)
{
arr[i++] = pHead->_data;
pHead = pHead->_pNext;
}
while (i)
{
printf("%d ", arr[--i]);
}
printf("\n");
}
- 测试结果
2 . 头插法
头插法的思路就是将该组数据按顺序头插进另外一个单链表,然后再将新单链表输出就完成了倒序打印。
// 逆序打印单链表 3
void PrintListFromTail2Head(PNode pHead)
{
PNode PN = NULL;//创建一个新链表
while (NULL != pHead)//将数据头插进新链表
{
SListPushBack(&PN, pHead->_data);//头插函数,将data头查进PN单链表
pHead = pHead->_pNext;
}
SListPrint(PN);//打印单链表函数
SListDestroy(PN);//销毁整个单链表函数
}
这个方法中所用到的其他函数均在单链表这篇文章中有所介绍,为单链表的基本操作。
- 结果
3 . 递归法
个人最推荐的方式,采用递归进行倒序打印,即想要打印第一个就先打印第二个,想打印第二个,就先打印的第三个,以此类推,直到最后一个数据先打印出来,在返回去打印之前的数据。
void PrintListFromTail2Head(PNode pHead)
{
if(NULL != pHead && NULL != pHead->_pNext)
{
PrintListFromTail2Head(pHead->_pNext);
}
if(pHead != NULL)
printf("%d ", pHead->_data);
}
使用递归就得有出口,出口的判断条件为该节点(pHead)和该节点的下一个节点(pHead->_pNext)是否为空。如果不为空,再次进行循环,如果为空就跳出递归,进行数据打印。要注意的是两次 if 语句中都对(pHead)进行了判空,主要是为了解决头指针为空(即空链表)的情况。
- 测试
// 逆序打印单链表 测试
void PrintListFromTail2Head_test()
{
PNode pHead = NULL;
SListInit(&pHead);
printf("逆序打印测试\n");
SListPushFront(&pHead, 0);
SListPushFront(&pHead, 1);
SListPushFront(&pHead, 2);
SListPushFront(&pHead, 3);
SListPushFront(&pHead, 4);
SListPrint(pHead);
PrintListFromTail2Head(pHead);
printf("\n");
}
- 测试结果