【根据双向链表来自定义一个单向链表】

标题

 

public class 单链<T> {
    private int size;
    private Node<T> first;
    private Node<T> last;
    
    
    @Override
	public String toString() {
		StringBuilder sb = new StringBuilder("[");
		//从头结点开始逐个向后遍历
		Node<T> node=first;
		while(node!=null) {
			//获取结点内容
			T e=node.item;
			//拼接结点内容
			sb.append(e+",");
			//获取下一个结点
			node=node.next;
		}
		sb.setCharAt(sb.length()-1,']');
		return sb.toString();
	}
	/**
     * 队首插入法
     */
   public boolean addFirst(T item) {
        Node<T> node = new Node<>(item);
        if (first == null){
            first = node;
            last = node;
        }else {
            node.setNext(first);
            first = node;
        }
        size++;
        return true;
    }

    /**
     * 队尾插入法
     */
   public boolean addLast(T item) {
        Node<T> node = new Node<>(item);
        if (first == null){
            first = node;
        }else {
            last.next = node;
        }
        last = node;
        size++;
        return true;
    }

    /**
     * 元素插入到指定位置
     */
    public boolean add(int index, T item) {
        Node<T> node = new Node<>(item);

        if (index<0 || index>size){
            throw new IndexOutOfBoundsException("数据下标越界");
        } else if (index == 0) {
            return addFirst(item);
        } else if(index == size){
            last.next = node;
            last = node;
        }else {
            Node<T> temp = first;
            for (int i = 0; i < index - 1; i++) {
                temp = temp.next;
            }
            node.setNext(temp.next);
            temp.setNext(node);
        }
        size++;
        return true;
    }

    /**
     * 删除头节点
     */
    public T removeFirst() {
        if (first == null) {
            throw new IndexOutOfBoundsException("该链表为空!");
        } else {
            T item = first.item;
            first = first.next;
            size--;
            return item;
        }
    }

    /**
     * 删除尾节点
     */
    public T removeLast() {
        T item;
        if (first == null) {
            throw new IndexOutOfBoundsException("该链表为空!");
        } else if (first == last){
            item = first.item;
            first = null;
            last = null;
        }else {
            Node<T> temp = first;
            while (temp.next != last){
                temp = temp.next;
            }
            item = last.item;
            last = temp;
        }
        size--;
        return item;
    }

    /**
     * 删除指定位置的节点
     */
    public T remove(int index) {
        T item;
        if (index<0 || index>size){
            throw new IndexOutOfBoundsException("数据下标越界");
        } else if (index == 0) {
            return removeFirst();
        } else if(index == size-1){
            return removeLast();
        }else {
            Node<T> temp = first;
            for (int i = 0; i < index - 1; i++) {
                temp = temp.next;
            }
            Node<T> old = temp.next;
            temp.next = temp.next.next;
            item = old.item;
        }
        size--;
        return item;
    }

    /**
     * 根据下标获取对应的数据
     * */
    public T getItem(int index){
        if (index<0 || index>size){
            throw new IndexOutOfBoundsException("数据下标越界");
        }else {
            Node<T> node = first;
            for (int i = 0; i < index; i++) {
                node = node.getNext();
            }
            return node.getItem();
        }
    }
    
    /**
	 * 判断链表是否为空
	 * @return
	 */
	public boolean isEmpty() {
		return size==0;
	}
	
	/**
	 * 清空链表
	 * @param args
	 */
	public void clear() {
		//从头结点开始向后遍历
		//将每个结点后驱指针,结点内容置为null、
		Node<T> node=first;
		for(int i=0;i<size;i++) {
			//先获取下一个结点
			Node<T> next=node.next;
			//再将当前结点的后驱指针,结点内容置为null
			node.next=null;
			node.item=null;
			//切换到下一个结点
			node=next;
		}
		first=last=null;
		//计数归0
		size=0;
	}
    
    /**
	 * 根据下标获取结点
	 * @param index
	 * @return
	 */
	public Node<T> getNode(int index){
		//判断下标
		if(index<0 ||index>=size) {
			throw new IndexOutOfBoundsException("查找不到");
		}
		Node<T> node = null;
			node=first;
			for(int i=0;i<index;i++) {
				node=node.next;
		
		}
		return node;
	}
    
    /**
	 * 根据下标获得结点中内容,
	 * 没有查找到,返回-1
	 * @param index
	 * @return
	 */
	public T get(int index) {
		return getNode(index).item;
	}
    
    /**
	 * 根据传入的结点内容,查找该结点的下标
	 */
	public int indexOf(T t) {
		Node<T> node=first;
		if(t==null) {
			for(int i=0;i<size;i++) {
				if(node.item==null) {
					return i;
				}
				//切换到下一个结点
				node=node.next;
			}
		}else {
			for(int i=0;i<size;i++) {
				if(t.equals(node.item)) {
					return i;
				}
				//切换到下一个结点
				node=node.next;
			}
		}
		return -1;
	}


	/**
	 * 根据元素内容删除结点
	 * 			传入元素内容,多结点内容相同,只删除第一个
	 * @return
	 */
	public boolean remove(T t) {
		//根据内容查找结点下标
		int index=indexOf(t);
		if(index==-1) {//内容不存在
			return false;
			
		}
		//根据下标删除结点
		remove(index);
		return true;
	}
	
	/**
	 *判断是否包含指定内容结点
	 * @return
	 */
	public boolean contains(T t) {
		return indexOf(t)>0;
	}
	
	public T set(int index,T t) {
		//判断下标
		if(index<0 ||index>=size) {
			throw new IndexOutOfBoundsException("查找不到");
		}
	   //根据下标查找原来结点内容
		T oldValue =get(index);
		//根据下标查找结点
		Node<T> node=getNode(index);
		//替换内容
		node.item=t;
		return oldValue;
	}
    
	/**
	 * 代表链表上的每一个结点
	 * 泛型表示结点中内容的类型
	 */
    
    private static class Node<T>{
        private T item;//结点内容部分
        private Node<T> next;//后驱指针

        public T getItem() {
            return item;
        }
        public void setItem(T item) {
            this.item = item;
        }
        public Node(T item) {
            this.item = item;
        }
        public Node<T> getNext() {
            return next;
        }
        public void setNext(Node<T> next) {
            this.next = next;
        }
    }
    
		public static void main(String[] args) {
			 //创建单链表对象
	        单链<String> List = new 单链<>();
	        
	        List.addLast("aaa");
	        List.addLast("bbb");
	        List.addLast("ccc");
	        List.addLast("ddd");
	        List.addLast("eee");
	        
	        System.out.println(List.first);
	        System.out.println(List.last);

	        //插入尾结点
	        List.addLast("fff");
	        List.addLast("ggg");
	        System.out.println(List);

	        //插入头结点
	        List.addFirst("hhh");
	        System.out.println(List);

	        //插入到指定下标元素
	       List.add(2,"iii");
	        System.out.println(List);
	        
	        //根据下标获取结点
	        System.out.println(List.get(0));
			System.out.println(List.get(1));
			System.out.println(List.get(2));
			System.out.println(List.get(3));
			
			//根据传入的结点内容,查找该结点的下标
			System.out.println(List.indexOf(null));
			System.out.println(List.indexOf("aaa"));
			System.out.println(List.indexOf("bbb"));
	
			//清空
			List.clear();
			System.out.println(List);
		}
	
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

God Zhang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值