链表是数据结构的基础内容之一,下面就链表操作中的创建链表、打印链表、求取链表长度、判断链表是否为空、查找结点、插入结点、删除结点、逆转链表、连接链表、链表结点排序等进行总结。
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); } } }
时间: 2024-10-09 18:17:29