8. The basic data structure - the sequence list in Table 8. The basic data structure and - the order of the list table and

8. The basic data structure - the sequence list and tables

 

A. Memory

  - the role of the computer: the data storage and calculation. First, we need to know that we currently use computers are binary computer, you can only think that the computer storage and computing binary data. For example downloaded a movie, the movie can be stored in the computer, stored in the computer is based on the binary data of the movie, then we can be related to arithmetic operations with related hardware binary data to a movie by related video player software the results generated by what we can see a movie screen and hear audio sound.

  - Question: How elaborate computer calculations 1 + 2?

  - Statement: is simple to understand, first 1 and 2 may be entered into the computer, then the computer 1 and 2 will be converted into binary data for data storage, and then calculating two binary values ​​by an adder and returns the result.

  - Analysis: described in the above mentioned, the computer first need to store these two values ​​1 and 2, the computer how to store data in it? Then there is no doubt that computer data can be stored directly into memory.

  - Variable: we in the programming world, you can directly assign a value to a variable, but the final value will be stored in the computer's memory, so we can understand, it is the computer representation of variable data stored in a piece RAM.

  - understand how to visualize the computer's memory?

    - Example: mapping the memory space on your computer to us in real life, then memory is like us in real life three-dimensional space. Living in Beijing's northern drift, almost all live in an independent apartment or shared in one room a few bedroom, then drift north armor is like data, and the room he lives then that is a memory for storing data space.

    - Analysis: From the example above, we can see that the room drift north A living will have two basic attributes, one of which is the size of the room space, and the second is a locator room (house number). Then the data stored in the computer memory space will also have two basic properties: memory address space and memory space. May indicate the size of the memory space address space may range in size, the memory storing data values ​​(expressed by a hexadecimal number) by the addressing may be used to locate and query the data values ​​stored in the memory space.

    - How to understand a = 10 this assignment corresponding memory map do?

  - Quote: When a variable is stored in the address of a piece of memory space, then you can become a reference to the variable that memory space. a = 10, a is a reference to the 10 where the memory space.

  - point: When a variable is stored in a memory address space, called the variable (reference) point to that memory.

  - Different types of data size of the memory space occupied: shaping (4 bytes), floating point (8 bytes), character (1 byte)

Two sequence table: elements in the collection are stored in sequential. Structure of sequence table can be divided into two forms: a single data type, and multiple data types.

  - Single Data Type: int a = 10,20,30 how to store in memory, how to get each data value it?

  

  - Multiple data types: how to store in memory li = 10, 'a', 96.5, how to get each data value it?

   - Table of malpractice order: the order table structure needs to know in advance the size of the data to apply continuous storage space, time and needs to be expanded during the relocation of data.

   - Python tuple in the list and uses two types of implementation techniques sequence table.

Three lists: With respect to the order list, the list structure can take advantage of computer memory, dynamic memory management flexible.

  - list (Linked list) is a common basic data structures, a linear table, as sequence table but not continuously stored data, but each node (data storing means) stored in a node of the next information (ie, address):

  

  - 1, one-way linked list

    Also known as singly linked lists single linked list, the table is the simplest form, that each node contains two fields, an information field (field element) and a link field. The link points to the next node in the linked list, and the link field points to the last node is a null value.

    - table used to store the elements elem specific data.

    - next link field for the storage of the next node.

    - The variable p points to the location of the head node of the list (the first node), and p departure from any node can be found in the table.

  - one-way linked list of abstract data type definitions:

      . Is_empty (): the list is empty

      . Length (): chain length

      . Travel (): traverse the entire list

      . add(item):链表头部添加元素

      . append(item):链表尾部添加元素

      . insert(pos, item):指定位置添加元素

      . remove(item):删除节点

      . search(item):查找节点是否存在

  - 代码实现:

  

Copy the code
class Node():
    def __init__(self,item):
        self.item = item
        self.next = None
    def __str__(self):
        return str(self.item)
class Link():
    def __init__(self):
        #永远指向链表中第一个节点
        self._head = None
    def isEmpty(self):
        return self._head is None
    def add(self,item):
        node = Node(item)
        node.next = self._head
        self._head = node
    def length(self):
        count = 0
        if self.isEmpty():
            return count
        else:
            cur = self._head
            while cur is not None:
                count += 1
                cur = cur.next
            return count
    def travel(self):
        cur = self._head
        while cur is not None:
            print(cur)
            cur = cur.next
    def append(self,item):
        node = Node(item)
        cur = self._head
        if self.isEmpty():
            self._head = node
        else:
            while cur is not None:
                #因为循环遍历结束后cur会指向空并非最后一个节点
                pre_cur = cur
                cur = cur.next
            pre_cur.next = node
        
    def search(self,item):
        ex = False
        cur = self._head
        while cur is not None:
            if cur.item == item:
                ex = True
                break
            cur = cur.next
        return ex
    
    def insertTo(self,item,index):
        cur = self._head
        ex = 0
        node = Node(item)
        #插入到第一个节点位置
        if index <= 0:
            self.add(item)
        #插入到最后一个节点位置
        elif index >= self.length():
            self.append(item)
        else:
            while cur is not None:
                pre = cur 
                cur = cur.next
                #此处插入的一定不是第一个节点和最后一个节点位置,因此index要减1
                if ex == index-1:
                    node.next = cur
                    pre.next = node
                    break
                ex += 1
    def remove(self,item):
        pre = None
        cur = self._head
        #删除的是第一个节点
        if cur.item == item:
            self._head = cur.next
        else:
            while cur is not None:
                pre = cur
                cur = cur.next
                if cur.item == item:
                    pre.next = cur.next
                    cur.next = None
                cur = cur.next
                    
                

 #测试代码
link = Link()
link.add('bobo')
link.add('jay')
link.add('tom')
link.add('jerry')
# print(link.search('tom'))
# link.insertTo('haha',1)
link.remove('bobo')
link.travel()
Copy the code

 

  - 2.单向循环链表:单链表的一个变形是单向循环链表,链表中最后一个节点的next域不再为None,而是指向链表的头结点。

  - 基本操作和单链表基本一样,实现代码如下:

Copy the code
# coding=utf-8
# 单向循环链表


class Node:
    """节点"""
    def __init__(self, item):
        self.item = item
        self.next = None

    def __str__(self):
        return str(self.item)


class SinCycLinkedList:
    """单向循环链表"""
    def __init__(self):
        self._head = None

    def is_empty(self):
        """判断链表是否为空"""
        return self._head is None

    def length(self):
        """链表长度"""
        if self.is_empty():
            return 0
        count = 1
        cur = self._head
        while cur.next != self._head:
            # print("cur", cur.item)
            count += 1
            cur = cur.next
        return count

    def travel(self):
        """遍历"""
        if self.is_empty():
            return

        cur = self._head
        print(cur.item)
        while cur.next != self._head:
            cur = cur.next
            print(cur.item)

    def add(self, item):
        """在头部添加一个节点"""
        node = Node(item)
        if self.is_empty():
            self._head = node
            node.next = self._head
        else:
            node.next = self._head
            cur = self._head
            while cur.next != self._head:
                cur = cur.next

            cur.next = node
            self._head = node

    def append(self, item):
        """在尾部添加一个节点"""
        node = Node(item)
        if self.is_empty():
            self._head = node
            node.next = self._head
        else:
            cur = self._head
            # print(type(cur), cur.item, cur.next)
            while cur.next != self._head:
                cur = cur.next

            # print(cur.item)
            cur.next = node
            node.next = self._head

    def insert(self, pos, item):
        """指定位置pos添加节点"""
        if pos <= 0:
            self.add(item)
        elif pos > (self.length() - 1):
            self.append(item)
        else:
            node = Node(item)
            cur = self._head
            cur_pos = 0
            while cur.next != self._head:
                if (pos - 1) == cur_pos:
                    node.next = cur.next
                    cur.next = node
                    break
                cur_pos += 1
                cur = cur.next

    def remove(self, item):
        """删除一个节点"""
        if self.is_empty():
            return

        pre = self._head
        # 删除首节点
        if pre.item == item:
            cur = pre
            while cur.next != self._head:
                cur = cur.next

            cur.next = pre.next     # 删除首节点(跳过该节点)
            self._head = pre.next   # 重新指定首节点

        # 删除其他的节点
        else:
            cur = pre
            while cur.next != self._head:
                if cur.next.item == item:
                    cur.next = cur.next.next
                cur = cur.next

    def search(self, item):
        """查找节点是否存在"""
        if self.is_empty():
            return -1

        cur_pos = 0
        cur = self._head
        if cur.item == item:
            return cur_pos

        while cur.next != self._head:
            if cur.item == item:
                return cur_pos
            cur_pos += 1
            cur = cur.next

        if cur_pos == self.length() - 1:
            return -1


if __name__ == "__main__":
    ll = SinCycLinkedList()
    ll.add(1)       # 1
    ll.add(2)       # 2 1
    # ll.travel()
    ll.append(3)    # 2 1 3
    ll.insert(2, 4) # 2 1 4 3
    ll.insert(4, 5) # 2 1 4 3 5
    ll.insert(0, 6) # 6 2 1 4 3 5
    print("length:", ll.length())        # 6
    ll.travel()                           # 6 2 1 4 3 5
    print("search(3)", ll.search(3))     # 4
    print("search(7)", ll.search(7))     # -1
    print("search(6)", ll.search(6))    # 0
    print("remove(1)")
    ll.remove(1)
    print("length:", ll.length())       # 6 2 4 3 5
    print("remove(6)")
    ll.remove(6)
    ll.travel()
Copy the code

  3.双向链表:一种更复杂的链表是 "双向链表" 或 "双面链表"。每个节点有两个链接:一个指向前一个节点,当次节点为第一个节点时,指向空值;而另一个指向下一个节点,当此节点为最后一个节点时,指向空值。

  - 代码实现:

Copy the code
# coding=utf-8
# 双向链表


class Node:
    """节点"""
    def __init__(self, item):
        self.item = item
        self.prev = None
        self.next = None


class DLinkList:
    """双向链表"""
    def __init__(self):
        self._head = None

    def is_empty(self):
        """判断链表是否为空"""
        return self._head is None

    def length(self):
        """获取链表长度"""
        if self.is_empty():
            return 0
        else:
            cur = self._head
            count = 1
            while cur.next is not None:
                count += 1
                cur = cur.next

            return count

    def travel(self):
        """遍历链表"""
        print("↓↓" * 10)
        if self.is_empty():
            print("")

        else:
            cur = self._head
            print(cur.item)
            while cur.next is not None:
                cur = cur.next
                print(cur.item)
        print("↑↑" * 10)

    def add(self, item):
        """链表头部添加节点"""
        node = Node(item)
        if self.is_empty():
            self._head = node
        else:
            cur = self._head

            node.next = cur
            cur.prev = node
            self._head = node

    def append(self, item):
        """链表尾部添加节点"""
        node = Node(item)
        if self.is_empty():
            self._head = node
        else:
            cur = self._head
            # 遍历找到最后一个节点
            while cur.next is not None:
                cur = cur.next

            # 在尾节点添加新的节点
            cur.next = node
            node.prev = cur

    def insert(self, pos, item):
        """指定位置添加"""
        # 头部添加
        if pos <= 0:
            self.add(item)

        # 尾部添加
        elif pos > (self.length() - 1):
            self.append(item)

        # 其他位置添加
        else:
            node = Node(item)

            cur = self._head
            cur_pos = 0
            while cur.next is not None:
                if cur_pos == (pos - 1):
                    # 与下一个节点互相指向
                    node.next = cur.next
                    cur.next.prev = node
                    # 与上一个节点互相指向
                    cur.next = node
                    node.prev = cur
                cur_pos += 1
                cur = cur.next

    def remove(self, item):
        """删除节点"""
        if self.is_empty():
            return
        else:
            cur = self._head
            # 删除首节点
            if cur.item == item:
                self._head = cur.next
                cur.next.prev = None

            # 删除其他节点
            else:
                while cur.next is not None:
                    if cur.item == item:
                        # 删除之前:1 ←→ [2] ←→ 3
                        # 删除之后:1 ←→ 3
                        cur.prev.next = cur.next
                        cur.next.prev = cur.prev
                    cur = cur.next

                # 删除尾节点
                if cur.item == item:
                    cur.prev.next = None


    def search(self, item):
        """查找节点是否存在"""
        if self.is_empty():
            return -1
        else:
            cur = self._head
            cur_pos = 0
            while cur.next is not None:
                if cur.item == item:
                    return cur_pos

                cur_pos += 1
                cur = cur.next

            if cur_pos == (self.length() - 1):
                return -1


if __name__ == "__main__":
    ll = DLinkList()
    ll.add(1)       # 1
    ll.add(2)       # 2 1
    ll.append(3)    # 2 1 3
    ll.insert(2, 4) # 2 1 4 3
    ll.insert(4, 5) # 2 1 4 3 5
    ll.insert(0, 6) # 6 2 1 4 3 5
    print("length:", ll.length())   # 6
    ll.travel()                 # 6 2 1 4 3 5
    print("search(3)", ll.search(3))
    print("search(4)", ll.search(4))
    print("search(10)", ll.search(10))
    ll.remove(1)
    print("length:", ll.length())
    ll.travel()
    print("删除首节点 remove(6):")
    ll.remove(6)
    ll.travel()
    print("删除尾节点 remove(5):")
    ll.remove(5)
    ll.travel()
Copy the code

 

 
 
 

一.内存

  - 计算机的作用:对数据进行存储和运算。首先我们需要知道我们目前使用的计算机都是二进制的计算机,就以为着计算机只可以存储和运算二进制的数据。例如下载好的一部电影,该电影可以存储到计算机中,计算机中存储的是基于二进制的电影数据,然后我们可以通过相关的视频播放软件结合相关的硬件对电影的二进制数据进行相关的运算操作,所产生的结果就是我们可以看到电影的画面和听到音频的声音。

  - 问题:阐述计算机如何计算1+2的结果?

  - 阐述:简单理解为,首先可以将1和2输入到计算机中,然后计算机会将1和2转换成二进制的数据进行数据存储,然后通过加法器进行两个二进制数值的计算并返回结果。

  - 分析:上述的阐述中提到,计算机首先需要存储1和2这两个数值,那么计算机如何进行数据的存储呢?那么毫无疑问,计算机可以将数据直接存储到内存中。

  - 变量:我们在编程世界中,可以将某个数值直接赋值给一个变量,但是最终数值会被存储到计算机的内存中,因此我们可以理解为,变量表示的就是计算机中进行数据存储的某一块内存。

  - 如何形象化的理解计算机的内存?

    - 举例:将计算机的内存空间映射到我们现实生活中的话,内存就好比是我们在现实生活中三维立体的空间。生活在北京的北漂们,几乎都居住的是一个独立的公寓或者合租在一个几居室的某一个房间中,那么北漂甲就好比是数据,而他所居住的房间则就是存储数据的一块内存空间。

    - 分析:从上述案例中,我们可以得知北漂甲居住的房间会有两个基本的属性,其一就是房间空间的大小,其二就是房间的一个位置标识(门牌号)。那么计算机中存储数据的内存空间也会有这两个最基本的属性:内存空间大小和内存空间的地址。内存空间的大小可以表示该空间可以存储数据值的大小范围,内存空间的地址(用十六进制数值表示)可以用来通过寻址定位、查找到该内存空间中所存储的数据值。

    - 如何理解 a = 10 这条赋值语句对应的内存图呢?

  - 引用:当一个变量中存储的是某一块内存空间的地址,则该变量即可成为那块内存空间的引用。a=10,a就是10所在内存空间的一个引用。

  - 指向:当一个变量中存储了一块内存空间的地址,则称该变量(引用)指向了那块内存。

  - 不同类型数据占用内存空间的大小:整形(4字节),浮点型(8字节),字符型(1字节)

二.顺序表:集合中存储的元素是有顺序的。顺序表的结构可以分为两种形式:单数据类型和多数据类型。

  - 单数据类型:在内存中如何存储 int a = 10,20,30,如何取得每一个数据值呢?

  

  - 多数据类型:在内存中如何存储 li = 10,'a',96.5,如何获取每一个数据值呢?

   - 顺序表的弊端:顺序表的结构需要预先知道数据大小来申请连续的存储空间,而在进行扩充时又需要进行数据的搬迁。

   - Python中的 list 和 tuple 两种类型采用了顺序表的实现技术。

三.链表:相对于顺序表,链表结构可以充分利用计算机内存空间,实现灵活的内存动态管理。

  - 链表(Linked list)是一种常见的基础数据结构,是一种线性表,但是不像顺序表一样连续存储数据,而是每一个结点(数据存储单元)里存放下一个结点的信息(即地址):

  

  - 1、单向链表

    单向链表也叫单链表,是表中最简单的一种形式,它的每个节点包含两个域,一个信息域(元素域)和一个链接域。这个链接指向链表中的下一个节点,而最后一个节点的链接域则指向一个空值。

    - 表中元素elem用来存放具体的数据。

    - 链接域next用来存放下一个节点的位置。

    - 变量p指向链表的头节点(首节点)的位置,从p出发能找到表中的任意节点。

  - 单向链表的抽象数据类型定义:

      . is_empty():链表是否为空

      . length():链表长度

      . travel():遍历整个链表

      . add(item):链表头部添加元素

      . append(item):链表尾部添加元素

      . insert(pos, item):指定位置添加元素

      . remove(item):删除节点

      . search(item):查找节点是否存在

  - 代码实现:

  

Copy the code
class Node():
    def __init__(self,item):
        self.item = item
        self.next = None
    def __str__(self):
        return str(self.item)
class Link():
    def __init__(self):
        #永远指向链表中第一个节点
        self._head = None
    def isEmpty(self):
        return self._head is None
    def add(self,item):
        node = Node(item)
        node.next = self._head
        self._head = node
    def length(self):
        count = 0
        if self.isEmpty():
            return count
        else:
            cur = self._head
            while cur is not None:
                count += 1
                cur = cur.next
            return count
    def travel(self):
        cur = self._head
        while cur is not None:
            print(cur)
            cur = cur.next
    def append(self,item):
        node = Node(item)
        cur = self._head
        if self.isEmpty():
            self._head = node
        else:
            while cur is not None:
                #因为循环遍历结束后cur会指向空并非最后一个节点
                pre_cur = cur
                cur = cur.next
            pre_cur.next = node
        
    def search(self,item):
        ex = False
        cur = self._head
        while cur is not None:
            if cur.item == item:
                ex = True
                break
            cur = cur.next
        return ex
    
    def insertTo(self,item,index):
        cur = self._head
        ex = 0
        node = Node(item)
        #插入到第一个节点位置
        if index <= 0:
            self.add(item)
        #插入到最后一个节点位置
        elif index >= self.length():
            self.append(item)
        else:
            while cur is not None:
                pre = cur 
                cur = cur.next
                #此处插入的一定不是第一个节点和最后一个节点位置,因此index要减1
                if ex == index-1:
                    node.next = cur
                    pre.next = node
                    break
                ex += 1
    def remove(self,item):
        pre = None
        cur = self._head
        #删除的是第一个节点
        if cur.item == item:
            self._head = cur.next
        else:
            while cur is not None:
                pre = cur
                cur = cur.next
                if cur.item == item:
                    pre.next = cur.next
                    cur.next = None
                cur = cur.next
                    
                

 #测试代码
link = Link()
link.add('bobo')
link.add('jay')
link.add('tom')
link.add('jerry')
# print(link.search('tom'))
# link.insertTo('haha',1)
link.remove('bobo')
link.travel()
Copy the code

 

  - 2.单向循环链表:单链表的一个变形是单向循环链表,链表中最后一个节点的next域不再为None,而是指向链表的头结点。

  - 基本操作和单链表基本一样,实现代码如下:

Copy the code
# coding=utf-8
# 单向循环链表


class Node:
    """节点"""
    def __init__(self, item):
        self.item = item
        self.next = None

    def __str__(self):
        return str(self.item)


class SinCycLinkedList:
    """单向循环链表"""
    def __init__(self):
        self._head = None

    def is_empty(self):
        """判断链表是否为空"""
        return self._head is None

    def length(self):
        """链表长度"""
        if self.is_empty():
            return 0
        count = 1
        cur = self._head
        while cur.next != self._head:
            # print("cur", cur.item)
            count += 1
            cur = cur.next
        return count

    def travel(self):
        """遍历"""
        if self.is_empty():
            return

        cur = self._head
        print(cur.item)
        while cur.next != self._head:
            cur = cur.next
            print(cur.item)

    def add(self, item):
        """在头部添加一个节点"""
        node = Node(item)
        if self.is_empty():
            self._head = node
            node.next = self._head
        else:
            node.next = self._head
            cur = self._head
            while cur.next != self._head:
                cur = cur.next

            cur.next = node
            self._head = node

    def append(self, item):
        """在尾部添加一个节点"""
        node = Node(item)
        if self.is_empty():
            self._head = node
            node.next = self._head
        else:
            cur = self._head
            # print(type(cur), cur.item, cur.next)
            while cur.next != self._head:
                cur = cur.next

            # print(cur.item)
            cur.next = node
            node.next = self._head

    def insert(self, pos, item):
        """指定位置pos添加节点"""
        if pos <= 0:
            self.add(item)
        elif pos > (self.length() - 1):
            self.append(item)
        else:
            node = Node(item)
            cur = self._head
            cur_pos = 0
            while cur.next != self._head:
                if (pos - 1) == cur_pos:
                    node.next = cur.next
                    cur.next = node
                    break
                cur_pos += 1
                cur = cur.next

    def remove(self, item):
        """删除一个节点"""
        if self.is_empty():
            return

        pre = self._head
        # 删除首节点
        if pre.item == item:
            cur = pre
            while cur.next != self._head:
                cur = cur.next

            cur.next = pre.next     # 删除首节点(跳过该节点)
            self._head = pre.next   # 重新指定首节点

        # 删除其他的节点
        else:
            cur = pre
            while cur.next != self._head:
                if cur.next.item == item:
                    cur.next = cur.next.next
                cur = cur.next

    def search(self, item):
        """查找节点是否存在"""
        if self.is_empty():
            return -1

        cur_pos = 0
        cur = self._head
        if cur.item == item:
            return cur_pos

        while cur.next != self._head:
            if cur.item == item:
                return cur_pos
            cur_pos += 1
            cur = cur.next

        if cur_pos == self.length() - 1:
            return -1


if __name__ == "__main__":
    ll = SinCycLinkedList()
    ll.add(1)       # 1
    ll.add(2)       # 2 1
    # ll.travel()
    ll.append(3)    # 2 1 3
    ll.insert(2, 4) # 2 1 4 3
    ll.insert(4, 5) # 2 1 4 3 5
    ll.insert(0, 6) # 6 2 1 4 3 5
    print("length:", ll.length())        # 6
    ll.travel()                           # 6 2 1 4 3 5
    print("search(3)", ll.search(3))     # 4
    print("search(7)", ll.search(7))     # -1
    print("search(6)", ll.search(6))    # 0
    print("remove(1)")
    ll.remove(1)
    print("length:", ll.length())       # 6 2 4 3 5
    print("remove(6)")
    ll.remove(6)
    ll.travel()
Copy the code

  3.双向链表:一种更复杂的链表是 "双向链表" 或 "双面链表"。每个节点有两个链接:一个指向前一个节点,当次节点为第一个节点时,指向空值;而另一个指向下一个节点,当此节点为最后一个节点时,指向空值。

  - 代码实现:

Copy the code
# coding=utf-8
# 双向链表


class Node:
    """节点"""
    def __init__(self, item):
        self.item = item
        self.prev = None
        self.next = None


class DLinkList:
    """双向链表"""
    def __init__(self):
        self._head = None

    def is_empty(self):
        """判断链表是否为空"""
        return self._head is None

    def length(self):
        """获取链表长度"""
        if self.is_empty():
            return 0
        else:
            cur = self._head
            count = 1
            while cur.next is not None:
                count += 1
                cur = cur.next

            return count

    def travel(self):
        """遍历链表"""
        print("↓↓" * 10)
        if self.is_empty():
            print("")

        else:
            cur = self._head
            print(cur.item)
            while cur.next is not None:
                cur = cur.next
                print(cur.item)
        print("↑↑" * 10)

    def add(self, item):
        """链表头部添加节点"""
        node = Node(item)
        if self.is_empty():
            self._head = node
        else:
            cur = self._head

            node.next = cur
            cur.prev = node
            self._head = node

    def append(self, item):
        """链表尾部添加节点"""
        node = Node(item)
        if self.is_empty():
            self._head = node
        else:
            cur = self._head
            # 遍历找到最后一个节点
            while cur.next is not None:
                cur = cur.next

            # 在尾节点添加新的节点
            cur.next = node
            node.prev = cur

    def insert(self, pos, item):
        """指定位置添加"""
        # 头部添加
        if pos <= 0:
            self.add(item)

        # 尾部添加
        elif pos > (self.length() - 1):
            self.append(item)

        # 其他位置添加
        else:
            node = Node(item)

            cur = self._head
            cur_pos = 0
            while cur.next is not None:
                if cur_pos == (pos - 1):
                    # 与下一个节点互相指向
                    node.next = cur.next
                    cur.next.prev = node
                    # 与上一个节点互相指向
                    cur.next = node
                    node.prev = cur
                cur_pos += 1
                cur = cur.next

    def remove(self, item):
        """删除节点"""
        if self.is_empty():
            return
        else:
            cur = self._head
            # 删除首节点
            if cur.item == item:
                self._head = cur.next
                cur.next.prev = None

            # 删除其他节点
            else:
                while cur.next is not None:
                    if cur.item == item:
                        # 删除之前:1 ←→ [2] ←→ 3
                        # 删除之后:1 ←→ 3
                        cur.prev.next = cur.next
                        cur.next.prev = cur.prev
                    cur = cur.next

                # 删除尾节点
                if cur.item == item:
                    cur.prev.next = None


    def search(self, item):
        """查找节点是否存在"""
        if self.is_empty():
            return -1
        else:
            cur = self._head
            cur_pos = 0
            while cur.next is not None:
                if cur.item == item:
                    return cur_pos

                cur_pos += 1
                cur = cur.next

            if cur_pos == (self.length() - 1):
                return -1


if __name__ == "__main__":
    ll = DLinkList()
    ll.add(1)       # 1
    ll.add(2)       # 2 1
    ll.append(3)    # 2 1 3
    ll.insert(2, 4) # 2 1 4 3
    ll.insert(4, 5) # 2 1 4 3 5
    ll.insert(0, 6) # 6 2 1 4 3 5
    print("length:", ll.length())   # 6
    ll.travel()                 # 6 2 1 4 3 5
    print("search(3)", ll.search(3))
    print("search(4)", ll.search(4))
    print("search(10)", ll.search(10))
    ll.remove(1)
    print("length:", ll.length())
    ll.travel()
    print("删除首节点 remove(6):")
    ll.remove(6)
    ll.travel()
    print("删除尾节点 remove(5):")
    ll.remove(5)
    ll.travel()
Copy the code

 

Guess you like

Origin www.cnblogs.com/yanghongtao/p/10960370.html