一、单链表反转
链表反转,就是将链表从1->2->3->4->5这种形式反转成5->4->3->2->1这种形式,目前能想到的有两种实现方式,对于什么是链表,链表的一些性质就不多说了,直接说两种实现方式,实现方式如下:
1,用头节点插入法新建链表。反转链表,有创建链表的两种方式(头节点插入法,尾节点插入法)知道,头结点插入法形成的链表是和输入顺序相反的,尾节点插入法形成的链表是和输入顺序相同的,所以其中一种方法是,遍历原链表,然后用原链表的输出元素顺序用头结点插入法新建链表,这样新建的链表就是反转后的链表。具体伪代码操作:
reverse(NodeList list)
if list == null
return null
NodeList newList
Node temp = list->next
newList->next = null
while temp != null
temp->next = newList->next
newList->next = temp
temp = temp->next
return newList
2,就地反转链表。遍历链表,将当前链表的头结点下一个的下一个节点插入到头结点的下一个节点中,这样就能就地反转了。如1->2->3->4->5先转成2->1->3->4->5,然后在转成3->2->1->4->5这样知道最后一个节点就可以就地反转了。具体为代码操作如下:
reverse(NodeList list)
if list == null
return null
Node temp = list->next
while temp->next != null
Node insert = temp->next // 取出要反转节点下一个节点
insert->next = list->next // 将这个节点插入到头结点后面
list->next = insert
temp = temp->next // 继续遍历
return list
二、两两反转
两两反转单项链表就是把每两个数反转一次。如:A -> B -> C ->D -> E -> F ->G -> H -> I 两两反转后变为 B -> A -> D ->C -> F -> E ->H -> G -> I
我们一共需要分析四个指针,prev, current, next, nextNext。 分析:我们需要两个“指针”指着当前要反转的两个值current和next。两两反转后,我们还需要记录下一个的值,即反转A和B后, 需要记录 C 值,我们才能够不断向下走,直到到达链表末端,所以,需要另一个指向下一个值的“指针”,即nextNext。反转以后,A的下一个是C, 但是,实际上,A的下一个应该是D,所以,每次反转时,我们需要更新前一个值的下一个值,也就是说把 A -> C 改成 A -> D,所以需要prev指针。所以,要完成这个操作,我们总共需要4个“指针”。具体看代码。
java代码:
java代码:
先定义数据结构:
class Node {
char value;
Node next;
}
具体操作:
/**
* 两两反转具体操作,先得到当前节点的下个节点和下下个节点,然后下个节点的指针指向当前节点nextNode.next = current,当前节点的指针只想下下个节点current.next = nextNextNode,这样这两个节点就互换了,然后更新前一个节点的下一个节点值previousNode.next = nextNode,在更新的时候要判断是不是第一次,因为第一次两两反转没有前一个节点指针,指向的是null,然后赋值继续循环previousNode = currentNode; currentNode = nextNextNode;这样就可以了。。
* @param list 要两两反转的链表头结点
* @return 反转后的链表头结点
*/
public static Node reverseInPair(Node list) {
Node current = list;
if (current == null || current.next == null){
return current;
}
Node head = current.next;// 保存头结点,用以返回。
Node previousNode = null; // 这是指向前一个节点的指针
while(current != null && current.next != null) {
// 得到下一个节点和下一个的下一个节点
Node nextNode = current.next;
Node nextNextNode = nextNode.next;
nextNode.next = current;
current.next = nextNextNode;
//更新前一个节点的下一个节点
if (previousNode != null) {
previousNode.next = nextNode;
}
previousNode = current;
current = nextNextNode; // 当前节点赋值为下一个的下一个节点继续遍历
}
return head;
}