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


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

    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);
    		}
    	}
    }


  • 相关阅读:
    guaguia
    webapp手机移动端开发技巧
    两个数组对象对比
    json 根据某个子,寻找父节点的算法
    递归写法
    数组归类
    视频点击按钮下载
    微信小程序 直接跳转到首页
    iframe 跨域传值
    判断对象是否为空
  • 原文地址:https://www.cnblogs.com/llguanli/p/7122232.html
Copyright © 2020-2023  润新知