单链表和双链表

本文深入探讨了链表和双端链表的基本概念、实现方式及操作方法,包括插入、删除、查找等核心功能,展示了链表在数据结构中的应用与灵活性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

单链表:是一个Node,存储当前对象,并指向下一个next,;插入在第一位Node,next指向原来的first

单链表:只保存第一个node的引用,

双端链表:保存两个node的引用,第一个和最后一个node,可以从第一个插入,也可以从最后一个插入,也可以从头部和尾部删除

/*
 * 链结点,相当于是车厢
 */
public class Node {
    //数据域
    public long data;
    //指针域
    public Node next;
    
    public Node(long value) {
        this.data = value;
    }
    
    /**
     * 显示方法
     */
    public void display() {
        System.out.print(data + " ");
    }
}

/*
 * 链表,相当于火车
 */
public class LinkList {
    //头结点
    private Node first;
    
    public LinkList() {
        first = null;
    }
    
    /**
     * 插入一个结点,在头结点后进行插入
     */
    public void insertFirst(long value) {
        Node node = new Node(value);
        node.next = first;
        first = node;
    }
    
    /**
     * 删除一个结点,在头结点后进行删除
     */
    public Node deleteFirst() {
        Node tmp = first;
        first = tmp.next;
        return tmp;
    }
    
    /**
     * 显示方法
     */
    public void display() {
        Node current = first;
        while(current != null) {
            current.display();
            current = current.next;
        }
        System.out.println();
    }
    
    /**
     * 查找方法
     */
    public Node find(long value) {
        Node current = first;
        while(current.data != value) {
            if(current.next == null) {
                return null;
            }
            current = current.next;
        }
        return current;
    }
    
    /**
     * 删除方法,根据数据域来进行删除
     */
    public Node delete(long value) {
        Node current = first;
        Node previous = first;
        while(current.data != value) {
            if(current.next == null) {
                return null;
            }
            previous = current;
            current = current.next;
        }
        
        if(current == first) {
            first = first.next;
        } else {
            previous.next = current.next;
        }
        return current;
        
    }
}

public static void main(String[] args) {
        LinkList linkList = new LinkList();
        linkList.insertFirst(34);
        linkList.insertFirst(23);
        linkList.insertFirst(12);
        linkList.insertFirst(0);
        linkList.insertFirst(-1);
        
//        linkList.display();
//        
//        linkList.deleteFirst();
//        linkList.display();
//        
//        Node node = linkList.find(23);
//        node.display();
        
        Node node1 = linkList.delete(0);
        node1.display();
        System.out.println();
        linkList.display();
    }

2、双端链表

/*
 * 链结点,相当于是车厢
 */
public class Node {
    //数据域
    public long data;
    //指针域
    public Node next;
    public Node previous;
    
    public Node(long value) {
        this.data = value;
    }
    
    /**
     * 显示方法
     */
    public void display() {
        System.out.print(data + " ");
    }
}

public class DoubleLinkList {
    //头结点
    private Node first;
    //尾结点
    private Node last;
    
    public DoubleLinkList() {
        first = null;
        last = null;
    }
    
    /**
     * 插入一个结点,在头结点后进行插入
     */
    public void insertFirst(long value) {
        Node node = new Node(value);
        if(isEmpty()) {
            last = node;
        } else {
            first.previous = node;
        }
        node.next = first;
        first = node;
    }
    
    /**
     * 插入一个结点,从尾结点进行插入
     */
    public void insertLast(long value) {
        Node node = new Node(value);
        if(isEmpty()) {
            first = node;
        } else {
            last.next = node;
            node.previous = last;
        }
        last = node;
    }
    
    /**
     * 删除一个结点,在头结点后进行删除
     */
    public Node deleteFirst() {
        Node tmp = first;
        if(first.next == null) {
            last = null;
        } else {
            first.next.previous = null;
        }
        first = tmp.next;
        return tmp;
    }
    
    /**
     * 删除结点,从尾部进行删除
     */
    public Node deleteLast() {
        Node tmp = last;
        if(first.next == null) {
            first = null;
        } else {
            last.previous.next = null;
        }
        last = last.previous;
        return last;
    }
    
    /**
     * 显示方法
     */
    public void display() {
        Node current = first;
        while(current != null) {
            current.display();
            current = current.next;
        }
        System.out.println();
    }
    
    /**
     * 查找方法
     */
    public Node find(long value) {
        Node current = first;
        while(current.data != value) {
            if(current.next == null) {
                return null;
            }
            current = current.next;
        }
        return current;
    }
    
    /**
     * 删除方法,根据数据域来进行删除
     */
    public Node delete(long value) {
        Node current = first;
        while(current.data != value) {
            if(current.next == null) {
                return null;
            }
            current = current.next;
        }
        
        if(current == first) {
            first = first.next;
        } else {
            current.previous.next = current.next;
        }
        return current;
        
    }
    
    /**
     * 判断是否为空
     */
    public boolean isEmpty() {
        return (first == null);
    }
}
public static void main(String[] args) {
        DoubleLinkList dl = new DoubleLinkList();
        dl.insertLast(45);
        dl.insertLast(56);
        dl.insertLast(90);
        dl.display();
        
        
        while(!dl.isEmpty()) {
            dl.deleteFirst();
            dl.display();
        }
    }

单链表双链表是两种常见的链表结构,它们在数据存储、操作效率以及适用场景上存在显著区别。 ### 单链表 单链表中的每个节点仅包含一个指向下一个节点的指针(通常称为`next`),这使得它只能从头到尾进行单向遍历。这种结构相对简单,占用的内存较少[^1]。然而,由于没有反向指针,如果需要访问当前节点之前的节点,则必须从头节点重新开始遍历,直到找到目标节点,这样的操作效率较低。 ### 双链表 双链表改进了这一问题,在每个节点中不仅有一个指向下一个节点的指针(`next`),还有一个指向前一个节点的指针(通常称为`prev`)。这种双向链接的设计允许从任意方向遍历链表,无论是从前向后还是从后向前。尽管这样增加了节点所需的存储空间,并且在插入或删除节点维护两个方向的链接会稍微复杂一些,但这些额外开销往往能换来更高效的随机访问能力更灵活的操作方式[^2]。 ### 操作上的差异 - **遍历**:单链表只能单方向遍历,而双链表支持双向遍历。 - **插入与删除**:对于单链表来说,在给定位置插入或删除元素可能需要找到该位置的前驱节点,这通常涉及一次完整的遍历过程;相比之下,双链表可以直接利用`prev`指针快速定位到前驱节点,从而加快了插入删除的速度。 - **实现复杂度**:单链表实现起来更为简单,而双链表因为要处理前后两个方向上的链接关系,其逻辑上更加复杂[^4]。 ### 应用场景 选择使用哪种类型的链表取决于具体的应用需求。当应用程序频繁地执行反向遍历或者需要高效地进行插入/删除操作双链表通常是更好的选择。反之,如果对内存使用非常敏感且主要进行顺序访问的话,那么采用单链表可能会更加合适。 例如,下面是一个简单的Python代码示例,用于创建并初始化一个双链表节点: ```python class Node: def __init__(self, data): self.data = data self.next = None # 初始化下一个节点为None self.prev = None # 初始化上一个节点为None ``` 通过上述分析可以看出,虽然双链表相比单链表具有更多的功能更高的灵活性,但它也消耗了更多的内存资源来保存额外的指针信息。因此,在决定使用哪种类别的链表,应当综合考虑程序的需求以及性能与资源之间的平衡点。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

程序猿365

祝你好运,谢谢

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

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

打赏作者

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

抵扣说明:

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

余额充值