题目描述
输入一个链表,反转链表后,输出新链表的表头。
解题思路:
这道题刷OJ的话,可以水过:遍历链表,将数值存在数组里,然后再创建新链表,按数组倒序生成。
但是为了正正经经理解链表训练的话,还是按照字面意思对原本的链表进行操作吧。
设置2个指针pNew,pOld。
如:
pNew,pOld分别指向原来链表中前后2个结点。
pNew指针用来指向的是新链表的头节点,pOld用来指向操作过程中原来链表的头结点。
根据原来链表的顺序,不断的将pOld指向pNew,最后返回pNew即指向新链表的头节点啦
package com.xxxx;
/**
* create by ziqiiii
*/
public class Example {
static public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}
static public void main(String[] args){
ListNode head = new ListNode(1);
ListNode p = head;
for(int i =2;i<6;i++){
ListNode ele = new ListNode(i);
p.next =ele;
p=p.next;
}
p=head;
while(p!=null){
System.out.println(p.val);
p=p.next;
}
System.out.println("反转链表");
head = ReverseList(head);
p=head;
while(p!=null){
System.out.println(p.val);
p=p.next;
}
}
//输入一个链表,反转链表后,输出新链表的表头。
static public ListNode ReverseList(ListNode head) {
if(head == null){ //注意判断输入是否为空
return null;
}
//设置pNew指针指向的是新链表的头节点
//pOld为操作中,原来链表的头结点
ListNode pNew = head, pOld = head.next;
pNew.next = null; //注意原来的头节点将是返回链表的尾结点,尾结点next要设置为null
ListNode tmp = pOld; //这句纯粹为了初始化tmp而已
while(pOld != null){
tmp = pOld.next; //tmp要保存pOld.next,不然等下pOld指向pNew,原来pOld后面的结点将会丢失
pOld.next = pNew;
pNew = pOld;
pOld = tmp;
}
return pNew;
}
}
输出:
1
2
3
4
5
反转链表
5
4
3
2
1
// 参考自:
https://hit-alibaba.github.io/interview/basic/algo/Linked-List.html
这个问题可以使用递归和非递归两种方法解决。(C++)
递归算法实现:
ListNode* reverseList(ListNode* head)
{
if(NULL == head || NULL == head->next)
return head;
ListNode * p = reverseList(head->next);
head->next->next = head;
head->next = NULL;
return p;
}
非递归算法实现:
ListNode* reverseList(ListNode* head) {
ListNode *curr = head;
if (curr == NULL) {
return NULL;
}
ListNode *prev = NULL, *temp = NULL;
while (curr != NULL) {
temp = curr->next;
curr->next = prev;
prev = curr;
curr = temp;
}
return prev;
}