hello大家好,我是小慕呀,愉快的周末结束啦,明天得去上班咯! 最近老是在微博热搜中看到“躺平”一词,出现的次数太多太多了,多的都数不清了,我们一起看下图
然后看微博评论的时候看到很多好笑的,特别好笑,我随便列出几个好笑的
你们都躺平,我赚谁的培训费?
只要我躺平,镰刀就割不到我!
我现在听什么马云俞敏洪之类讲话我就烦躁想抽他们!
你们随意,我先躺为敬
资本家还是别发声了,他屁股都是歪的
我觉得吧,大家讨厌的不是资本家也不是有钱人,本质上是讨厌自己怎么没有成为这类人。俗话说“屁股决定脑袋”嘛,说的大概也是这个意思,所处位置不同,想法不同,可以理解的,哈哈!!!
好啦,和大家唠嗑了一会儿了,废话不多说了,那今天晚上我们加个餐,学习一下“反转链表”呗!
所谓反转链表,就是将链表整体“反过来”,将头变成尾、尾变成头,如下图所示
一、利用“栈”的特性来实现
我们都知道栈是“先进后出”的,刚好适用于将线性表的顺序颠倒这类问题
public ListNode reverseList(ListNode head) {
Stack<ListNode> stack = new Stack<>();
//把链表节点全部摘掉放到栈中
while (head != null) {
stack.push(head);
head = head.next;
}
if (stack.isEmpty())
return null;
ListNode node = stack.pop(); //弹出栈顶的元素做新链表的头结点
ListNode dummy = node;
//栈中的结点全部出栈,然后重新连成一个新的链表
while (!stack.isEmpty()) {
ListNode tempNode = stack.pop();
node.next = tempNode;
node = node.next;
}
//最后一个结点就是反转前的头结点,一定要让他的next
//等于空,否则会构成环
node.next = null; //这个时候node已经变成新链表的最后一个节点了
return dummy;
}
二、利用“头插法”来实现
不熟悉头插法的朋友们,看下图即可明白啥是“头插法”
实现代码如下
struct ListNode *reverseList(struct ListNode* head) {
struct ListNode *newHead = NULL;
struct ListNode *node;
while (head != NULL) {
//1. 对之前的链表做头删
node = head;
head = head->next;
//2. 对新链表做头插
node->next = newHead;
newHead = node;
}
return newHead;
}
三、利用“三指针”来实现
首先让P1指针指向链表的头结点,让P2指向链表的第二个节点,让P0指向链表的尾部
然后将P1和P2之间的那个指针给干掉,然后再让P1所指的那个节点的next箭头指向P0,如下图,(让P1节点和P0节点之间加一个箭头,就相当于让头结点指向了尾结点,这样不就有点反转的意思了吗?)
然后把P2,P1指针往后移一步,分别指向下一个节点,然后让P0指向链表的头部,再然后就是在P0和P1之间加一个红色箭头,如下图所示
然后一直把P2,P1,P0指针依次往后挪动,一边挪,一边加红色箭头,如下图所示,看红色的箭头,这样不就达到了链表反转的效果了吗?
代码如下:
struct ListNode *reverseList(struct ListNode* head) {
if (head == NULL) {
return NULL;
}
struct ListNode *p0 = NULL;
struct ListNode *p1 = head;
struct ListNode *p2 = head->next;
while (p1 != NULL) {
p1->next = p0;
p0 = p1;
p1 = p2;
if (p2 != NULL) {
p2 = p2->next;
}
}
return p0;
}
四、利用“递归法”来实现
递归说白了就是“套娃”,所以想要学好递归,首先把套娃玩具玩它个几百遍,哈哈, 下图就是递归的思想。
下面的实现代码也是按上图的思想来实现的
1 public ListNode reverseList(ListNode head) {
2 //终止条件
3 if (head == null || head.next == null)
4 return head;
5 //保存当前节点的下一个结点
6 ListNode next = head.next;
7 //从当前节点的下一个结点开始递归调用
8 ListNode reverse = reverseList(next);
9 //reverse是反转之后的链表,因为函数reverseList表示的是对链表的反转,所以反转完之后next肯定
11 // 是链表reverse的尾结点,然后我们再把当前节点head挂到next节点的后面就完成了链表的反转。
13 next.next = head;
14 //这里head相当于变成了尾结点,尾结点都是为空的,
15 //否则会构成环
16 head.next = null;
17 return reverse;
18}
好啦,今天的内容到这里就结束了,行百里者半九十,请不要半途而废,好吗?
历史推文