Python数据结构学习笔记——链表:无序链表和有序链表

简介: Python数据结构学习笔记——链表:无序链表和有序链表

一、链表

1667141338473.jpg

链表中每一个元素都由为两部分构成:一是该链表节点的数据,二是指向下一个节点的引用。

1、定义节点类,链表中的节点包含数据以及指向下一个节点的引用,在构造方法中定义一个变量data用于存储数据,另定义一个变量next等于None,即指向None的引用,代表传入的节点后面没有元素(由于不确定传入的元素数目),使其指向一个空值;


# 节点类
class Node:
    def __init__(self, initdata):
        self.data = initdata
        self.next = None  # 指向空值,初始化next


2、返回当前指向节点的数据

def getData(self):
        return self.data  # 返回当前数据,无需参数

3、返回当前指向节点指向下一个节点的引用

def getNext(self):
        return self.next  # 返回当前指向下一个节点的引用,无需参数


4、传入新的节点数据

def setData(self, newdata):
        self.data = newdata  # 添加新的数据,包含参数newdata


5、传入指向下一个节点的引用

def setNext(self, newnext):
        self.next = newnext  # 添加新的指向引用,包含参数newnext


通过向链表中添加节点数据以及指向和传入节点的引用来测试,完整代码如下:

# 节点类
class Node:
    def __init__(self, initdata):
        self.data = initdata
        self.next = None  # 指向空值,初始化next
    def getData(self):
        return self.data  # 返回当前数据,无需参数
    def getNext(self):
        return self.next  # 返回当前指向下一个节点的引用,无需参数
    def setData(self, newdata):
        self.data = newdata  # 添加新的数据,包含参数newdata
    def setNext(self, newnext):
        self.next = newnext  # 添加新的指向引用,包含参数newnext
c = Node(2)  # 向链表中传入节点数据"2"
print(c.getData())  # 获取当前指向节点的数据
print(c.getNext())  # 返回当前指向节点指向下一个节点的引用,由于初始化指向引用为None,所以为None
c.setData(36)  # 传入新的节点数据"36"
print(c.getData())  # 获取当前指向节点的数据
c.setData("st")
c.setNext("st")  # 传入指向下一个节点的引用为st
print(c.getNext())
print(c.getData())

运行结果如下:

1667141436393.jpg


二、无序链表 实现步骤分析


通过定义一个无序列表UnorderedList类,然后基于链表Node类的方法实现无序链表,无序列表本身不包含链表中的任何节点,只是其头部指向整个链表结构中第一个节点的引用,该节点包含指向下一个节点的引用。

1、定义无序列表类,head指向None,它表示无序列表的头部没有指向任何节点,即说明这是一个空列表。

# 无序列表类
class UnorderedList:
    def __init__(self):
        self.head = None  # 表示无序列表的头部没有指向任何节点


2、检查列表是否为空,通过比较运算符“==”比较队列是否为空(None),若为空,则返回布尔值False,若不为空,则返回True;

def isEmpty(self):  # 检查无序列表是否为空,不需要参数,返回一个布尔值
        return self.head == None


3、向列表中添加元素,通过节点类Node()的构造方法添加新元素temp,然后利用节点类的setNext()方法传入新的指向引用,即指向链表的头部,此时再将新元素赋值给链表的头部;

def add(self, item):  # 向列表中添加元素
        temp = Node(item)  # 添加新元素temp
        temp.setNext(self.head)  # 传入新的指向引用,指向链表的头部   
        self.head = temp  # 将新元素赋值给链表的头部


4、返回列表中元素数目,首先初始化变量current将列表的头节点赋值给它,然后对列表进行遍历;

def length(self):  # 返回列表中元素数目
        current = self.head  # 定义中间变量current,列表的头节点赋值给该变量
        count = 0
        while current != None:  # 列表遍历
            count = count + 1  # 每当指向一个节点,变量count递加1
            current = current.getNext()  # 返回当前指向下一个节点的引用并赋值给变量current
        return count


5、搜索指定的列表元素,通过输入参数item搜索,遍历列表,found作为一个布尔值,初值为False,若定义的中间变量current的数据等于要搜索的元素时,则说明已搜索到该元素,并将布尔值True赋值给变量found,改变其值然后返回True值;

def search(self, item):  # 在列表中搜索元素item,需参数item
        current = self.head  # 定义中间变量current,列表的头节点赋值给该变量
        found = False
        while current != None and not found:
            if current.geatData() == item:  # 若定义的中间变量的数据等于要搜索的元素时,则将布尔值True赋值给变量found,改变其值
                found = True
            else:  # 若不是要搜索的元素,即对下一个节点进行搜索
                current = current.getNext()  # 返回当前指向下一个节点的引用并赋值给变量current
        return found


6、删除指定的列表元素,删除操作的第一步也是先搜索要要删除的元素;

def remove(self, item):  # 从列表中删除元素item,需参数item
        current = self.head  # 定义中间变量current,列表的头节点赋值给该变量,标记当前位置
        previous = None  # 定义变量previous为空
        found = False
        while not found:  # 若定义的found变量布尔值为True时,while循环一直执行下去
            if current.getData() == item:
                found = True
            else:  # 若found变量布尔值改变,执行以下操作
                previous = current  # 将列表的头节点赋值给该变量previous
                current = current.getNext()  # 返回当前指向下一个节点的引用并赋值给变量current
        if previous == None:  # 若要删除的元素是列表中的头节点时,需改变列表的头节点
            self.head = current.getNext()  # 返回当前指向下一个节点的引用并赋值给列表的头节点
        else:
            previous.setNext(current.getNext())  # 使用previous的setNext方法来完成移除操作,添加新的指向引用,修改后的引用都指向当前指向下一个节点的引用


三、无序链表的Python实现代码


完整代码及测试如下:

# 节点类
class Node:
    def __init__(self, initdata):
        self.data = initdata
        self.next = None  # 指向空值,初始化next
    def getData(self):
        return self.data  # 返回当前数据,无需参数
    def getNext(self):
        return self.next  # 返回当前指向下一个节点的引用,无需参数
    def setData(self, newdata):
        self.data = newdata  # 添加新的数据,包含参数newdata
    def setNext(self, newnext):
        self.next = newnext  # 添加新的指向引用,包含参数newnext
# 无序列表类
class UnorderedList:
    def __init__(self):
        self.head = None  # 表示无序列表的头部没有指向任何节点
    def isEmpty(self):  # 检查无序列表是否为空,不需要参数,返回一个布尔值
        return self.head == None
    def add(self, item):  # 向列表中添加元素
        temp = Node(item)  # 通过节点类Node()的构造方法添加新元素temp
        temp.setNext(self.head)  # 通过节点类的setNext()方法传入新的指向引用,指向链表的头部
        self.head = temp  # 将新元素赋值给链表的头部
    def length(self):  # 返回列表中元素数目
        current = self.head  # 定义中间变量current,列表的头节点赋值给该变量,标记当前位置
        count = 0
        while current != None:  # 列表遍历
            count = count + 1  # 每当指向一个节点,变量count递加1
            current = current.getNext()  # 返回当前指向下一个节点的引用并赋值给变量current
        return count
    def search(self, item):  # 在列表中搜索元素item,需参数item
        current = self.head  # 定义中间变量current,列表的头节点赋值给该变量,标记当前位置
        found = False
        while current != None and not found:
            if current.getData() == item:  # 若定义的中间变量的数据等于要搜索的元素时,则将布尔值True赋值给变量found,改变其值
                found = True
            else:  # 若不是要搜索的元素,即对下一个节点进行搜索
                current = current.getNext()  # 返回当前指向下一个节点的引用并赋值给变量current
        return found
    def remove(self, item):  # 从列表中删除元素item,需参数item
        current = self.head  # 定义中间变量current,列表的头节点赋值给该变量,标记当前位置
        previous = None  # 定义变量previous为空
        found = False
        while not found:  # 若定义的found变量布尔值为True时,while循环一直执行下去
            if current.getData() == item:
                found = True
            else:  # 若found变量布尔值改变,执行以下操作
                previous = current  # 将列表的头节点赋值给该变量previous
                current = current.getNext()  # 返回当前指向下一个节点的引用并赋值给变量current
        if previous == None:  # 若要删除的元素是列表中的头节点时,需改变列表的头节点
            self.head = current.getNext()  # 返回当前指向下一个节点的引用并赋值给列表的头节点
        else:
            previous.setNext(current.getNext())  # 使用previous的setNext方法来完成移除操作,添加新的指向引用,修改后的引用都指向当前指向下一个节点的引用
# 测试
mylist = UnorderedList()  # 创建一个无序链表
print(mylist.isEmpty())  # 检查链表是否为空
mylist.add(39)
mylist.add(154)
mylist.add("trr")
mylist.add(10)
print(mylist.isEmpty())
print(mylist.length())  # 返回列表的元素数目
print(mylist.search(21))
print(mylist.search("trr"))
mylist.remove(39)
print(mylist.length())
print(mylist.search(39))


运行结果如下:

1667141548602.jpg


四、有序链表 实现步骤分析


通过定义一个有序列表OrderedList类,然后基于链表Node类的方法实现有序链表,有序列表为升序排列或降序排列,它的一些操作基本与无序列表相同,只是search搜索元素和add添加元素要需要根据其修改。

1、定义有序列表类,与有序列表一样,也是head引用指向None,代表它是一个空列表;

# 无序列表类
class OrderedList:
    def __init__(self):
        self.head = None  # 表示无序列表的头部没有指向任何节点


2、检查列表是否为空,通过比较运算符“==”比较队列是否为空(None),若为空,则返回布尔值False,若不为空,则返回True;

def isEmpty(self):  # 检查无序列表是否为空,不需要参数,返回一个布尔值
        return self.head == None


3、向列表中添加元素,首先确定位置然后条件元素;


 

def add(self, item):  # 向列表中添加元素
        current = self.head  # 定义中间变量current,列表的头节点赋值给该变量,标记当前位置
        previous = None  # 定义变量previous值为空
        stop = False
        while current != None and not stop:  # 变量previous值跟在变量current后面,只要还有节点且不大于要添加的元素while循环一直进行下去
            if current.getData() > item:
                stop = True
            else:
                previous = current
                current = current.getNext()
        temp = Node(item)  # 通过节点类Node()的构造方法添加新元素temp
        if previous == None:  # 判断添加的元素添加到链表的开头还是中间某个位置
            temp.setNext(self.head)  # 通过节点类的setNext()方法传入新的指向引用,指向链表的头部
            self.head = temp  # 将新元素赋值给链表的头部
        else:
            temp.setNext(current)
            previous.setNext(temp)


4、返回列表中元素数目,首先初始化变量current将列表的头节点赋值给它,然后对列表进行遍历;

def length(self):  # 返回列表中元素数目
        current = self.head  # 定义中间变量current,列表的头节点赋值给该变量
        count = 0
        while current != None:  # 列表遍历
            count = count + 1  # 每当指向一个节点,变量count递加1
            current = current.getNext()  # 返回当前指向下一个节点的引用并赋值给变量current
        return count


5、搜索指定的列表元素,通过输入参数item搜索,遍历列表,found作为一个布尔值,初值为False,若定义的中间变量current的数据等于要搜索的元素时,则说明已搜索到该元素,并将布尔值True赋值给变量found,改变其值然后返回True值,若不是要搜索的元素,即对下一个节点进行搜索,遇到中间值大于目标元素的节点,则将stop值设为True,否则将中间变量的指向下一个节点的引用赋值给current,然后继续进行while循环;

def search(self, item):  # 在列表中搜索元素item,需参数item
        current = self.head  # 定义中间变量current,列表的头节点赋值给该变量,标记当前位置
        found = False
        stop = False
        while current != None and not found and not stop:
            if current.getData() == item:  # 若定义的中间变量的数据等于要搜索的元素时,则将布尔值True赋值给变量found,改变其值
                found = True
            else:  # 若不是要搜索的元素,即对下一个节点进行搜索
                if current.getData() > item:  # 若遇到中间值大于目标元素的节点,则将stop值设为True
                    stop = True
                else:
                    current = current.getNext()  # 否则返回当前指向下一个节点的引用并赋值给变量current
        return found


6、删除指定的列表元素,删除操作的第一步也是先搜索要要删除的元素;

def remove(self, item):  # 从列表中删除元素item,需参数item
        current = self.head  # 定义中间变量current,列表的头节点赋值给该变量,标记当前位置
        previous = None  # 定义变量previous为空
        found = False
        while not found:  # 若定义的found变量布尔值为True时,while循环一直执行下去
            if current.getData() == item:
                found = True
            else:  # 若found变量布尔值改变,执行以下操作
                previous = current  # 将列表的头节点赋值给该变量previous
                current = current.getNext()  # 返回当前指向下一个节点的引用并赋值给变量current
        if previous == None:  # 若要删除的元素是列表中的头节点时,需改变列表的头节点
            self.head = current.getNext()  # 返回当前指向下一个节点的引用并赋值给列表的头节点
        else:
            previous.setNext(current.getNext())  # 使用previous的setNext方法来完成移除操作,添加新的指向引用,修改后的引用都指向当前指向下一个节点的引用


五、有序链表的Python实现代码


完整代码及测试如下:

# 节点类
class Node:
    def __init__(self, initdata):
        self.data = initdata
        self.next = None  # 指向空值,初始化next
    def getData(self):
        return self.data  # 返回当前数据,无需参数
    def getNext(self):
        return self.next  # 返回当前指向下一个节点的引用,无需参数
    def setData(self, newdata):
        self.data = newdata  # 添加新的数据,包含参数newdata
    def setNext(self, newnext):
        self.next = newnext  # 添加新的指向引用,包含参数newnext
# 无序列表类
class OrderedList:
    def __init__(self):
        self.head = None  # 表示无序列表的头部没有指向任何节点
    def isEmpty(self):  # 检查无序列表是否为空,不需要参数,返回一个布尔值
        return self.head == None
    def add(self, item):  # 向列表中添加元素
        current = self.head  # 定义中间变量current,列表的头节点赋值给该变量,标记当前位置
        previous = None  # 定义变量previous值为空
        stop = False
        while current != None and not stop:  # 变量previous值跟在变量current后面,只要还有节点且不大于要添加的元素while循环一直进行下去
            if current.getData() > item:
                stop = True
            else:
                previous = current
                current = current.getNext()
        temp = Node(item)  # 通过节点类Node()的构造方法添加新元素temp
        if previous == None:  # 判断添加的元素添加到链表的开头还是中间某个位置
            temp.setNext(self.head)  # 通过节点类的setNext()方法传入新的指向引用,指向链表的头部
            self.head = temp  # 将新元素赋值给链表的头部
        else:
            temp.setNext(current)
            previous.setNext(temp)
    def length(self):  # 返回列表中元素数目
        current = self.head  # 定义中间变量current,列表的头节点赋值给该变量,标记当前位置
        count = 0
        while current != None:  # 列表遍历
            count = count + 1  # 每当指向一个节点,变量count递加1
            current = current.getNext()  # 返回当前指向下一个节点的引用并赋值给变量current
        return count
    def search(self, item):  # 在列表中搜索元素item,需参数item
        current = self.head  # 定义中间变量current,列表的头节点赋值给该变量,标记当前位置
        found = False
        stop = False
        while current != None and not found and not stop:
            if current.getData() == item:  # 若定义的中间变量的数据等于要搜索的元素时,则将布尔值True赋值给变量found,改变其值
                found = True
            else:  # 若不是要搜索的元素,即对下一个节点进行搜索
                if current.getData() > item:  # 若遇到中间值大于目标元素的节点,则将stop值设为True
                    stop = True
                else:
                    current = current.getNext()  # 否则返回当前指向下一个节点的引用并赋值给变量current
        return found
    def remove(self, item):  # 从列表中删除元素item,需参数item
        current = self.head  # 定义中间变量current,列表的头节点赋值给该变量,标记当前位置
        previous = None  # 定义变量previous值为空
        found = False
        while not found:  # 若定义的found变量布尔值为True时,while循环一直执行下去
            if current.getData() == item:
                found = True
            else:  # 若found变量布尔值改变,执行以下操作
                previous = current  # 将列表的头节点赋值给该变量previous
                current = current.getNext()  # 返回当前指向下一个节点的引用并赋值给变量current
        if previous == None:  # 若要删除的元素是列表中的头节点时,需改变列表的头节点
            self.head = current.getNext()  # 返回当前指向下一个节点的引用并赋值给列表的头节点
        else:
            previous.setNext(current.getNext())  # 使用previous的setNext方法来完成移除操作,添加新的指向引用,修改后的引用都指向当前指向下一个节点的引用
# 测试
mylist = OrderedList()  # 创建一个有序链表
print(mylist.isEmpty())  # 检查链表是否为空
mylist.add(39)  # 添加元素
mylist.add(154)
mylist.add(10)
print(mylist.isEmpty())
print(mylist.length())  # 返回列表的元素数目
print(mylist.search(21))
mylist.remove(39)  # 移除元素39
print(mylist.length())
print(mylist.search(39))


运行结果如下:

1667141158238.jpg

相关文章
|
7天前
|
算法 安全 大数据
揭秘!Python堆与优先队列:数据结构的秘密武器,让你的代码秒变高效战士!
【7月更文挑战第8天】Python的heapq模块和queue.PriorityQueue提供堆与优先队列功能,助你提升算法效率。堆用于快速找大数据集的第K大元素,如示例所示,时间复杂度O(n log k)。PriorityQueue在多线程中智能调度任务,如模拟下载管理器,按优先级处理任务。掌握这些工具,让代码运行更高效!
21 1
|
3天前
|
算法 Python
逆袭之路!用 Python 玩转图的 DFS 与 BFS,让数据结构难题无处遁形
【7月更文挑战第12天】图的遍历利器:DFS 和 BFS。Python 中,图可表示为邻接表或矩阵。DFS 沿路径深入,回溯时遍历所有可达顶点,适合找路径和环。BFS 层次遍历,先近后远,解决最短路径问题。两者在迷宫、网络路由等场景各显神通。通过练习,掌握这些算法,图处理将游刃有余。
10 3
|
2天前
|
存储 算法 Python
“解锁Python高级数据结构新姿势:图的表示与遍历,让你的算法思维跃升新高度
【7月更文挑战第13天】Python中的图数据结构用于表示复杂关系,通过节点和边连接。常见的表示方法是邻接矩阵(适合稠密图)和邻接表(适合稀疏图)。图遍历包括DFS(深度优先搜索)和BFS(广度优先搜索):DFS深入探索分支,BFS逐层访问邻居。掌握这些技巧对优化算法和解决实际问题至关重要。**
9 1
|
3天前
|
存储 缓存 Python
Python中的列表(List)和元组(Tuple)是两种重要的数据结构
【7月更文挑战第12天】Python中的列表(List)和元组(Tuple)是两种重要的数据结构
6 1
|
5天前
|
存储 算法 调度
惊呆了!Python高级数据结构堆与优先队列,竟然能这样优化你的程序性能!
【7月更文挑战第10天】Python的heapq模块实现了堆和优先队列,提供heappush和heappop等函数,支持O(log n)时间复杂度的操作。优先队列常用于任务调度和图算法,优化性能。例如,Dijkstra算法利用最小堆加速路径查找。堆通过列表存储,内存效率高。示例展示了添加、弹出和自定义优先级元素。使用堆优化程序,提升效率。
15 2
|
2天前
|
存储 数据可视化 数据处理
`geopandas`是一个开源项目,它为Python提供了地理空间数据处理的能力。它基于`pandas`库,并扩展了其对地理空间数据(如点、线、多边形等)的支持。`GeoDataFrame`是`geopandas`中的核心数据结构,它类似于`pandas`的`DataFrame`,但包含了一个额外的地理列(通常是`geometry`列),用于存储地理空间数据。
`geopandas`是一个开源项目,它为Python提供了地理空间数据处理的能力。它基于`pandas`库,并扩展了其对地理空间数据(如点、线、多边形等)的支持。`GeoDataFrame`是`geopandas`中的核心数据结构,它类似于`pandas`的`DataFrame`,但包含了一个额外的地理列(通常是`geometry`列),用于存储地理空间数据。
4 0
|
7天前
|
算法 安全 调度
逆天改命!Python高级数据结构堆(Heap)与优先队列,让你的算法效率飙升至宇宙级!
【7月更文挑战第8天】Python的heapq模块和queue.PriorityQueue实现了堆和优先队列,提供高效算法解决方案。堆用于Dijkstra算法求解最短路径,例如在图论问题中;PriorityQueue则在多线程下载管理中确保高优先级任务优先执行。这两个数据结构提升效率,简化代码,是编程中的强大工具。
10 0
|
2月前
|
存储 数据可视化 数据挖掘
Python在数据分析中的利器:Pandas库全面解析
【2月更文挑战第7天】 众所周知,Python作为一种简洁、易学且功能强大的编程语言,被广泛运用于数据科学和人工智能领域。而Pandas库作为Python中最受欢迎的数据处理库之一,在数据分析中扮演着举足轻重的角色。本文将全面解析Pandas库的基本功能、高级应用以及实际案例,带您深入了解这个在数据分析领域的利器。
132 1
|
2月前
|
SQL 数据挖掘 数据处理
Python数据分析(二)—— Pandas快速入门
Python数据分析(二)—— Pandas快速入门
|
3天前
|
机器学习/深度学习 数据采集 数据挖掘
解锁 Python 数据分析新境界:Pandas 与 NumPy 高级技巧深度剖析
【7月更文挑战第12天】Python的Pandas和NumPy库助力高效数据处理。Pandas用于数据清洗,如填充缺失值和转换类型;NumPy则擅长数组运算,如元素级加法和矩阵乘法。结合两者,可做复杂数据分析和特征工程,如产品平均销售额计算及销售额标准化。Pandas的时间序列功能,如移动平均计算,进一步增强分析能力。掌握这两者高级技巧,能提升数据分析质量和效率。
17 4