链表是数据结构的基础内容之中的一个,以下就链表操作中的创建链表、打印链表、求取链表长度、推断链表是否为空、查找结点、插入结点、删除结点、逆转链表、连接链表、链表结点排序等进行总结。
1.创建表示结点的类,由于链表操作中须要比較结点,因此结点须要实现comparable接口。
public class Node implements Comparable<Node> {
private Object data;
private Node next;
//构造函数
public Node() {
this.data = null;
this.next = null;
}
//构造函数重载
public Node(Object data) {
this.data = data;
this.next = null;
}
public Node(Object data, Node next) {
this.data = data;
this.next = next;
}
//读结点数据
public Object getData() {
return data;
}
//写结点数据
public void setData(Object data) {
this.data = data;
}
//获取结点链接的下一个点
public Node getNext() {
return next;
}
//设置结点链接的下一个点
public void setNext(Node next) {
this.next = next;
}
@Override
public int compareTo(Node o) {
if((Integer)this.data == (Integer)o.getData()) {
return 0;
}
else {
if((Integer)this.data < (Integer)o.getData()) {
return -1;
}
else {
return 1;
}
}
}
}
2.链表类例如以下。
public class Link{
/**
* 链表头结点
*/
private Node m_headNode = null;
/**
* 链表长度
*/
private int m_length = 0;
/**
* 获取链表头结点
*
* @return 链表头结点
*/
public Node getheadNode() {
return m_headNode;
}
/**
* 获取链表长度
*
* @return 链表长度
*/
public int getLength() {
return m_length;
}
/**
* 对以head为头结点的链表中的各个元素进行打印输出
*
* @param head 链表的头结点
*/
public void printLink() {
Node p = m_headNode;
while(p != null) {
System.out.print(p.getData() + " ");
p = p.getNext();
}
System.out.println();
}
/**
* 用来创建一个链表,data数组中的数据相应链表中各个结点的data值
*
* @param data 链表中各个结点的数据信息
* @return 链表的头结点
*/
public Node createLink(Object[] data) {
Node headNode = null, r = null;
for(int i=0; i<data.length; i++) {
Node p = new Node();
p.setData(data[i]);
p.setNext(null);
if(headNode == null) {
headNode = p;
}
else {
r.setNext(p);
}
r = p;
this.m_length++;
}
this.m_headNode = headNode;
return headNode;
}
/**
* 求线性链表的长度
*
* @return 链表的长度
*/
public int linkLength() {
/*常规算法
int n = 0;
Node p = head;
while(p != null) {
n++;
p = p.getNext();
}
return n;
*/
/*递归算法
if(head != null) {
return 1 + linkLength(head.getNext());
} else {
return 0;
}
*/
return m_length;
}
/**
* 推断线性链表是否为空
*
* @param headNode 链表的头结点
* @return 若链表为空,返回true;否则返回false
*/
public boolean isEmpty() {
return m_headNode == null;
}
/**
* 查找链表中item的地址
*
* @param item 查找的目标结点的地址
* @return 假设结点存在,返回结点。否则返回空
*/
public Node findElement(Object item) {
Node p = m_headNode;
while(p != null) {
if(p.getData() == item) {
return p;
}
p = p.getNext();
}
return null;
}
/**
* 在链表头结点之前插入结点,使之成为头结点
*
* @param data 插入的结点数据
*/
public void insertHeadNode(Object data) {
Node node = new Node(data, null);
node.setNext(m_headNode);
m_headNode = node;
m_length++;
}
/**
* 在链表尾部插入结点。使之成为尾结点
*
* @param data 插入的结点数据
*/
public void insertTailNode(Object data) {
Node p = m_headNode;
while(p.getNext() != null) {
p = p.getNext();
}
Node node = new Node(data, null);
p.setNext(node);
m_length++;
}
/**
* 在链表的第pos个位置后插入数据为data的结点
*
* @param pos 插入结点的位置
* @param data 插入结点的数据
* @return 正确插入返回1。否则返回0
*/
public int insertNode(int pos, Object data) {
if(pos <= 0 || pos > m_length) {
return 0;
}
int n = 0;
Node p = m_headNode;
while(p != null) {
n++;
if(n == pos) {
Node node = new Node(data);
node.setNext(p.getNext());
p.setNext(node);
m_length++;
return 1;
}
p = p.getNext();
}
return 0;
}
/**
* 删除链表中第一次出现数据为data的结点
*
* @param data 被删除的结点数据
* @return 链表中存在该结点且删除成功,返回true。否则,返回false
*/
public boolean deleteNode(Object data) {
if(m_headNode.getData() == data) {
m_headNode = m_headNode.getNext();
m_length--;
return true;
}
Node p = m_headNode, r = null;
while(p != null) {
if(p.getData() == data) {
r.setNext(p.getNext());
m_length--;
return true;
}
else {
r = p;
p = p.getNext();
}
}
return false;
}
/**
* 删除链表中数据元素为data的全部结点
*
* @param data 链表中被删结点的数据
*/
public void deleteAllNode(Object data) {
Node p = m_headNode.getNext(), r = m_headNode;
while(p != null) {
if(p.getData() == data) {
r.setNext(p.getNext());
p = p.getNext();
m_length--;
}
else {
r = p;
p = p.getNext();
}
}
if(m_headNode.getData() == data) {
m_headNode = m_headNode.getNext();
m_length--;
}
}
/**
* 逆转链表
*/
public void invertLink() {
Node p = m_headNode, r, q = null;
while(p != null) {
r = q;
q = p;
p = p.getNext();
q.setNext(r);
}
m_headNode = q;
}
/**
* 将该链表链接在headLink之后
*
* @param link 被链接的链表
* @throws NullPointerException 假设被链接的链表中一个结点都没有,抛出空指针异常
*/
public void connectFrom(Link link) throws NullPointerException {
if(link.getheadNode() == null) {
throw new NullPointerException();
}
else {
Node p = link.getheadNode(), r = null;
while(p != null) {
r = p;
p = p.getNext();
}
r.setNext(m_headNode);
m_headNode = link.getheadNode();
m_length += link.getLength();
}
}
/**
* 在链表尾部追加link链表
*
* @param link 须要追加的链表
*/
public void connectTo(Link link) {
Node p = m_headNode, r = null;
while(p != null) {
r = p;
p = p.getNext();
}
r.setNext(link.getheadNode());
m_length += link.getLength();
}
/**
* 对链表各结点数据从小到大排序
*
* @throws NullPointerException 假设链表中一个结点都没有,则抛出空指针异常
*/
public void sort() throws NullPointerException {
if(m_headNode == null) {
throw new NullPointerException();
}
else {
Node r = m_headNode, p = m_headNode.getNext(), q = null;
int count = 1;
while(p != null) {
if(p.compareTo(r) == -1) {
q = p;
r.setNext(p.getNext());
p = p.getNext();
insert(q, count);
}
else {
r = p;
p = p.getNext();
}
count++;
}
}
}
/**
* 将结点p插入一个顺序排列的长度为length的链表中,使得插入结点p后的链表仍然顺序排列
*
* @param p 须要插入的结点
* @param length 顺序排列的链表的长度
*/
private void insert(Node p, int length) {
if(p.compareTo(m_headNode) == -1) {
p.setNext(m_headNode);
m_headNode = p;
}
else {
Node r = m_headNode.getNext(), q = m_headNode;
for(int i = 2; i < length; i++) {
if(p.compareTo(r) == 1) {
q = r;
r = r.getNext();
}
else {
q.setNext(p);
p.setNext(r);
return;
}
}
q.setNext(p);
p.setNext(r);
}
}
}