文章目录
1.代码示例2.图文解释3.思考总结
1.代码示例
在Clion,用C14标准编译运行通过采用的是有头节点的链表
#include
using namespace std;
typedef struct ListNode
{
ListNode* next;
int val;
ListNode():val(0),next(NULL){}
}* LinkList;
LinkList CreatLinkList(int cnt)
{
LinkList head = (LinkList)(malloc(sizeof(ListNode)));
head->next = NULL;
head->val = -1;
LinkList q,p;
q = head;
while(cnt)
{
p = new ListNode;
p->val = cnt;
q->next = p;
q = p;
cnt--;
}
return head;
}
void ReverseLinkList(LinkList &p)
{
LinkList head = p;
LinkList q,r,tmp;
q = head->next;
if(q == NULL) return;//空链表
else r = q->next;
q->next = NULL;
while(r)
{//有2个以上元素
tmp = r->next;
head->next = r;//头插
r->next = q;
q = r;
r = tmp;
}
}
int main() {
LinkList lk;
lk = CreatLinkList(5);
LinkList p = lk->next;
cout<
while(p)
{
cout<val<
p = p->next;
}
cout<
ReverseLinkList(lk);
lk = lk->next;
while(lk)
{
cout<val<
lk = lk->next;
}
cout<
return 0;
}
2.图文解释
这里使用的方法是头插法进行单链表逆置,算法流程伪代码如下:
1.链表只有一个元素,算法结束 2.链表有2个或以上元素时,将第二个元素及以后元素依次插入到头节点后面,变成第一个元素 算法结束
主要难点是插入节点时各个指针指向的调整。 那第二个元素插入到头节点后面为例子,说明一下: 一开始时是这样,将节点2插入到头节点时,需要干2件大事: 1.将2节点与3节点断链,所以需要一个变量在断链前保存节点3的指针,这就要用到tmp 2.将2节点插到头节点后面,这就涉及到节点插入的基本操作,节点next域做相应改变。 将2节点插入到头节点后,变成这样:
3.思考总结
从图和思想上看,这个q指针始终指向第一个节点,也就是head->next,所以它是可以优化掉的。r指针始终指向要处理的节点,所以它是循环条件细节上,第一次插入要把第一个节点next赋空,因为遍历依赖于它的值。tmp是临时保存变量,因为断链前不保存下一个要处理的节点,后续操作就无法循环继续。