java实现链表

Java实现链表

单向链表:单向链表是最简单、最基础的链表,它的一个结点(node)分两部分,第一部分存储结点的数据信息(data),第二部分存储指向下一结点的地址(next)信息。最后一个结点(链尾)指向一个空地址(null)。单向链表一般只在链表表头(链头)结点的位置插入元素,这样每次新加入的元素都会在链头位置,而最先加入的元素会在链尾位置。删除操作时,如果在链头位置删除,只需要把头结点指向其下一个结点即可;如果是在中间位置删除,只需要将其前一个结点指向其下一个结点即可。单向链表示意图如下图所示:
在这里插入图片描述
代码实现:

import java.util.Stack;
public class LinkedListOnePoint {
    private Node head;  //头结点
    private int size;  //链表长度,即链表中结点数量
    
    public LinkedListOnePoint(){
        head = null;
        size = 0;
    }
    
    //私有内部类,代表链表每个结点
    private class Node{
        private Object data;  //链表结点的值
        private Node next;  //指向的下一个结点
        public Node(Object data){
            this.data = data;
        }
    }
    
    //判断链表是否为空
    public boolean isEmpty(){
        return size==0?true:false;
    }
    
    //返回链表长度
    public int size(){
        return size;
    }
    
    //查看链表头结点,不移除
    public Object headNode(){
        if(size == 0) return null;
        return head.data;
    }
    
    //在链表表头插入一个结点(入栈)
    public void insertInHead(Object obj){
        Node newNode = new Node(obj);
        if(size == 0){
            head = newNode;
        }else{
            newNode.next = head;
            head = newNode;
        }
        size++;
    }
    
    //删除链表表头结点(出栈)
    public Object deleteHeadNode(){
        if(size == 0) return null;
        Object obj = head.data;
        if(head.next == null){
            head = null;  //只有一个结点
        }else{
            head = head.next;
        }
        size--;
        return obj;
    }
    
    //链表查找:判断链表中是否包含某个元素
    public boolean containObject(Object obj){
        if(size == 0) return false;
        Node n = head;
        while(n != null){
            if(n.data == obj) return true;
            else n = n.next;
        }
        return false;
    }
    
    //删除链表中的指定结点(如果包含多个指定结点,只会删除第一个)
    public boolean deleteNode(Object obj){
        if(size == 0){
            System.out.println("链表为空!");
            return false;
        }
        //先在链表中查询是否包含该结点,找到之后获取该结点和其前一个结点
        Node previous = null;  //前一个结点
        Node current = head;  //当前结点
        while(current.data != obj){
            if(current.next == null){
                System.out.println("没有找到该结点!");
                return false;
            }
            previous = current;
            current = current.next;
        }
        if(current == head){
            this.deleteHeadNode();
        }else{
            previous.next = current.next;
            size--;
        }
        return true;
    }
    
    //正向打印链表
    public void display(){
        if(size == 0) System.out.println("链表为空!");
        Node n = head;
        while(n != null){
            System.out.print("<-"+n.data);
            n = n.next;
        }
        System.out.println();
    }
    
    //反向打印链表(用栈)
    public void printListFromTailToHead(Node node){
        if(node == null) System.out.println("链表为空!");
        Stack<Integer> sta = new Stack<Integer>();
        while(node != null){
            sta.push((Integer) node.data);  //先将链表压入栈中
            node = node.next;
        }
        while(!sta.empty()){
            System.out.print(sta.pop()+"<-");  //出栈
        }
        System.out.println();
    }
    
    //反向打印链表(递归)
    public void printListFromTailToHeadDiGui(Node node){
        if(node == null){
            System.out.println("链表为空!");
        }else{
            if(node.next != null){
                printListFromTailToHeadDiGui(node.next);
            }
            System.out.print(node.data+"<-");
        }
    }
    
    
    public static void main(String[] args) {
        LinkedListOnePoint list = new LinkedListOnePoint();
        System.out.println(list.isEmpty());            //true
        System.out.println(list.size());               //0
        list.display();                                //链表为空!
        list.printListFromTailToHead(list.head);       //链表为空!
        
        list.insertInHead(0);
        list.insertInHead(1);
        list.insertInHead(2);
        list.insertInHead(3);        
        list.display();                                //<-3<-2<-1<-0
        list.printListFromTailToHead(list.head);       //0<-1<-2<-3<-
        list.printListFromTailToHeadDiGui(list.head);  //0<-1<-2<-3<-
        System.out.println(list.isEmpty());            //false
        System.out.println(list.size());               //4
        System.out.println(list.containObject(1));     //true
    }
}

双向链表:前面的几种链表只能从头结点遍历到尾结点这一个方向,每个结点都只能指向其下一个结点。而双向链表的每个结点既能指向下一个结点,又能指向前一个结点,双向链表既能从头结点向尾结点遍历,又能从尾结点向头结点遍历,既有一个头结点,又有一个尾结点。
在这里插入图片描述
代码实现:

/*
 * 双向链表
 * 单向链表只可向一个方向遍历,一般查找一个结点的时候需要从第一个结点开始每次访问下一个结点,一直访问到需要的位置。
 * 双向链表的每个结点都有指向的前一个结点和后一个节点,既有链表表头又有表尾,即可从链头向链尾遍历,又可从链尾向链头遍历。
 * LinkedList中的私有静态内部类Node实际上就是一个双向链表,<E>代表泛型,指明结点的数据类型
 * private static class Node<E> {
        E item;
        Node<E> next;
        Node<E> prev;

        Node(Node<E> prev, E element, Node<E> next) {
            this.item = element;
            this.next = next;
            this.prev = prev;
        }
    }
 */
public class LinkedListTwoDirections {
    private Node head;  //头结点
    private Node tail;  //尾结点
    private int size;  //链表长度,即链表中结点数量
    
    public LinkedListTwoDirections(){
        head = null;
        tail = null;
        size = 0;
    }
    
    //私有内部类,代表链表每个结点
    private class Node{
        private Object data;    //链表结点的值
        private Node previous;  //当前结点指向的前一个结点
        private Node next;      //当前结点指向的下一个结点
        public Node(Object data){
            this.data = data;
        }
    }
    
    //判断链表是否为空
    public boolean isEmpty(){
        return size==0?true:false;
    }
    
    //返回链表长度
    public int size(){
        return size;
    }
    
    //查看链表头结点,不移除
    public Object headNode(){
        if(size == 0) return null;
        return head.data;
    }
    
    //查看链表尾结点,不移除
    public Object tailNode(){
        if(size == 0) return null;
        return tail.data;
    }
    
    //在链表表头插入一个结点
    public void insertInHead(Object obj){
        Node newNode = new Node(obj);
        if(size == 0){
            head = newNode;
            tail = newNode;
        }else{
            newNode.next = head;
            head.previous = newNode;
            head = newNode;
        }
        size++;
    }
    
    //在链表表尾插入一个结点
    public void insertInTail(Object obj){
        Node newNode = new Node(obj);
        if(size == 0){
            head = newNode;
            tail = newNode;
        }else{
            newNode.previous = tail;
            tail.next = newNode;
            tail = newNode;
        }
        size++;
    }
    
    //删除链表表头结点
    public Object deleteHeadNode(){
        if(size == 0) return null;
        Object obj = head.data;
        if(head.next == null){  //只有一个结点
            head = null;
            tail = null;
        }else{
            head = head.next;
            head.previous = null;
        }
        size--;
        return obj;
    }
    
    //删除链表表尾结点
    public Object deleteTailNode(){
        if(size == 0) return null;
        Object obj = tail.data;
        if(tail.previous == null){  //只有一个结点
            head = null;
            tail = null;
        }else{
            tail = tail.previous;
            tail.next = null;
        }
        size--;
        return obj;
    }
    
    //正向打印链表
    public void display(){
        if(size == 0) System.out.println("链表为空!");
        Node n = head;
        while(n != null){
            System.out.print("<-"+n.data);
            n = n.next;
        }
        System.out.println();
    }
    
    public static void main(String[] args) {
        LinkedListTwoDirections list = new LinkedListTwoDirections();
        System.out.println(list.isEmpty());            //true
        System.out.println(list.size());               //0
        list.display();                                //链表为空!
        
        list.insertInHead(0);
        list.insertInHead(1);
        list.insertInHead(2);
        list.insertInHead(3);        
        list.display();                                //<-3<-2<-1<-0
        System.out.println(list.deleteHeadNode());     //3
        
        list.insertInTail(1);
        list.insertInTail(2);
        list.display();                                //<-2<-1<-0<-1<-2
        
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值