java单链表的实现,自己写的,功能不完全,一般使用还是可以的,供大家参考

本文介绍了如何使用Java实现单链表数据结构,包括节点类Node和链表类LinkList的详细定义,实现了增、删、查、改等基本操作。通过一个测试类展示了这些操作的实际应用,如插入节点、获取节点、删除节点、替换节点数据等。
摘要由CSDN通过智能技术生成

单链表的逻辑就不多说了,别的文章有很多细致的分析,直接上代码

首先是节点的实现:

/**
 * 
 * 节点类型
 * 
 * @author 网络W信号
 *
 * @param <E>
 */
public class Node<E>{
	private Node<E> next;//下一节点地址
	private E e;//数据域
	
    //构造方法
	public Node (){
	}
	
	public Node (E e){
		this.e = e;
		next = null;
	}

    //构造器和读取器
	public Node<E> getNext() {
		return next;
	}

	public void setNext(Node<E> next) {
		this.next = next;
	}

	public E getE() {
		return e;
	}

	public void setE(E e) {
		this.e = e;
	}
}

接下来是单链表的实现:

/**
 * 实现链表功能
 * 
 * @author 网络W信号
 *
 * @param <E>
 */
public class LinkList <E>{
	
	private Node<E> head;//头结点
	private Node<E> last;//尾结点
	private int size = 0;//链表长度
	
	//创建链表
	public LinkList(){
		head = new Node<E>();
		last = head;
	}
	
	public LinkList(E e){
		head = new Node<E>();
		last = head;
	}
	
	/**
	 * 判断是否为空
	 * 
	 * @return 为空返回false,不为空返回true
	 */
	public boolean isEmpty(){
		if(head == last){
			return false;
		}
		return true;
	}
	
	/**
	 * 清空链表
	 */
	public void clear(){
		head = last;
	}
	
	/**
	 * 返回长度
	 * 
	 * @return
	 */
	public int size(){
		return size;
	}
	
	/**
	 * 查找并返回目标位置的节点
	 * 
	 * @param i (int)目标位置
	 * @return 目标节点
	 */
	public Node<E> find(int i){
		if(i < 0 || i >= size){
			return null;
		}
		Node<E> temp = head.getNext();
		for(int k = 0 ; k < i ; k ++){
			temp = temp.getNext();
		}
		return temp;
	}
	
	/**
	 * 查找并返回目标位置的数据域
	 * 
	 * @param i (int)目标位置
	 * @return 目标节点数据域
	 */
	public E getE(int i){
		if(i < 0 || i >= size){
			return null;
		}
		Node<E> temp = find(i);
		return temp.getE();
	}
	
	/**
	 * 按数据域内容查找节点位置,并返回位置I
	 * @param e (E)目标内容
	 * @return 返回元素i,-1为不存在
	 */
	public int getI(E e){
		E temp = e;
		int i;
		//找到指定位置
		for(i = 0 ; ; i ++){
			temp = getE(i);
			if(temp == e) {
				break;
			}
			if(temp == null){
				return -1;
			}
		}
		return i;
	}
	
	/**
	 * 判断数据域为e的节点是否在链表中
	 * 
	 * @param e 目标数据域
	 * @return 存在返回true,不存在返回false
	 */
	public boolean exist(E e){
		int i = getI(e);
		if(i == -1){
			return false;
		}
		return true;
	}
	
	/**
	 * 判断i位置是否存在节点
	 * 
	 * @param i 目标位置
	 * @return 存在返回true,不存在返回false
	 */
	public boolean exist(int i){
		if(find(i) == null){
			return false;
		}
		return true;
	}
	
	/**
	 * 在尾部添加数据域为e的节点
	 * 
	 * @param e 目标节点
	 */
	public void add(E e){
		Node<E> newNode = new Node<E>(e);
		last.setNext(newNode);
		last = newNode;
		size++;
	}
	
	/**
	 * 在指定位置(i)添加数据域为e的节点
	 * 
	 * @param e 数据域
	 * @param i 目标位置
	 */
	public void add(E e,int i){
		if(i >= 0 && i < size){
			Node<E> newNode = new Node<E>(e);
			//如果添加位置为第一个节点则改变头结点next地址
			if(i == 0){
				newNode.setNext(head.getNext());
				head.setNext(newNode);
			}
			else if(i == (size-1)){
				last.setNext(newNode);
				last = newNode;
			}
			else{
			newNode.setNext(find(i));
			find(i-1).setNext(newNode);
			}
		}
		//将在队列中的添加到最后
		else {
			add(e);
		}
		size++;
	}
	
	/**
	 * 删除指定位置的节点e
	 * 
	 * @param i (int)目标位置
	 */
	public void delete(int i){
		if(i >= 0 && i < size){
			Node<E> temp = find(i);
			//当删除第一个节点时,改变头结点的next
			if(i == 0){
				head.setNext(find(i+1));
			}
		
			find(i-1).setNext(temp.getNext());//删除k位置的节点
		}
		size--;
	}
	
	
	/**
	 * 删除所有拥有指定数据域(e)的节点
	 * 
	 * @param e (E)目标数据域的内容
	 */
	public void delete(E e){
		int i = getI(e);//查找目标位置
		if(i != -1){			
			Node<E> temp = find(i);
		
			//当删除第一个节点时,改变头结点的next
			if(i == 0){
				head.setNext(find(i+1));
			}
			find(i-1).setNext(temp.getNext());//删除k位置的节点
			size--;
			if(i < size){
				delete(e);
			}
		}
	}
	
	/**
	 * 修改指定位置(k)的数据域为(e)
	 * 
	 * @param e 修改后的数据域
	 * @param i 指定位置
	 */
	public void remodel(E e,int i){
		if(i >= 0 && i < size){
			find(i).setE(e);
		}
	}
	
	/**
	 * 修改所有指定数据域为e的节点的数据域为x
	 * 
	 * @param x 修改后的数据域
	 * @param e 指定数据域
	 */
	public void remodel(E x,E e){
		int i = getI(e);
		if(i != -1){
			find(i).setE(x);
			if(i < size){
				remodel(x,e);
			}
		}
		
	}
	
	/**
	 * 将指定位置i的节点替换为目标节点node
	 * 
	 * @param node 修改后的节点
	 * @param i 修改后的目标节点
	 */
	public void remodel(Node<E> node,int i){
		if(i >= 0 && i < size){
			find(i).setE(node.getE()) ;
		}
	}
	
	/**
	 * 将对应节点(node)替换为新节点newNode
	 * 
	 * @param newNode 修改后的节点
	 * @param node 修改前的目标节点
	 */
	public void remodel (Node<E> newNode,Node<E> node){
		int i = getI(node.getE());
		if(i != -1){
			find(i).setE(newNode.getE()) ;
		}
	}
	
	/**
	 * 输出链表的数据域
	 */
	public String toString(){
		String temp = new String();
		for(int i = 0 ; i < size ; i ++){
			
			if(i == 0 ){
				E e = getE(i);
				temp = (String)e;
			}
			
			else{
				E e = getE(i);
				temp = temp+","+(String)e;
			}
		}
		return temp;
	}
}

顺便提供一个测试类:

class Main{
	public static void main(String[] adsb){
		LinkList<String> a = new LinkList<String>();//创建新链表
		System.out.println(a.isEmpty());//判断是否为空

        //添加节点
		a.add("123");
		a.add("456");
		a.add("789");
		System.out.println(a.toString());//输出链表
		System.out.println(a.isEmpty());//再次判空
		System.out.println(a.size());//判断长度

        //在指定位置添加节点
		a.add("234",1);
		a.add("245",0);
		System.out.println(a.toString());

        //获取节点数据域与获得数据位置
		System.out.println(a.getE(1));
		System.out.println(a.getI("123"));

        //测试各种删除模式
		System.out.println(a.toString());//首先输出列表用于比对
		a.delete(1);//删除1的节点
		System.out.println(a.toString());
		a.delete("234");//删除数据域为“234”的节点	
		System.out.println(a.toString());

        //判断元素是否在单链表中
		System.out.println(a.exist("234"));
		System.out.println(a.exist("789"));
		
		//各种替换测试
		a.remodel("567", 2);//替换固定位置节点数据域
		System.out.println(a.toString());
		a.remodel("789","567");//用数据域替换节点数据域
		System.out.println(a.toString());
		Node<String> b = new Node<String>("789");//定义新的节点用于测试节点替换
		Node<String> c = new Node<String>("567");//同上
		a.remodel(c, 2);//固定位置的节点替换
		System.out.println(a.toString());
		a.remodel(b, c);//用节点替换节点
		System.out.println(a.toString());
		
        //测试清除方法
		a.clear();
		System.out.println(a.isEmpty());
	}
}

链表的逻辑部分还有很大优化的空间,还有很多功能没有实现,不过对于我这次的实验来说已经够用了,所以就先这样,把这个单链表放在这里当做备忘录,也希望对大家有所帮助。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值