面试官: “反转链表”有哪些实现方式?
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}
好啦,今天的内容到这里就结束了,行百里者半九十,请不要半途而废,好吗?


历史推文


浙公网安备 33010602011771号