双向链表的简单操作(Java)

//定义一个链表标准接口
interface LinkList{
    //增加链表结点,返回是否成功
    boolean add(Object data);

    //指定内容结点在链表中是否存在,返回节点索引
    int isExist(Object data);

    //删除指定内容结点,成功是否成功
    boolean remove(Object data);

    //修改指定下标结点的内容
    void set(int index, Object newData);

    //返回指定下标结点的内容
    Object get(int index);

    //清空链表
    void clear();

    //将链表转换为数组,返回所有节点的内容
    Object[] toArray();

    //获取链表长度
    int size();

    //遍历打印链表
    void printLinkList();


}

//提供数据、节点间的关系、具体操作
class LinkListDo implements LinkList{
    private Node head;//链表头结点
    private Node tail;//链表尾结点
    private int size;//链表长度

    //内部类Node,处理节点间的关系
    private class Node{
        private Node prev;//上一个节点
        private Object data;//节点值
        private Node next;//下一个节点

        //构造方法
        public Node(Node prev,Object data,Node next){
            this.prev = prev;
            this.data = data;
            this.next = next;
        }
    }

    //*********链表的相关操作***********

    //增加链表结点,返回是否成功
    public boolean add(Object data){
        //找到链表的尾节点(尾指针指向的节点)
        Node node = this.tail;
        //创建新节点,让新节点前驱为元链表的尾节点,新节点猴急为null
        Node newNode = new Node(node,data,null);
        //修改尾指针的指向
        this.tail = newNode;

        if(this.head == null){//当链表为空时,头指针指向新建结点
            this.head = newNode;
        }
        else{//链表不为空时,原链表尾节点后继 为 新节点

            node.next = newNode;
        }
        //链表长度+1
        this.size++;
        return true;
    }

    //指定内容结点在链表中是否存在,返回节点索引
    public int isExist(Object data){
        if(data == null){
            int i = 0;
            for(Node node=this.head; node!=null; node=node.next){
                if(node == null){
                    return i;
                }
                i++;
            }
        }else{
            int i=0;
            for(Node node=this.head; node!=null; node=node.next){
                if(node.data == data){
                    return i;
                }
                i++;
            }
        }
        return -1;
    }
    //删除第一个值为data的结点,成功是否成功
    public boolean remove(Object data){
        if(data == null){
            for(Node node=this.head; node!=null; node=node.next){
                if(node.data == null){
                    deleteNode(node);
                    return true;
                }
            }
        }else{
            for(Node node=this.head; node!=null; node=node.next){
                if(node.data == data){
                    deleteNode(node);
                    return true;
                }
            }
        }
        return false;
    }

    //修改指定下标结点的内容
    public void set(int index, Object newData){
        if(index<0 || index>=size){
            System.out.println("下标越界!无法修改");
        }else{
            Node node = getNode(index);
            node.data = newData;
        }
    }

    //返回指定下标结点的内容
    public Object get(int index){
        if(index<0 || index>=size){
            return null;
        }
        return getNode(index).data;
    }

    //清空链表
    public void clear(){
        for(Node node=this.head; node!=null;){
            node.data = null;
            Node temp = node.next;
            node = node.prev = node.next = null;
            node = temp;
            this.size--;
        }
    }

    //将链表转换为数组,返回数组
    public Object[] toArray(){
        Object[] datas = new Object[size];
        int i = 0;//记录数组下标
        for(Node node=head; node!=null;node=node.next){
            datas[i] = node.data;
            i++;
        }
        return datas;
    }

    //获取链表长度
    public int size(){
        return this.size;
    }

    //遍历打印链表
    public void printLinkList(){
        if(this.size == 0){
            System.out.println("链表为空!");
        }else{
            //将链表转化为数组
            //方法1
            // Object[] datas = new LinkListDo().toArray();
            //方法2
            Object[] datas = this.toArray();
            //遍历打印
            for(Object data:datas){
                System.out.print(data+" ");
            }
            System.out.println();
        }

    }

    //根据指定索引取得具体节点
    private Node getNode(int index){
        if(index<0 || index>=size){
            return null;
        }

        if(index < (size>>1)){
            Node node = this.head;
            for(int i=0; i<index; i++){
                node = node.next;
            }
            return node;
        }

        Node node = this.head;
        for(int i=size-1; i>index; i--){
            node = node.prev;
        }
        return node;
    }


    //删除节点node,并返回所删节点的值
    private Object deleteNode(Node node){
        Node prev = node.prev;
        Object data = node.data;
        Node next = node.next;

        //后继
        if(prev == null){//如果node接待是头节点
            this.head = next;
        }else{
            prev.next = next;
            node.prev = null;
        }

        //前驱
        if(next == null){//如果node节点是尾节点
            this.tail = prev;
        }else{
            next.prev = prev;
        }

        node.data = null;
        this.size--;
        return data;
    }
}

//测试类
public class LinkListTest{
    public static void main(String[] args){
        LinkList m = new LinkListDo();
        //.out.println(m.add(1));
        m.add(0);
        m.add(1);
        m.add(2);
        m.add(3);
        m.add(4);
        m.add(5);
        m.add(6);
        m.add(7);
        m.add(7);
        m.printLinkList();
        System.out.println("链表长度为:"+m.size());
        System.out.println("7下标为:"+m.isExist(7));
        m.remove(7);
        m.printLinkList();

        m.set(2,88);
        m.printLinkList();

        m.get(2);
        m.clear();
        m.printLinkList();

    }
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值