数据结构之链表 java实现

链表是一种常见的数据结构,是一种线性表,它是物理单元上非连续存储的结构单元(这一点和数组恰恰相反),链表的基本组成包括一个存储数据的节点和一个指向下一个节点的引用或者指针。``
链表的应用可以用链表实现最基本的栈和队列。
链表的优缺点链表可以灵活的利用内存空间,并且插入和删除的效率也高于数组,和数组相比失去了随机访问的能力,同时由于增加了指针域增加了内存空间的开销。
今天我们先学习如何用java实现单链表。

package com.lut.list;

public class LinkedList<E> {
	private class Node {
		public E e;//存储的元素
		public Node next;//指向下一个节点的引用

		public Node(E e, Node next) {//构造方法
			this.e = e;
			this.next = next;
		}

		public Node(E e) {
			this(e, null);
		}

		public Node() {
			this(null, null);
		}
		
		@Override
		public String toString() {
			return e.toString();
		}
	}
	private Node dummyHead;//虚拟头节点,存储的元素是null
	private int size;//链表的大小
	public LinkedList() {
		dummyHead=new Node(null,null);
		size=0;
	}
	public int getSize() {//得到链表的大小
		return size;
	}
	public boolean isEmpty(){//判断链表是不是为空
		return size==0;
	}
	public void addFirst(E e) {//在链表的头节点添加元素
		//Node node=new Node(e);
		//node.next=head;
		//head=node;
		//size++;
		add(e,0);
		
	}
	public void add(E e,int index) {//在链表的中间添加元素
		if(index<0||index>size)
			throw new IllegalArgumentException("index is error");
		
			Node prev=dummyHead;
			for(int i=0;i<index;i++)
				prev=prev.next;
			//Node node=new Node(e);
			//node.next=prev.next;
			//prev.next=node;
			prev.next=new Node(e,prev.next);
			size++;
		
		
		
	}
	
	public void addLast(E e) {//往链表的尾部添加元素
		add(e,size );
		
	}
	public E get(int index) {//查询的方法
		if(index<0||index>size)
			throw new IllegalArgumentException("index is error");
		Node cur=dummyHead.next;
		for(int i=0;i<index;i++)
			cur=cur.next;
		return cur.e;
	}
	public E getFirst() {
		return get(0);
	}
	public E getLast() {
		return get(size);
	}
	public void set(int index,E e) {//修改的方法
	if(index<0||index>size)
		throw new IllegalArgumentException("index is error");
	Node cur=dummyHead.next;
	for(int i=0;i<index;i++)
		cur=cur.next;
	cur.e=e;
}
	//查找链表中是否有元素e
	public boolean contains(E e) {
		Node cur=dummyHead.next;
		while(cur!=null) {
			if(cur.e.equals(e))
				return true;
			cur=cur.next;
		}
		return false;
	}
	//链表元素的删除
	public E remove(int index) {
		if(index<0||index>size)
			throw new IllegalArgumentException("index is error");
		Node prev=dummyHead;
		for(int i=0;i<index;i++) {
			prev=prev.next;
		}
		Node retNode=prev.next;
		prev.next=retNode.next;
		retNode.next=null;
		size--;
		return retNode.e;
	}
	public E removeFirst() {
		return remove(0);
	}
	public E removeLast() {
		return remove(size-1);
	}
	public String  toString() {
		StringBuilder res=new StringBuilder();
		Node cur=dummyHead.next;
		while(cur!=null) {
			res.append(cur+"->");
			cur=cur.next;
		}
		res.append("NULL");
		return res.toString();
		
	}
	
}

链表的应用之栈,栈的特点是先进后出。用链表的头部模拟栈顶,从链表的头部添加元素,从链表的头部删除元素。

先提供一个接口,模拟栈的api
package com.lut.list;

public interface Stack<E> {
	int getSize();

	boolean isEmpty();

	void push(E e);

	E pop();

	E peek();
}
package com.lut.list;

public class LinkedListStack<E>  implements Stack<E>{
	private LinkedList<E> list;
	public LinkedListStack() {
		list=new LinkedList<E>();
	}

	@Override
	public int getSize() {
		// TODO Auto-generated method stub
		return list.getSize();
	}

	@Override
	public boolean isEmpty() {
		// TODO Auto-generated method stub
		return list.isEmpty();
	}

	@Override
	public void push(E e) {
		// TODO Auto-generated method stub
		list.addFirst(e);
	}

	@Override
	public E pop() {
		// TODO Auto-generated method stub
		return list.removeFirst();
	}

	@Override
	public E peek() {
		// TODO Auto-generated method stub
		return list.getFirst();
	}
	public String toString() {
		StringBuilder res=new StringBuilder();
		res.append("stack top");
		res.append(list);
		return res.toString();
	}

	
}
这个过程就是一个简单的栈的实现

链表的应用之队列的实现,队列的特点是先进先出,用链表的头部模拟队列的头部,用链表的尾部模拟队列的尾部。从队列的头部删除元素,从队列的尾部添加元素。为了实现这种机制,前面的链表实现需要做出一定的修改,需要引入一个tail尾节点。

先提供一个接口用于模拟队列的api
package com.lut.list;

public interface Queue<E> {
	int getSize();
	boolean iszEmpty();
	void enqueue(E e);
	E dequeue();
	E getFront();

}
package com.lut.list;



public class LinkedListQueue<E> implements Queue<E> {
	private class Node {
		public E e;
		public Node next;

		public Node(E e, Node next) {
			this.e = e;
			this.next = next;
		}

		public Node(E e) {
			this(e, null);
		}

		public Node() {
			this(null, null);
		}

		@Override
		public String toString() {
			return e.toString();
		}
	}
	private Node head,tail;//头节点,尾节点
	private int size;
	public LinkedListQueue() {
		// TODO Auto-generated const+ructor stub
		tail=null;
		head=null;
		size=0;
	}

	@Override
	public int getSize() {
		// TODO Auto-generated method stub
		return size;
	}

	@Override
	public boolean iszEmpty() {
		// TODO Auto-generated method stub
		return size==0;
	}

	@Override
	public void enqueue(E e) {//入队操作
		// TODO Auto-generated method stuble3
		if(tail==null) {
			tail=new Node(e);
			head=tail;
		}else {
			tail.next=new Node(e);
			tail=tail.next;
		}
		size++;
		
	}

	@Override
	public E dequeue() {
		// TODO Auto-generated method stub
		if(iszEmpty())
			throw new IllegalArgumentException("queue is isempty");
		Node retNode=head;
		head=head.next;
		retNode.next=null;//使出队的元素脱离队列
		if(head==null)//如果队列只有一个元素,进行出队的操作之后,需要将尾节点也指向null
			tail=null;
		size--;
		return retNode.e;
	}

	@Override
	public E getFront() {//获取队列头部的元素
		// TODO Auto-generated method stub
		if(iszEmpty())
			throw new IllegalArgumentException("queue is isempty");
		return head.e;
	}
	public String toString() {
		StringBuilder res=new StringBuilder();
		res.append("Queue: front");
		Node cur=head;
		while(cur!=null) {
			res.append(cur+"->");
			cur=cur.next;
		}
		res.append("Null tail");
		return res.toString();
	}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值