三、线性表中数组和链表的python代码实现和代码解释

让各为读者久等了,笔者正在加班加点肝代码,望各位读者见谅。
以下为本节内容。
**

一、数组

**
数组是一种数据结构,它由一组元素组成,这些元素按照线性顺序排列,并且通过索引访问。数组的元素可以是任何数据类型,包括整数、浮点数、字符串等等。数组有很多种不同的实现方式,其中最常见的是固定大小的静态数组和可变大小的动态数组。
Python中的列表(list)就是一种动态数组,它支持插入、删除和获取元素的操作,也支持切片(slice)和迭代(iteration)等高级操作。可以通过下标(index)来访问列表中的元素,下标从0开始,表示第一个元素,依次递增。
常见的基础操作:

创建一个包含5个元素的列表

my_list = [1, 2, 3, 4, 5]

访问第3个元素

print(my_list[2])  # 输出 3

修改第4个元素的值

my_list[3] = 6

在列表末尾添加一个新元素

my_list.append(7)

删除第2个元素

del my_list[1]

获取列表长度

print(len(my_list))  # 输出 5

切片操作

print(my_list[1:3])  # 输出 [3, 6]

需要注意的是,Python的列表实际上是由动态数组和指向元素的指针组成的,因此插入和删除元素时可能需要移动后面的元素,时间复杂度为O(n),在一些需要高效插入和删除操作的场景中,可能需要使用其他数据结构,如链表等。

当我们需要在程序中存储一组数据时,可以使用线性表来实现。线性表是一种逻辑结构,可以用一组连续的内存空间存储相同类型的数据。

数组是一种线性表的实现方式。在数组中,数据元素存储在连续的内存空间中,并按照一定的规律依次存储。我们可以通过下标来访问数组中的元素。由于数据元素的内存空间是连续的,因此数组具有快速随机访问元素的优势。但是,在进行插入、删除等操作时,由于需要移动大量元素,数组的效率较低。
数组(Array)

class Array:
    def __init__(self, capacity):
        self._capacity = capacity
        self._data = [None] * capacity
        self._size = 0

    def __len__(self):
        return self._size

    def __getitem__(self, index):
        if not 0 <= index < self._size:
            raise IndexError("Index out of range")
        return self._data[index]

    def __setitem__(self, index, value):
        if not 0 <= index < self._size:
            raise IndexError("Index out of range")
        self._data[index] = value

    def append(self, value):
        if self._size == self._capacity:
            self._resize(2 * self._capacity)
        self._data[self._size] = value
        self._size += 1

    def _resize(self, new_capacity):
        new_data = [None] * new_capacity
        for i in range(self._size):
            new_data[i] = self._data[i]
        self._data = new_data
        self._capacity = new_capacity

上述代码实现了一个简单的数组,包括以下方法:
__init__(self, capacity): 构造函数,创建一个指定容量的数组。
__len__(self): 获取数组长度。
__getitem__(self, index): 获取指定索引的元素。
__setitem__(self, index, value): 设置指定索引的元素。
append(self, value): 向数组末尾添加一个元素。
_resize(self, new_capacity): 数组扩容,将容量增加到指定大小。

在 Python 中,可以使用列表(list)来实现数组的功能。列表是一种有序的、可变的、可以存储任意类型元素的数据结构。

数组操作

创建数组

在Python中,可以使用内置的列表(list)来实现数组的功能。创建一个有 n n n个元素的数组,可以使用以下代码:

arr = [None] * n

其中,None是Python中的空值,表示数组中的元素暂时为空。

访问元素

可以通过下标来访问数组中的元素,下标从0开始,到 n − 1 n-1 n1结束。例如:

arr = [1, 2, 3, 4, 5]
print(arr[0])  # 输出1
print(arr[2])  # 输出3

修改元素

可以通过下标来修改数组中的元素。例如:

arr = [1, 2, 3, 4, 5]
arr[0] = 10
arr[2] = 30
print(arr)  # 输出[10, 2, 30, 4, 5]

插入元素

在数组中插入元素需要将插入位置之后的元素向后移动一位,然后将新元素放入插入位置。例如:

arr = [1, 2, 3, 4, 5]
n = len(arr)
pos = 2  # 插入位置
val = 6  # 插入值

#将插入位置之后的元素向后移动一位
for i in range(n-1, pos-1, -1):
    arr[i+1] = arr[i]

# 插入新元素
arr[pos] = val

print(arr)  # 输出[1, 2, 6, 3, 4, 5]

删除元素

在数组中删除元素需要将删除位置之后的元素向前移动一位,然后将最后一个元素放入删除位置。例如:

arr = [1, 2, 3, 4, 5]
n = len(arr)
pos = 2  # 删除位置

# 将删除位置之后的元素向前移动一位
for i in range(pos, n-1):
    arr[i] = arr[i+1]

# 将最后一个元素放入删除位置
arr[n-1] = None

print(arr)  # 输出[1, 2, 4, 5, None]

遍历数组:可以使用 for 循环来遍历数组

for i in arr:
    print(i)
# 输出:
# 0
# 10
# 2
# 3
# 4

数组操作:列表提供了丰富的方法来操作数组,例如 append()、insert()、pop()、remove() 等。

在这里插入代码片# 在数组末尾添加一个元素
arr.append(5)
print(arr)  # 输出:[0, 10, 2, 3, 4, 5]

# 在数组的第3个位置插入一个元素
arr.insert(2, 20)
print(arr)  # 输出:[0, 10, 20, 2, 3, 4, 5]

# 删除数组的最后一个元素
arr.pop()
print(arr)  # 输出:[0, 10, 20, 2, 3, 4]

# 删除数组中值为20的元素
arr.remove(20)
print(arr)  # 输出:[0, 10, 2, 3, 4]

除了列表之外,Python 还提供了 array 模块,可以用来创建固定类型的数组。例如,以下代码创建一个包含10个整数的数组:

import array
arr = array.array('i', [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

其中 ‘i’ 表示数组中的元素类型为整数。除了 ‘i’,array 模块还支持其他的类型码,例如 ‘f’ 表示单精度浮点数,‘d’ 表示双精度浮点数等等。array 模块中还提供了一些方法。在 Python 中,可以使用内置的 list 类型来实现数组。Python 中的 list 类型实际上是一种动态数组,可以存储任意类型的元素,并且支持动态调整大小。
以下是一些常用的 list 操作方法:
创建一个空的列表:my_list = []
创建一个包含指定元素的列表:my_list = [1, 2, 3]
获取列表长度:len(my_list)
访问列表中的元素:my_list[index]
修改列表中的元素:my_list[index] = new_value
向列表尾部添加一个元素:my_list.append(value)
在指定位置插入一个元素:my_list.insert(index, value)
从列表中删除一个元素:my_list.remove(value)
从列表中删除指定位置的元素:my_list.pop(index)
查找指定元素在列表中的位置:my_list.index(value)
判断一个元素是否在列表中:value in my_list

需要注意的是,Python 中的 list 类型实现方式是基于动态数组的,因此在对列表进行频繁的插入或删除操作时,性能可能会受到影响。如果需要高效地进行频繁的插入或删除操作,可以考虑使用链表或其他数据结构。

**

二、链表

**
链表是一种常见的数据结构,它是由若干个节点组成的序列,每个节点包含数据和指向下一个节点的指针。链表可以分为单向链表、双向链表和循环链表等不同类型。Python中可以使用类来实现链表,具体实现方法如下:
首先,定义链表节点类,包含节点的数据和指向下一个节点的指针:

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

然后,定义链表类,包含链表头和链表尾指针:

class LinkedList:
    def __init__(self):
        self.head = None
        self.tail = None

接着,实现链表的基本操作,例如在链表头部添加节点、在链表尾部添加节点、在指定位置添加节点、删除节点、查找节点等:

class LinkedList:
    ...

    def add_first(self, data):
        new_node = Node(data)
        if not self.head:
            self.head = self.tail = new_node
        else:
            new_node.next = self.head
            self.head = new_node

    def add_last(self, data):
        new_node = Node(data)
        if not self.head:
            self.head = self.tail = new_node
        else:
            self.tail.next = new_node
            self.tail = new_node

    def add_at(self, index, data):
        new_node = Node(data)
        if not self.head:
            self.head = self.tail = new_node
        elif index == 0:
            new_node.next = self.head
            self.head = new_node
        else:
            node = self.head
            for i in range(index - 1):
                if node.next is None:
                    break
                node = node.next
            new_node.next = node.next
            node.next = new_node

    def remove(self, data):
        if not self.head:
            return
        elif self.head.data == data:
            self.head = self.head.next
        else:
            node = self.head
            while node.next:
                if node.next.data == data:
                    node.next = node.next.next
                    if node.next is None:
                        self.tail = node
                    break
                node = node.next

    def find(self, data):
        node = self.head
        while node:
            if node.data == data:
                return node
            node = node.next
        return None

最后,可以使用链表类来创建一个具有一定功能的链表实例:

ll = LinkedList()
ll.add_first(1)
ll.add_first(2)
ll.add_last(3)
ll.add_at(1, 4)
ll.remove(2)
node = ll.find(3)
if node:
    print(node.data)

这样,就可以用Python实现链表数据结构了。

二.1单链表实现:

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

class LinkedList:
    def __init__(self):
        self.head = None

    def add_node(self, data):
        new_node = Node(data)
        if self.head is None:
            self.head = new_node
        else:
            current = self.head
            while current.next is not None:
                current = current.next
            current.next = new_node

    def delete_node(self, data):
        if self.head is None:
            return

        if self.head.data == data:
            self.head = self.head.next
            return

        current = self.head
        while current.next is not None:
            if current.next.data == data:
                current.next = current.next.next
                return
            current = current.next

    def print_list(self):
        current = self.head
        while current is not None:
            print(current.data)
            current = current.next

二、2双向链表实现

class Node:
    def __init__(self, data):
        self.data = data
        self.prev = None
        self.next = None

class DoublyLinkedList:
    def __init__(self):
        self.head = None

    def add_node(self, data):
        new_node = Node(data)
        if self.head is None:
            self.head = new_node
        else:
            current = self.head
            while current.next is not None:
                current = current.next
            current.next = new_node
            new_node.prev = current

    def delete_node(self, data):
        if self.head is None:
            return

        if self.head.data == data:
            self.head = self.head.next
            self.head.prev = None
            return

        current = self.head
        while current.next is not None:
            if current.next.data == data:
                current.next = current.next.next
                if current.next is not None:
                    current.next.prev = current
                return
            current = current.next

    def print_list(self):
        current = self.head
        while current is not None:
            print(current.data)
            current = current.next

二、3双向循环链表

class Node:
    def __init__(self, data=None, prev=None, next=None):
        self.data = data
        self.prev = prev
        self.next = next

class DoublyCircularLinkedList:
    def __init__(self):
        self.head = None

    def is_empty(self):
        return self.head == None

    def add(self, data):
        new_node = Node(data)
        if self.is_empty():
            self.head = new_node
            new_node.prev = new_node
            new_node.next = new_node
        else:
            new_node.prev = self.head.prev
            new_node.next = self.head
            self.head.prev.next = new_node
            self.head.prev = new_node

    def insert(self, index, data):
        new_node = Node(data)
        if self.is_empty():
            self.head = new_node
            new_node.prev = new_node
            new_node.next = new_node
        else:
            cur_node = self.head
            for i in range(index-1):
                cur_node = cur_node.next
            new_node.prev = cur_node
            new_node.next = cur_node.next
            cur_node.next.prev = new_node
            cur_node.next = new_node
            if index == 0:
                self.head = new_node

    def remove(self, data):
        if self.is_empty():
            return
        cur_node = self.head
        while cur_node.data != data:
            cur_node = cur_node.next
            if cur_node == self.head:
                return
        if cur_node == self.head:
            self.head = cur_node.next
        cur_node.prev.next = cur_node.next
        cur_node.next.prev = cur_node.prev

    def print_list(self):
        if self.is_empty():
            print("List is empty")
            return
        cur_node = self.head
        while True:
            print(cur_node.data, end=" ")
            cur_node = cur_node.next
            if cur_node == self.head:
                break
        print()

# Test
dll = DoublyCircularLinkedList()
dll.add(1)
dll.add(2)
dll.add(3)
dll.insert(0, 0)
dll.insert(4, 4)
dll.remove(2)
dll.print_list()

上述代码中,Node 类表示链表的节点,包含数据、前驱节点和后继节点;DoublyCircularLinkedList 类表示双向循环链表,包含一个指向链表头节点的 head 属性,is_empty、add、insert、remove、print_list等操作方法。在 add 方法中,如果链表为空,则将新节点作为头节点,并使其前驱和后继都指向自身;否则将新节点插入到链表尾部,同时将新节点的前驱指向链表尾节点,后继指向头节点,头节点的前驱指向新节点;在 insert 方法中,如果链表为空,则将新节点作为头节点,并使其前驱和后继都指向自身;否则将新节点插入到指定位置,同时修改前驱和后继节点的指针。在 remove 方法中,遍历链表,找到待删除节点并修改前驱和后继节点的指针即可。

二、4静态链表

静态链表(Static Linked List)是指使用数组来模拟链表的一种数据结构。它的实现思想是将链表中的结点通过一个数组来存储,同时利用数组元素的下标来表示链表中结点的指针。

在静态链表中,数组中的每个元素(或称为“节点”)由两个部分组成,一个是存储数据的域,另一个是指向下一个元素(节点)的指针域。由于静态链表的结构可以预先分配,因此在一些空间有限、需要高效利用空间的场合下,使用静态链表是一种比较实用的方法。
下面是一个简单的 Python 实现,实现了静态链表的初始化、添加元素、删除元素等基本操作。

class Node:
    def __init__(self, value, next):
        self.value = value
        self.next = next
        
class StaticLinkedList:
    def __init__(self, capacity):
        self.head = None
        self.capacity = capacity
        self.nodes = [Node(None, i+1) for i in range(capacity)]
        self.nodes[capacity-1].next = 0
        
    def is_full(self):
        return self.nodes[0].next == 0
    
    def is_empty(self):
        return self.head is None
    
    def get_next(self, index):
        return self.nodes[index].next
    
    def insert(self, value):
        if self.is_full():
            raise Exception("Static linked list is full")
        new_node_index = self.nodes[0].next
        new_node = self.nodes[new_node_index]
        new_node.value = value
        self.nodes[0].next = new_node.next
        if self.is_empty():
            new_node.next = 0
        else:
            new_node.next = self.head.next
        self.head = new_node
        
    def delete(self, value):
        if self.is_empty():
            raise Exception("Static linked list is empty")
        prev_node = None
        current_node = self.nodes[self.head.next]
        while current_node.value != value:
            prev_node = current_node
            current_node = self.nodes[current_node.next]
            if current_node == self.head:
                raise Exception("Node with value {} not found".format(value))
        if prev_node is None:
            self.head = None
        else:
            prev_node.next = current_node.next
        self.nodes[current_node.next].next = current_node.next
        current_node.next = self.nodes[0].next
        self.nodes[0].next = self.nodes.index(current_node)
        current_node.value = None

在这个实现中,Node 类表示静态链表中的一个节点,包含两个成员变量 value 和 next,分别表示节点存储的值和指向下一个节点的指针。StaticLinkedList 类表示静态链表,包含了一些基本的操作,如 insert 和 delete 等,还有一些辅助方法,如 is_full 和 is_empty 等,用于判断静态链表是否已满或为空。

链表是一种基本的数据结构,可以用来表示线性结构,如数组、字符串等。相较于数组,链表的插入和删除操作更加灵活和高效,但访问特定位置的元素需要遍历整个链表,效率较低。

链表有多种类型,如单向链表、双向链表、循环链表、静态链表等,它们各自具有特定的优缺点和应用场景。
在 Python 中实现链表可以使用类来表示节点,节点包含数据和指向下一个节点(和前一个节点,如果是双向链表)的指针。对于单向链表和双向链表,我们可以通过指针操作来实现插入、删除和访问等操作。循环链表和双向循环链表在实现上也类似,只需在链表尾部节点的指针指向头部节点即可。

静态链表是一种在数组基础上实现的链表,它通过将数组元素当作节点,使用数组下标作为指针来实现链表的指向,同时还需要一个空闲链表来存储未被占用的节点。静态链表在实现上相对复杂,但可以节省空间和避免动态分配内存的问题。在使用链表时,需要注意链表为空或链表长度不足的情况,以及避免出现循环引用等问题。

以上便是本节内容,有不足请指出,笔者会耐心细致的去看完。下节更新数据结构线性表的栈和队列,有需要的小伙伴可以关注我之后的更新。谢谢各位。

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小翟不会写代码

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值