一、链表
链表的结构是一种非线性的数据结构,优点是可以充分使用空间,插入和删除节点的时候不需要遍历节点速度较快,但是由于其特性在查找的时候遍历速度比较慢。每一个节点在存储自己的数据的时候,还存储下一个节点的物理位置。
可抽象为:
二、链表反转
1、新增物理存储反转
如图:
1 | 2 | 3 | 4 | null |
第一步:生成一个新的节点1
1 |
第二步:生成一个新的节点2,并指向1
2 | 1 |
...依次类推,最终形成
4 | 3 | 2 | 1 | null |
伪代码:
Node reverseList(node header){
if(null == header || null == header->next){
return header;
}
Node node = header,tem = header;
while(null != tem->next){
tem = tem->next;
node->next = tem;
}
return node;
}
可运行代码
package com.example.demo;
/**
* @author superStar Zhao
* 反转单向链表
*/
public class ReverseNode {
/**
* 节点结构
*/
class Node{
private Node next;
private int value;
public Node(Node next, int value) {
this.next = next;
this.value = value;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
}
/**
* 初始化链表
* @return
*/
public Node init() {
Node header = new Node(null,1);
header.setNext(new Node(new Node(new Node(null,4),3),2));
return header;
}
/**
* 链表反转方法
* @param header
* @return
*/
public Node reverseList(Node header){
if(null == header || null == header.next){
return header;
}
Node node = new Node(null,header.value),tmp = null;
while (null != header.next){
tmp = new Node(header.next.next,header.next.value);
tmp.setNext(node);
node = tmp;
header = header.next;
}
return node;
}
/**
* 测试main方法
* @param args
*/
public static void main(String[] args) {
ReverseNode service = new ReverseNode();
Node node = service.init();
node = service.reverseList(node);
while (null != node){
System.out.println(node.value);
node = node.next;
}
}
}
2、遍历算法
遍历算法比第一种算法更为优秀的一点是不增加物理存储
初始状态
第一步:
第二步:
伪代码:
Node reverseList(node header){
if(null == header || null == header->next){
return header;
}
if(null == header->next->next){
Node newHeader = header->next;
newHeader->next = header;
header->next = null;
return newHeader;
}
Node nodeM = header,nodeP = header->next, nodeN = header->next->next;
while(null != nodeN){
if(nodeM->next == nodeP){
nodeM->next = null;
}
nodeP->next = nodeM;
nodeM = nodeP;
nodeP = nodeN;
nodeN = node->next;
}
return nodeP;
}
可运行代码:
/**
* 链表反转方法
* @param header
* @return
*/
public Node reverseList(Node header){
if(null == header || null == header.next){
return header;
}
Node nodeM = header; Node nodeP = header.next; Node nodeN = header.next.next;
while (null != nodeN){
if(nodeM.next == nodeP){
nodeM.setNext(null);
}
nodeP.setNext(nodeM);
nodeM = nodeP;
nodeP = nodeN;
nodeN = nodeN.next;
}
/**
* 兼容两个节点
*/
if(nodeM.next == nodeP){
nodeM.setNext(null);
}
nodeP.setNext(nodeM);
return nodeP;
}
3、递归算法
其中一种思想同第二种方法,是第二种方法衍生而来不做赘述;这里重点描述另外一种方法。
解题思想,遍历到最后一个节点,逆向往回推
原模型:
第一步:
...
伪代码:
Node reverseList(Node header){
if(null == header || null == header.next){
return header;
}
Node new = reverseList(header.next);
}
可运行代码:
/**
* 链表反转方法
* @param header
* @return
*/
public Node reverseList2(Node header){
if(null == header || null == header.next){
return header;
}
Node newNode = reverseList2(header.next);
header.next.setNext(header);
header.setNext(null);
return newNode;
}