数据结构1-1. 链表(Linked List)

一、链表简介

  链表是一种逻辑顺序上连续、存储空间上不连续、不顺序的线性数据结构,其逻辑顺序由链表的指针依次链接实现。

     Head            Tail

  

  链表由一个个结点组成,每个节点由存储数据的数据域和存储指向下一结点指针的指针域组成。

  定义链表的结点:

1 class Node:
2     def __init__(self, data, next=None):
3         self.data = data
4         self.next = next

  链表的优点是不需要预先知道数据的大小,可以充分利用计算机内存空间,但其扩展的指针域增大了空间开销。与数组不同,我们无法在常量时间内访问单链表中的随机元素。 如果我们想要获得第 i 个元素,我们必须从头结点逐个遍历。 我们按索引来访问元素平均要花费 O(N) 时间,其中 N 是链表的长度。

二、链表的类型

  根据链表的结构,链表的类型有单向链表、双向链表和循环链表等。

  • 单向链表

  

   单向链表又叫单链表,是链表中最简单的形式,每个结点的指针都依次指向下一个结点,最后一个结点的指针指向一个空置Null,单向链表只可向一个方向遍历。

  • 双向链表

  双向链表比单向链表更加复杂,它的每个结点有两个指针next 和 prev,next指向下一个结点,当前结点为最后一个结点时,指向空值;prev指向上一个结点,当前结点为第一个结点时,指向空值。

  

  •  循环链表

  循环链表为单链表的变种,链表的最后一个结点指向链表的头结点,形成一个循环。

三、链表的操作

  • 添加操作 - 单链表

  一句话:先让新来的结点有所指向

  如果想在给定的结点prev后添加新的值,操作如下:

  

  (1) 使用给定值初始化新结点cur

  (2) 将cur的指针指向prev的下一个结点

  (3) 将prev的指针指向cur

 

  在开头添加结点:

  众所周知,使用头结点来代表整个链表,因此在开头添加结点时需要更新头结点head,操作如下:

  

  

  (1) 初始化新结点cur

  (2) 将新结点cur的指针指向头结点

  (3) 将cur指定为head

  在链表末尾添加结点,需要从head开始遍历,直到找到最后一个结点,将该节点的指针指向目标节点。

 

  • 删除操作  

  链表的删除操作由两步组成

  

   

 

  (1) 找到待删除结点 cur 的前一个结点 prev 和后一个结点 next

  (2) 将 prev 指向 next

  同上,删除链表的第一个结点或最后一个结点,只需将第二个结点设为 head 或将倒数第二个结点指向None

 

四、python实现链表

  代码如下

class Node(object):
    def __init__(self, val):
        self.val = val
        self.next = None


class MyLinkedList(object):
    def __init__(self):
        self.head = None
        self.size = 0

    def get(self, index):
        '''
        :param index:
        :return:the value of the index-th node
        '''
        # if index is not int:
        #     print('please input int')
        #     return -1
        if index >= self.size or index < 0:  # 包括链表为空、索引无效
            return -1

        cur = self.head
        for i in range(index):
            cur = cur.next
        return cur.val

    def addAtHead(self, val):
        new = Node(val)
        new.next = self.head
        self.head = new
        self.size += 1

    def addAtTail(self, val):
        new = Node(val)

        if self.head is None:
            self.head = new
            self.size += 1
        else:
            cur = self.head
            while cur.next is not None:
                cur = cur.next
            cur.next = new
            self.size += 1

    def addAtIndex(self, index,val):  # 在索引前加结点
        if index > self.size:
            return -1
        else:
            if index <= 0:
                self.addAtHead(val)

            elif index == self.size:
                self.addAtTail(val)

            else:
                cur = self.head
                pre = self.head
                new = Node(val)
                for i in range(index):
                    pre = cur
                    cur = cur.next

                new.next = cur
                pre.next = new

                self.size += 1

    def deleteAtIndex(self,index):
        if index < 0 or index >= self.size or self.head is None:
            return -1
        else:
            if index == 0:
                self.head = self.head.next
                self.size -= 1
                return

            cur = self.head
            pre = self.head
            for i in range(index):
                pre = cur
                cur = cur.next
            if cur is None:
                pre.next = None
            else:
                pre.next = cur.next
            self.size -= 1

 

posted @ 2022-06-29 11:23  Liang-ml  阅读(238)  评论(0)    收藏  举报