Day02 链表+LeetCode142

链表

今天重温了下链表知识。链表是一种链式存储法,链表中的顺序是对象中指针所决定的,因此链表中相邻的元素在存储空间内不一定相邻,但插入删除操作相对数组方便。下面简单介绍一下双向链表
如图所示,双链表L的每个元素都是一个对象,每个对象包含一个关键字域和两个指针域:next和prev。next[x]指向链表中x的后继元素,prev[x]指向链表x的前驱元素。如果prev[x]=NIL,则元素x没有前驱结点,即他是链表的第一个元素,也就是头(head)。如果next[x]=NIL,则元素x没有后继结点,即他是链表的最后一个元素,也就是尾(tail)。
属性head[L]指向表的第一个元素。如果head[L]=NIL,则该链表为空。****(注意:head[L]只是一个指向表头的指针,并不具有和结点一样的存储结构,例如下图中的head[L]就代表该链表存储9的结点。)

在这里插入图片描述
下面简单介绍双向链表的几种常用操作:
1、搜索
2、插入
3、删除

1、搜索
查找出链表L中第一个具有关键字k的元素,并返回该指针,如果没有,则返回NIL

LIST-SEARCH(L,k)
	x=head[L]
	while x不等于NIL且key[x]不等于k
		do x=next[x]
return x

2、插入
给定一个已设置了关键字的新元素x,将其插入到链表的最前端,如上图b所示。

LIST-INSERT(L,x)
	next[x]=head[L]
	if head[L]不等于NIL
		then   prev[next[x]]=x
	head[L]=x
	prev[x]=NIL	

3、删除
删除元素x

LIST-DELETE(L,x)
	if prev[x]不等于NIL
		then   next[prev[x]]=next[x]
		else   head[L]=next[x]
	if next[x]不等于NIL
		then   prev[next[x]]=prev[x]

哨兵 哑结点
对于插入和删除操作,如果忽视表头和表尾的边界条件,则代码会更简单。
例如:
List-Delete‘(L,x)
next[prev[x]]=next[x]
prev[next[x]]=prev[x]
哨兵是一个哑对象,可以简化边界条件。哑结点nil[L] 是一个空结点,但是包含和其他元素一样的各个域(不同于head[L],head[L]只是一个指针,而哑结点包含prev key 和next)。引入哑结点,可以将一个一般的双向链表转变成一个带哨兵的双向环形链表,如下图所示。
在这里插入图片描述
域next[nil[L]]指向链表头(第一个结点),而prev[nil[L]]指向表尾。同样的,表头的prev和表尾的next都指向nil[L]。因next[nil[L]]指向表头,因此可以去掉head[L]。
一个空链表仅含哨兵元素,此时next[prev[nil[L]]]和prev[next[nil[L]]]都指向nil[L]。

此时,插入的代码可以简化为:
List-Insert’(L,x)
next[x]=next[nil[L]]
prev[next[x]]=x
next[nil[L]=x]
prev[x]=nil[L]
(Delete见上,Search和原来差不多)
(参考《算法导论》10.2)

LeetCode142环形链表

在这里插入图片描述
思路一:
参考龟兔赛跑的思想:乌龟和兔子从同一起点出发,一个快,一个慢,如果在环形路上跑,则龟和兔始终会相遇,且此时兔子比乌龟多走了一个环的距离。因此,判断一个链表是否有环,可设置一个快指针一个慢指针,如果两个指针相遇,则有环。具体参看以下思路:
在这里插入图片描述
渣渣小白看到这里表示非常巧妙了,不由得鼓起小掌来~~
步骤:
1、设置一个快指针(fast)和一个慢指针(slow),fast步长为2,slow为1,若有环,则fast和slow迟早会相遇。
2、若fast==slow,则说明有环,进入第3步,否则,返回none。
3、设置一个新指针p,当p与slow相遇时,即为入口点。

代码:

class Solution(object):
    def detectCycle(self, head):
        """
        :type head: ListNode
        :rtype: ListNode
        """
        
//第一步 判断是否有环        
fast=head
    slow=head
    hasCycle=false
    
    while(fast.next.next!=None)&(slow.next!=None):
        fast=fast.next.next
        slow=slow.next
        if(fast==slow):
            hasCyle=true
            break
            
 //第二步 若有环,找到环开始结点   
    if(hasCycle):
        p=head
        while(p!=slow):
            p=p.next
            slow=slow.next        
        return p        
    else:
        return none

结果:
在这里插入图片描述

LeetCode206 反转字符串
在这里插入图片描述
思路:
新建一个链表,然后遍历旧链表,每遍历出来一个,就插入到新链表的表头中,那么这个新链表就是反转过来的了。
代码:

class Solution(object):
    def reverseList(self, head):
        """
        :type head: ListNode
        :rtype: ListNode
        """
        first = head
        newhead = None
        while first!=None:
            second = first.next
            first.next = newhead
            newhead = first
            first = second
        return newhead

执行结果:
在这里插入图片描述
(PS:在这里要感谢可爱的Deng童鞋~~)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值