首页 > 代码库 > 数据结构之链表单向操作总结

数据结构之链表单向操作总结

链表是数据结构的基础内容之一,下面就链表操作中的创建链表、打印链表、求取链表长度、判断链表是否为空、查找结点、插入结点、删除结点、逆转链表、连接链表、链表结点排序等进行总结。

1.创建表示结点的类,因为链表操作中需要比较结点,因此结点需要实现comparable接口。

public class Node implements Comparable<Node> {
	private Object data;
	private Node next;
	
	//构造函数
	public Node() {
		this.data = http://www.mamicode.com/null;>
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);
		}
	}
}