链表基础
链表是一种动态的数据结构,插入一个新节点时,为其分配内存,然后调整指针的指向,空间利用率高.
1.单向链表的节点定义:
struct listnode
{
int value;
listnode *next;
}
2.在链表的末尾追加一个节点:
在这里主要解释一下函数的第一个参数pHead是一个指向指针的指针,因为当我们传入一个空链表时,新插入的节点就是链表的头指针,也就是说此时形参需要更改.如果只传入*pHead,传出时依旧是空指针.可以参考C语言关于双指针和C语言单链表
void addlist(listnode **phead,int val)
{
listnode *pnew = new listnode();//创建一个新节点
pnew->value = val;
pnew->next = NULL;
if(*phead == NULL)//判断入参是不是空
{
*phead = pnew;
}
else
{
listnode *pnode = *phead;//传参是*phead时,直接把phead赋值
while(pnode->next != NULL)
{
pnode = pnode->pnext;
}
pnode->next = pnew;
}
}
从尾到头打印链表
题目描述
输入一个链表,从尾到头打印链表每个节点的值。
解题思路
每访问到一个节点,先递归输出他后面的节点,再输出该节点自身
std::vector<int> v;
vector<int> printListFromTailToHead(ListNode* head)
{
if(head != NULL)
{
if(head->next != NULL)
{
printListFromTailToHead(head->next);
}
}
v.push_back(head->value);
return v;
}
上面的代码存在一个问题,当链表长度过长,函数调用的层次过深,从而导致堆栈溢出.由于题目是典型的后进先出的特点,也可以采用栈来存储数据.
vector<int> printListFromTailToHead(ListNode* head)
{
vector<int> v;
std::stack<int> s;
ListNode *p = head;
while(p != NULL) //p->next会越界
{
s.push(p->val);
p = p->next;
}
while(!s.empty())
{
v.push_back(s.top());
s.pop();
}
return v;
}