0
点赞
收藏
分享

微信扫一扫

数据结构之链表(一)

捌柒陆壹 2022-03-30 阅读 75

数组跟链表

数组跟链表是都是一维的数据结构,因此经常一起对比学习,

  • 数组(arry)是顺序存储结构 按顺序存储到一个连续固定空间的内存上;所以扩容时空间大小需要手动改动。不便于修改。
  • 链表(linked list)是用指针连接元素的链式存储结构,不要求连续。查找不方便。
  • 数组查询访问速度快为O(1),插入删除效率慢为O(n)。
  • 链表则相反,链表查询慢O(n),插入删除为O(1)。

存储形式

储存[1,2,3,4,5] 这些值,在数组跟链表表现分别为下图。

在这里插入图片描述

代码表现

数组

a=[1,2,3,4,5] #此为python list,比array更多用法。

链表

class ListNode:
  def __init__(self,val,next=None):
    self.val=val
    self.next=next
a=ListNode(1, ListNode(2, ListNode(3, ListNode(4, ListNode(5)))))

代码应用

数组

list的相关接口可以查询官方库

链表

在python中不存在指针,所以用引用来表示指针,下面代码实现了根据序号获取元素、新增元素以及删除元素,下图为双链表实现的函数为:

  • get(index):获取链表中第 index 个节点的值。如果索引无效,则返回-1。

  • addAtHead(val):在链表的第一个元素之前添加一个值为 val 的节点。插入后,新节点将成为链表的第一个节点。

  • addAtTail(val):将值为 val 的节点追加到链表的最后一个元素。

  • addAtIndex(index,val):在链表中的第 index 个节点之前添加值为 val 的节点。如果 index 等于链表的长度,则该节点将附加到链表的末尾。如果 index 大于链表长度,则不会插入节点。如果index小于0,则在头部插入节点。

  • deleteAtIndex(index):如果索引 index 有效,则删除链表中的第 index 个节点。

class MyLinkedList:  # 初始化链表
    def __init__(self):
        self.head = None  # 头节点
        self.tail=None   #尾节点
        self.size=0
    def get(self,index:int)->int:
        if index<0 or index>=self.size:
            return -1
        cur=self.head
        for i in range(index):
            cur=cur.next
        return cur.val
    def addAtHead(self,val:int)->None:
        node=ListNode(val)
        if self.head==None:
            self.head=node
            self.tail=node
        else:
            node.next=self.head
            self.head=node
        self.size+=1
        

    def addAtTail(self,val:int)->None:
        node=ListNode(val)
        if self.tail==None:
            self.tail=node
            self.head=node
        else:
            self.tail.next=node
            self.tail=node
        self.size+=1
        
    def addAtIndex(self,index:int,val:int)->None:
        if index<0 or index>self.size:
            return None
        if index==0:
            self.addAtHead(val)
            self.size+=1
        else:
            cur=self.head
            for i in range(index-1):
                cur=cur.next
            node=ListNode(val)
            node.next=cur.next
            cur.next=node
            self.size+=1
            

    def deleteAtIndex(self,index:int)->None:
        if index<0 or index>=self.size:
            return None
        if index == 0:
            self.head =self.head.next
            self.size-=1
        else:
            cur = self.head
            for i in range(index - 1):
                cur = cur.next
            cur.next = cur.next.next
            self.size -= 1

    def __str__(self):
        cur=self.head
        res=[]
        while cur:
            res.append(str(cur.val))
            cur=cur.next
        return '->'.join(res)

链表基础题目

1. 反转链表

将一个链表进行反转 leetcode 206

from typing import Optional

class ListNode:
    def __init__(self, val=0, next=None):
        self.val = val
        self.next = next



class Solution:
    def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
      if not head:
        return None
      cur= head
      pre=None
      while cur:
        cur.next,cur,pre=pre,cur.next,cur  #理解此处即可
      return pre

2. 判断链表是否有环

链表可以指向链表任意位置,判断链表是否有环 Leetcode 141

# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def hasCycle(self, head: Optional[ListNode]) -> bool:
        if not head:
            return False
        slow =head 
        fast= head.next
        while fast and fast.next:
            if fast == slow :
                return True
            slow ,fast= slow.next,fast.next.next
        return False

3. 两数相加

将两个链表像加法一样求和,需要模拟进位 leetcode 2

# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:
        if not l1:
            return l2
        if not l2:
            return l1
        head= ListNode(0)
        cur =head
        carry=0
        while l1 or l2 :
            if l1:
                carry +=l1.val
                l1=l1.next
            if l2:
                carry +=l2.val
                l2=l2.next
            cur.next=ListNode(carry%10)
            cur=cur.next
            carry= carry //10 
        if carry:
            cur.next=ListNode(carry) # 进位
        return head.next


举报

相关推荐

0 条评论