Python 顺序表与链表

一、顺序表

顺序表是将元素顺序地存放在一块连续的存储区里,元素间的顺序关系由它们的存储顺序自然表示。以下为顺序表的基本实现(使用列表)

# 创建顺序表
seq_list = [10, 20, 30, 40, 50]  # Python列表本身就是顺序表的实现

# 访问元素 - O(1)
print("第三个元素:", seq_list[2])  # 输出: 30

# 插入元素 - 平均O(n)
seq_list.insert(2, 25)  # 在索引2处插入25
print("插入后:", seq_list)  # 输出: [10, 20, 25, 30, 40, 50]

# 删除元素 - 平均O(n)
seq_list.pop(3)  # 删除索引3的元素
print("删除后:", seq_list)  # 输出: [10, 20, 25, 40, 50]

# 查找元素 - O(n)
index = seq_list.index(40)  # 查找40的索引
print("40的索引位置:", index)  # 输出: 3

# 顺序表特点:
# 1. 随机访问速度快(O(1))
# 2. 插入删除操作慢(O(n))
# 3. 需要预先分配连续内存空间

二、链表

链表是通过指针将一组零散的内存块串联起来的数据结构,每个节点包含数据和指向下一个节点的指针。

1、单链表的基本实现

"""
链表的增删查改操作,如有错误,敬请谅解,也请及时告知,非常感谢!
"""

class Node():
    """链表节点类"""
    def __init__(self, data):
        self.data = data
        self.next = None

class listNode():
    """单链表实现"""
    def __init__(self):
        self.head = None
    def is_empty(self):
        """判断单链表是否为空"""
        return self.head is None
    def length(self):
        """计算链表长度"""
        count = 0
        current = self.head
        while current:
            count += 1
            current = current.next
        return count
    def append(self,data):
        """为链表添加元素"""
        if self.is_empty():
            self.head = Node(data)
        else:
            current = self.head
            while current.next:
                current = current.next
            current.next = Node(data)

    def print_list(self):
        current = self.head
        while current:
            print("{}->".format(current.data),end='')
            current = current.next
        print("NULL")
    def insert(self,index,data):
        """在某索引出插入新节点,index从0开始"""
        if index > self.length():
            raise IndexError("index out of range")
        new_node = Node(data)
        current = self.head
        if index == 0:
            new_node.next = current
            self.head = new_node #注意这里不可以是current,你把变量名 current 指向了另一个对象(new_node),
                                # 但 这并不会改变 self.head,因为 current 只是一个局部变量;
                                # Python 里简单的赋值(=)永远不会修改原对象,只会重绑定名字。
        else:
            for i in range(index-1):
                current = current.next
            new_node.next = current.next
            current.next = new_node

    def remove_index(self,index):
        """删除某索引节点,index从0开始"""
        if self.is_empty():
            print('链表为空!')
            return
        if index > self.length()-1:
            raise IndexError("index out of range")
        if index == 0:
            self.head = self.head.next
        else:
            current = self.head
            pre = None
            for i in range(index):
                pre = current
                current = current.next
            pre.next = current.next
    def remove_data(self,data):
        """删除数据为data的节点"""
        if self.is_empty():
            print('链表为空!')
            return
        current = self.head
        prev = None
        while current:
            if current.data == data:
                if prev is None:
                    self.head = current.next
                else:
                    prev.next = current.next
            prev = current
            current = current.next
    def search_index(self,data):
        """输入某数值的索引"""
        index = []
        count = 0
        current = self.head
        while current:
            if current.data == data:
                index.append(count)
            count = count + 1
            current = current.next
        return index
    def search_data(self,index):
        if self.is_empty():
            print("链表为空!")
            return
        if index > self.length()-1:
            raise IndexError("index out of range")
        current = self.head
        for i in range(index):
            current = current.next
        return current.data


x = listNode()
x.append(1)
x.append(2)
x.append(3)
x.append(4)
x.append(5)
x.append(6)
x.print_list()             #输出:1->2->3->4->5->6->NULL
x.insert(1,7)
x.print_list()             #输出:1->7->2->3->4->5->6->NULL
x.remove_data(7)
x.print_list()              #输出:1->2->3->4->5->6->NULL
x.remove_index(1)
x.print_list()              #输出:1->3->4->5->6->NULL

a = x.search_index(5)
print(a)                    #输出:[3]
b = x.search_data(4)
print(b)                    #输出:6

2、双向链表的实现 

每个节点不仅保存「下一个节点的引用」,还额外保存「上一个节点的引用」。
因此,它可以在 O(1) 时间内:

  • 从任意已知节点向前或向后移动

  • 在已知节点前/后插入、删除(不需要从头遍历找前驱)

class DNode:
    """双向链表节点类"""
    def __init__(self, data):
        self.data = data
        self.next = None # 指向前驱节点
        self.prev = None # 指向后继节点

class DoublyLinkedNode:
    def __init__(self):
        self.head = None
        self.tail = None
    def append(self, data):
        """尾部添加节点"""
        new_node = DNode(data)
        if self.head is None:
            self.head = self.tail = new_node
        else:
            new_node.prev = self.tail
            self.tail.next = new_node
            self.tail = new_node
    def remove(self, data):
        """删除节点"""
        current = self.head
        while current:                          #意味着至少有一个节点
            if current.data == data:
                if current.prev is None:        #要删除第一个节点(头结点)
                    self.head = current.next
                    if self.head:               #链表有两个及以上的节点
                        self.head.prev = None
                    else:                       #链表只有一个节点,即删除第一个节点后为空链表
                        self.tail = None
                elif current.next is None:      #删除尾节点,此时经过第一次分支后,说明链表至少有两个节点。
                    self.tail = current.prev
                    self.tail.next = None
                else:                           #删除中间节点
                    current.prev.next = current.next
                    current.next.prev = current.prev
            current = current.next
    def __str__(self):
        """打印链表"""
        nodes_data = []
        current = self.head
        while current:
            nodes_data.append(str(current.data))
            current = current.next
        return '<->'.join(nodes_data)

x = DoublyLinkedNode()
x.append(1)
x.append(2)
x.append(3)
x.append(4)
x.append(5)
x.append(6)
print(x)    #输出内容1<->2<->3<->4<->5<->6
x.remove(5)
print(x)    #输出内容1<->2<->3<->4<->6

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值