【数据结构】模拟Java中的双向链表

本文介绍了如何通过创建Node类和MyLinkedList类来实现一个简易的双向链表,并解决了原始版本的数据类型不安全问题,通过引入泛型实现元素类型的约束。关键步骤包括添加元素、获取元素数量和按索引获取元素。
摘要由CSDN通过智能技术生成


**前言:**LinkedList底层是使用双向链表实现的,我们就来实现一个简易的MyLinkedList吧

分析:首先实现一个Node类用来存放所需存储的内容上一个元素的地止和下一个元素的地址,再实现一个MyLinkedList类在里面定义Node属性first和last用来表示首尾节点,定义一个计数器用来表示添加次数,然后来实现add、size、get方法,具体实现过程请看0x001

0x000 Node类

由分析得,我们得创建一个Node类,可以封装三个属性,用来上一个节点地址下一个节点地址所需存储的内容,并实现toString方法

public class Node {
	//三个属性
	//上一个节点的地址
	private Node pre;
	//当前存入的元素
	private Object obj;
	//下一个节点的地址
	private Node next;
	public Node getPre() {
		return pre;
	}
    //封装节点的属性
	public void setPre(Node pre) {
		this.pre = pre;
	}
	public Object getObj() {
		return obj;
	}
	public void setObj(Object obj) {
		this.obj = obj;
	}
	public Node getNext() {
		return next;
	}
	public void setNext(Node next) {
		this.next = next;
	}
	@Override
	public String toString() {
		return "Node [pre=" + pre + ", obj=" + obj + ", next=" + next + "]";
	}
}

0x001 MyLinkedList类

我们实现了Node类后,就来实现MyLinkedList类吧。

  1. 定义属性和构造方法
public class MyLinkedList{
    //首尾元素
    Node first;
    Node last;
    //计时器
    int count=0;
    public MyLinkedList(){}
}
  1. 实现add方法:添加元素
public class MyLinkedList{
    //add方法添加元素
    public void add(Object obj){
        //如果first等于null,说明第一次添加元素
        if(first==null){
            //创建一个节点对象,并存入传入的元素
            Node n=new Node();
            //由于第一次添加,节点中的上一个节点使用null
            n.setPre(null);
            //在节点中存入元素
            n.setObj(obj);
            //由于第一次添加,节点中的下一个节点使用null
            n.setNext(null);
            //由于第一次添加,所以首尾节点(first和last)等于obj
            first=n;
            last=n;
        }else{
            //first不等于null,说明不是第一次添加元素,每次添加元素都一样了
            //创建节点对象
            Node n=new Node();
            //在节点中的上一个节点存入last
            n.setPre(last);
            //在节点中存入元素
            n.setObj(Obj);
            //在节点中的下一个节点存入null
            n.setNext(null);
            //在last中设置下一个节点为n
            last.setNext(n);
            //将n赋值给last
            last=n;
        }
        //添加元素的次数
        count++
    }
}

3.size方法:获取元素个数

public class MyLinkedList{
    public int size(){
        return count;
    }
}

4.get方法:下标从零开始获取元素数据

public class MyLinkedList{
    //下标从零开始获取元素数据
    public Object get(int index){
        Node n=first;
        //寻找下标为index的节点
        for(int i=0;i<index;i++){
            n=n.getNext();
        }
        return n.getObj();
    }
}

5.整理得:add方法、size方法、get方法构成简易的MyLinkedList类

public class MyLinkedList{
    //首尾元素
    Node first;
    Node last;
    //计时器
    int count=0;
    public MyLinkedList(){}
    //add方法添加元素
    public void add(Object obj){
        //如果first等于null,说明第一次添加元素
        if(first==null){
            //创建一个节点对象,并存入传入的元素
            Node n=new Node();
            //由于第一次添加,节点中的上一个节点使用null
            n.setPre(null);
            //在节点中存入元素
            n.setObj(obj);
            //由于第一次添加,节点中的下一个节点使用null
            n.setNext(null);
            //由于第一次添加,所以首尾节点(first和last)等于obj
            first=n;
            last=n;
        }else{
            //first不等于null,说明不是第一次添加元素,每次添加元素都一样了
            //创建节点对象
            Node n=new Node();
            //在节点中的上一个节点存入last
            n.setPre(last);
            //在节点中存入元素
            n.setObj(Obj);
            //在节点中的下一个节点存入null
            n.setNext(null);
            //在last中设置下一个节点为n
            last.setNext(n);
            //将n赋值给last
            last=n;
        }
        //添加元素的次数
        count++;
    }
    public int size(){
        return count;
    }
     //下标从零开始获取元素数据
    public Object get(int index){
        Node n=first;
        //寻找下标为index的节点
        for(int i=0;i<index;i++){
            n=n.getNext();
        }
        return n.getObj();
    }
}

0x002 Test类

public class Test{
	public static void main(String[] args) {
        //创建MyLinkedList对象
		MyLinkedList mll=new MyLinkedList();
        //添加元素
		mll.add("你好");
		mll.add("3Q");
		mll.add("zhoukali");
        //获取下标为2的元素
		System.out.println(mll.get(2));
        System.out.println("-----------------");
        //遍历MyLinkedList集合
		for(int i=0;i<mll.size();i++){
			System.out.println(mll.get(i));
		}
	}
}

运行效果:
在这里插入图片描述

0x003 解决数据类型安全问题

实现泛型版的MyLinkedList

**原因:**上面那种版本有一个明显的缺陷,数据类型不安全,不能固定一个相同的数据,为了约束数据类型我们可以实现一个泛型版的MyLinkedList

**改进:**我们把Node接口放在LinkedList类中,实现内部类方便管理

上代码:MyLinkedList类

public class MyLinkedList<E>{
	class Node {
		//三个属性
		//上一个元素的地址
		private Node pre;
		//当前存入的元素
		private E obj;
		//下一个元素的地址
		private Node next;
		public Node getPre() {
			return pre;
		}
		 //封装节点的属性
		public void setPre(Node pre) {
			this.pre = pre;
		}
		public E getObj() {
			return obj;
		}
		public void setObj(E obj) {
			this.obj = obj;
		}
		public Node getNext() {
			return next;
		}
		public void setNext(Node next) {
			this.next = next;
		}
		@Override
		public String toString() {
			return "Node [pre=" + pre + ", obj=" + obj + ", next=" + next + "]";
		}
	}
    //首尾元素
    Node first;
    Node last;
    //计时器
    int count=0;
    public MyLinkedList(){}
    //add方法添加元素
    public void add(E obj){
        //如果first等于null,说明第一次添加元素
        if(first==null){
            //创建一个节点对象,并存入传入的元素
            Node n=new Node();
            //由于第一次添加,节点中的上一个节点使用null
            n.setPre(null);
            //在节点中存入元素
            n.setObj(obj);
            //由于第一次添加,节点中的下一个节点使用null
            n.setNext(null);
            //由于第一次添加,所以首尾节点(first和last)等于obj
            first=n;
            last=n;
        }else{
            //first不等于null,说明不是第一次添加元素,每次添加元素都一样了
            //创建节点对象
            Node n=new Node();
            //在节点中的上一个节点存入last
            n.setPre(last);
            //在节点中存入元素
            n.setObj(obj);
            //在节点中的下一个节点存入null
            n.setNext(null);
            //在last中设置下一个节点为n
            last.setNext(n);
            //将n赋值给last
            last=n;
        }
        //添加元素的次数
        count++;
    }
    public int size(){
        return count;
    }
     //下标从零开始获取元素数据
    public E get(int index){
        Node n=first;
        //寻找下标为index的节点
        for(int i=0;i<index;i++){
            n=n.getNext();
        }
        return n.getObj();
    }
}

**测试一下:**Test类和运行结果

class Test{
	public static void main(String[] args) {
		MyLinkedList<String> mll=new MyLinkedList<String>();
		mll.add("你好");
		mll.add("3Q");
		mll.add("zhoukali");
		System.out.println(mll.get(2));
		System.out.println("-----------------");
		for(int i=0;i<mll.size();i++){
			System.out.println(mll.get(i));
		}
	}
}

在这里插入图片描述

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值