题目:反转单链表
定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。
- 示例:
- 输入: 1->2->3->4->5->NULL
- 输出: 5->4->3->2->1->NULL
题目分析:
单链表最大的限制就是只能从前往后进行遍历。而不能像数组一样,直接通过索引从前往后或者从后往前实现遍历。单链表最大的优势就是插入与删除不需要移动元素。我们可以利用单链表的头插法,将单链表的第二个元素开始,均通过头插法进行插入。
我们需要三个指针,分别指向头结点–header,头结点的下一个结点(待插入的结点)–newNode,头结点的下下一个结点–tempNode,用于保存后面的数据。
1. header指向示例中的1,
2. newNode指向示例中的2,
3. tempNode指向示例中的3,
4. 反转后,原先的头结点变为了末尾结点,故先要header.next=null, 1->null
前期的准备工作做好后,我依次进行插入:
1. tempNode=newNode.next; 用于保存后面的数据。
2. newNode.next=header; 待插入的结点指向原先的头结点。2->1->null;
3. header = newNode; 当前的头结点为待插入的结点。
4. newNode = tempNode; 待插入的结点变成之前待插入结点的后一个值,3
边界条件:
插入时的三种情况:
1. 头结点为空,即该链表为空。
if(head==null){
return null;
}
2.仅有一个结点的时候,直接返回该链表即可。
if(head!=null && head.next==null){
return head;
}
3. 因为是连续的三个指针,循环体内部一定要保证第二个指针存在。否则第三个指针的存在性不能保证。
Java代码:
/**
* 定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。
* 示例:
*
* 输入: 1->2->3->4->5->NULL
* 输出: 5->4->3->2->1->NULL
*/
public class Offer24 {
class Node{
int data;
Node next;
public Node() {
}
public Node(int data) {
this.data = data;
}
}
// 简易创建单链表
public Node creat(){
Node head = new Node(1);
Node cur = head;
for (int i = 1; i < 8; i++) {
cur.next = new Node(i);
cur = cur.next;
}
return head;
}
// 打印单链表
public void print(Node head){
if (head==null){
return;
}
while (head!=null){
System.out.print(head.data+" ");
head = head.next;
}
}
// 头插法反转单链表
public Node reverseList1(Node head){
// 边界处理
if(head==null){
return null;
}
if(head!=null && head.next==null){
return head;
}
Node temp = null;
Node newNode = head.next;
head.next = null;
while(newNode.next!=null){
temp = newNode.next;
newNode.next = head;
head = newNode;
newNode = temp;
}
// 退出循环后,说明只有最后一个结点
newNode.next = head;
return newNode;
}
public static void main(String[] args) {
Offer24 offer24 = new Offer24();
Node list = offer24.creat();
System.out.println("反转之前");
offer24.print(list);
System.out.println("\n反转之后");
offer24.print(offer24.reverseList1(list));
}
}
【注】
(1):leetcode 等平台只要我们完成一个函数即可,本人初出茅庐,为了巩固基本知识,故自己补充了部分代码,用于练手。本代码也许存在漏洞,望高手赐教。感谢!