链表——一种线性数据结构

链表

链表结构
链表中的每个元素实际上是一个单独的对象,而所有对象都通过每个元素中的引用字段链接在一起。

线性数据结构

与数组一样,链表也是线性数据结构,他们的区别在于存储方式不同。

  1. 顺序存储结构(数组):快速的存和取,逻辑上相邻,物理上也相邻。
  2. 链式存储结构(链表):快速的删和改,节点在内存中并不相邻,且相比数组需要更多存储空间。
    在这里插入图片描述
    Tips:链表的遍历时间复杂度为O(n),增删的时间复杂度为O(1)

定义单个节点结构体

public class SinglyListNode { //以单链表为例
    int val;
    SinglyListNode next;
    SinglyListNode(int x) { val = x; }
}

链表的基本操作

链表的增删

设计链表的实现。单链表中的节点应该具有两个属性:val 和 next。val 是当前节点的值,next 是指向下一个节点的指针/引用。

class MyLinkedList {
    Node head;  //虚拟头结点
    int size;
    class Node{  //节点类
        int val;
        Node next;
        Node(){}
        Node(int val){
            this.val=val;
            this.next=null;
        }
    }
    /** Initialize your data structure here. */
    public MyLinkedList() {
        head=new Node();
        size=0;
    }
    
    /** Get the value of the index-th node in the linked list. If the index is invalid, return -1. */
    public int get(int index) {
        Node p=head;
        if(index >= size || index < 0)return -1;
        for(int i=-1;i<index;i++)  //有一个头结点,i从-1开始
            {
                p=p.next;
            }
        return p.val;

    }
    
    /** Add a node of value val before the first element of the linked list. After the insertion, the new node will be the first node of the linked list. */
    public void addAtHead(int val) {
        addAtIndex(0,val);
    }
    
    /** Append a node of value val to the last element of the linked list. */
    public void addAtTail(int val) {
        addAtIndex(size,val);
    }
    
    /** Add a node of value val before the index-th node in the linked list. If index equals to the length of linked list, the node will be appended to the end of linked list. If index is greater than the length, the node will not be inserted. */
    public void addAtIndex(int index, int val) {
        if(index<=size&&index>=0)
        {
            Node node= new Node(val); //需要插入的节点
            if(index==0)
            {//插入在头结点
                    node.next=head.next;
                    head.next=node;
            }
            else
            {//插入在index位置
                Node p=head;
                for(int i=-1;i<index-1;i++)
                {
                    p=p.next;
                }
                node.next=p.next;
                p.next=node;
            }
        }
        size++;
    }
    
    /** Delete the index-th node in the linked list, if the index is valid. */
    public void deleteAtIndex(int index) {
     if(index >= 0 && index < size){
            if(index == 0){
                head.next = head.next.next;
            }else{
                Node p = head;
                int i = -1;
                while(i < index - 1){
                    p = p.next;
                    i++;
                }
                p.next = p.next.next;
            }
            size--;
        }


}
}
/**
 * Your MyLinkedList object will be instantiated and called as such:
 * MyLinkedList obj = new MyLinkedList();
 * int param_1 = obj.get(index);
 * obj.addAtHead(val);
 * obj.addAtTail(val);
 * obj.addAtIndex(index,val);
 * obj.deleteAtIndex(index);
 */

反转链表——头插法

解决方案:按原始顺序迭代结点,并将它们逐个移动到列表的头部

 public ListNode reverseList(ListNode head) {

        
        if(head==null||head.next==null) return head;
        ListNode prev=head;
        ListNode p=prev.next;
        
        while(p!=null)
        {
            prev.next=p.next;  //保存p的后继节点
            p.next=head;
            head=p;
            p=prev.next;
        }
        return head;
    }
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值