题目:
输入一个链表的头结点,从尾到头反过来打印每个节点的值。
struct LIstNode { int m_nKey; ListNode* m_pNext; }
分析:第一反应,从头到尾输出比较简单于是可以将链表连接节点的指针反转过来,改变链表的方向。
打印只是一个只读操作,不改变链表结构。
利用栈的后进先出。随之而来的问题;链表非常长的时候,会导致函数调用的层级很深,从而可能导致函数调用栈溢出。所以用栈基于循环的代码鲁棒性要好一些。
#include <cstdio>
#include <stack>
struct ListNode
{
int m_nValue;
ListNode* m_pNext;
};
//往尾节点添加一个节点
//头结点是一个指向指针的指针。当往空链表插入一个节点时,新插入的节点就是链表的头指针
//因此必须把pHead参数设置为指向指针的指针,否则出了这个函数pHead仍然是一个空指针。
//C语言函数传参实质上是传值,即拷贝实参。所以要修改实参只能传递实参的地址,利用指针的间接性
//进行修改。在此处实参是一个指针,所以要修改指针,就要传递该指针的地址。
void AddToTail(ListNode** pHead, int value)
{
ListNode* pNew = new ListNode();
pNew->m_nValue = value;
pNew->m_pNext = nullptr;
if(*pHead == nullptr)
{
*pHead = pNew;
}
else
{
ListNode* pNode = * pHead;
while(pNode->m_pNext != nullptr)
{
pNode = pNode->m_pNext;
}
pNode->m_pNext = pNew;
}
};
ListNode* CreateListNOde(int value)
{
ListNode* pNew = new ListNode();
pNew->m_nValue = value;
pNew->m_pNext = nullptr;
return pNew;
};
void LinkListNode(ListNode * p1, ListNode * p2)
{
ListNode* pNode = p1;
while(p1->m_pNext != nullptr)
pNode = pNode->m_pNext;
pNode->m_pNext = p2;
};
void RemoveListNode(ListNode** pHead, int value)
{
if(pHead == nullptr || *pHead == nullptr)
return;
ListNode* pToBeDeleted = nullptr;
if((*pHead)->m_nValue == value)//注意这里的(*pHead)一定要加括号
{
pToBeDeleted = *pHead;
*pHead = (*pHead)->m_pNext;
}
else
{
ListNode* pNode = *pHead;
while(pNode->m_pNext != nullptr && pNode->m_pNext->m_nValue != value)
pNode = pNode->m_pNext;
if (pNode->m_pNext != nullptr && pNode->m_pNext->m_nValue == value)
{
pToBeDeleted = pNode->m_pNext;
pNode->m_pNext = pNode->m_pNext->m_pNext;
}
}
if(pToBeDeleted != nullptr)
{
delete pToBeDeleted;
pToBeDeleted = nullptr;
}
}
//从头到尾反转打印链表
void PrintListReversingly(ListNode* pHead)
{
std::stack<ListNode*> nodes;
ListNode* pNode = pHead;
while(pNode != nullptr)
{
nodes.push(pNode);
pNode = pNode->m_pNext;
}
while(!nodes.empty())
{
pNode = nodes.top();
printf("%d\t", pNode->m_nValue);
nodes.pop();
}
}
//删除链表用到一个头指针和 pNode就可以了。
//一直移动pHead就行了
void DestroyListNode(ListNode* pHead)
{
if(pHead == nullptr)
return;
ListNode* pNode = pHead;
while(pNode != nullptr)
{
ListNode* pToBeDeleted = pNode;
pNode = pNode->m_pNext;
delete pToBeDeleted;
pToBeDeleted = nullptr;
}
}
void PrintListNode(ListNode* pHead)
{
if(pHead == nullptr)
return;
ListNode* pNode = pHead;
while(pNode != nullptr)
{
printf("%d\n", pNode->m_nValue);
pNode = pNode->m_pNext;
}
}
int main(int argc, char const *argv[])
{
ListNode* p1 = CreateListNOde(1);
ListNode* p2 = CreateListNOde(2);
ListNode* p3 = CreateListNOde(3);
ListNode* p4 = CreateListNOde(4);
LinkListNode(p1, p2);
LinkListNode(p2, p3);
LinkListNode(p3, p4);
PrintListNode(p1);
printf("\n");
PrintListReversingly(p1);
return 0;
}
输出结果。