数据结构与算法python—6.链表及python实现

本文介绍了链表的基本概念,对比了链表和数组的优缺点,并详细讲解了单链表、单向循环链表、双向链表和双向循环链表的Python实现,包括它们的添加、删除、查询和更新等操作。通过这些实现,展示了链表的动态数据结构特性。
摘要由CSDN通过智能技术生成

一、链表介绍

1.为什么需要链表?

  动态数组(顺序表)的构建底层依托静态数组,需要预先知道数据大小来申请连续的存储空间,而在进行扩容resize时又需要进行数据的搬迁,可能会造成内存空间的大量浪费;并且在插入与删除时需要移动大量的元素,所以使用起来并不是很灵活。
  链表结构可以充分利用计算机内存空间,实现灵活的内存动态管理。链表是真正的动态数据结构。

2.什么是链表?

  链表(Linked list)是一种常见的基础数据结构,它不像数组一样连续存储数据,而是在每一个节点(数据存储单元)里存放下一个节点的位置信息(即地址)
在这里插入图片描述
优点:真正的动态,不需要处理固定容量的问题
缺点:丧失了随机访问的能力

3.数组与链表对比

  数组连续存储数据,数组最好索引有语义的情况,最大的优点是支持快速查询。
  链表通过在每一个节点(数据存储单元)里存放下一个节点的位置信息(即地址)来充分利用计算机内存空间。链表不适合用于索引有语义的情况,最大的优点是动态。

二、单链表

1.什么是单链表?

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

表元素域elem用来存放具体的数据。
链接域next用来存放下一个节点的位置(python中的标识)
变量p指向链表的头节点(首节点)的位置,从p出发能找到表中的任意节点。

2.单链表python实现

  下面单链表要实现如下功能:添加、删除、查询、更新、包含

  1. is_empty() 链表是否为空
  2. length() 链表长度
  3. add(item) 链表头部添加元素
  4. append(item) 链表尾部添加元素
  5. insert(pos, item) 指定位置添加元素
  6. remove(item) 删除节点
  7. removeIndex(index)删除某一索引的元素
  8. search(item) 查找节点是否存在(包含)
  9. get(index)查询某一索引的元素(查询)
  10. setter(elem)更新某一索引的元素为elem(更新)
2.1 节点的实现
class _Node:
	def __init__(self, e=None):
	    self.e = e
	    self.next = None
	
	def __str__(self):
	    return str(self.e)
	
	def __repr__(self):
	    return self.__str__()

class SingleLinkList(object):
    '''单链表'''

    def __init__(self, node=None):  # 默认参数为None
        self.__head = node
2.2 is_empty() 链表是否为空
    def is_empty(self):
        '''is_empty() 链表是否为空'''
        return self.__head is None
2.3 length() 链表长度

在这里插入图片描述

def length(self):
    '''链表长度'''
    # cur游标 用来遍历节点
    # count 记录数量
    cur = self.__head
    count = 0
    while cur != None:
        count += 1
        cur = cur.next
    return count
2.4 add(item) 链表头部添加元素

在这里插入图片描述

def add(self,item):
    '''链表头部添加元素,"头插法"'''
    node = Node(item)
    node.next = self.__head
    self.__head = node
2.5 append(item) 链表尾部添加元素

在这里插入图片描述

def append(self,item):
    #创建节点
    node = Node(item)
    #判断链表是否为空
    if self.is_empty():
        self.__head = node
    else:
        cur = self.__head
        while cur.next != None:
            cur = cur.next
        #循环退出时,cur指向最后一个节点
        cur.next = node
2.6 insert(pos, item) 指定位置添加元素

在这里插入图片描述

def insert(self,pos,item):
    '''指定位置添加元素
    :param  pos 从0开始
    '''
    if pos <= 0:
        self.add(item)
    elif pos >(self.length()-1):        #没有等号
        self.append(item)
    else:
        node = Node(item)
        cur = self.__head
        count = 0           #记录移动到哪个位置
        while count < (pos-1):      #当循环退出后,cur指向pos-1位置
            count += 1
            cur = cur.next
        node.next = cur.next
        cur.next = node
2.7 remove(item) 删除节点

在这里插入图片描述

def remove(self,item):
    '''删除节点'''
    cur = self.__head
    pre = None
    count =0            #用来返回删除的值的下标
    while cur != None:		#循环内所有点都照顾到
        count += 1
        if cur.elem == item:
            #判断此节点是否是头节点
            if cur == self.__head:
                self.__head = cur.next          
            else:
                pre.next = cur.next             #删除的是最后一个节点,此时pre.next = None,满足
            return count
        else:
            pre = cur
            cur = cur.next
2.8 removeIndex(index)删除某一索引的元素
def removeIndex(self,index):
        if index < 0 and index >= self.length():
            raise Exception('removeindex failed. illegal index')
        curr = self.__head
        per = None
        for i in range(index):
            per = curr
            curr = curr.next
        e = curr.elem
        per.next = curr.next
        return e
2.9 search(item) 查找节点是否存在
def search(self,item):
    '''查找节点是否存在'''
    cur = self.__head
    while cur != None:          #若为while cur.next != None:则最后一个节点比较不了
        if cur.elem == item:
            return True
            #return是结束函数执行并返回值
        else:
            cur = cur.next
    return False
2.10 get(index)查询某一节点的元素
def get(self, index):
	if index < 0 and index >= self.length():
	    raise Exception('get filled. Illegal index!')
	cur = self.__head
	for i in range(index):
	    cur = cur.next
	return cur.elem
2.11 setter(elem)更新某一索引的元素为elem
    def setter(self, index, elem):
        """
        更新某一索引的元素为elem
        """
        if index < 0 and index >= self.length():
            raise Exception('get filled. Illegal index!')
        cur = self.__head
        for i in range(index):
            cur = cur.next
        cur.elem = elem
2.12 全部代码

这里的全部代码与上面的代码有些许不同,上面是self._head = 头节点,下面是self._head.next = 下一节点 ,下面更通用一点!

# 定义节点
class Node:
    def __init__(self, e=None):
        self.e = e
        self.next = None

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

    def __repr__(self):
        return self.__str__()


# 定义单链表
class LinkList:
    def __init__(self):
        # 初始化虚拟头结点
        self._head = Node()
        self.size = 0

    # 判断链表是否为空
    def is_empty(self):
        return self.size == 0

    # 判断链表的长度
    def get_size(self):
        return self.size

    # 链表头部添加元素
    def add_first(self, elem):
        # 初始化节点
        node = Node(elem)
        node.next = self._head.next
        self._head.next = node
        self.size += 1

    # 往链表尾部添加元素
    def add_last(self, elem):
        # 初始化节点
        node = Node(elem)
        # 判断链表是否为空
        if self._head.next is None:
            self._head.next = node
            self.size += 1

        # 如果链表非空,则进行遍历,直到找到链表尾部
        cur = self._head.next
        pre = self._head
        while cur:
            pre = cur
            cur = cur.next
        # 当循环结束时,pre指向链表末尾,cur指向None
        pre.next = node
        node.next = None
        self.size += 1

    # 往链表指定位置添加元素
    def add(self, index, elem):
        # 往头部添加
        if index <= 0:
            self.add_first(elem)
        # 往尾部添加
        elif index >= self.size:
            self.add_last(elem)
        # 往中间添加,基本思路是先找到插入位置的前一个元素,就可以解决这个问题
        else:
            node = Node(elem)
            cur = self._head.next
            for _ in range(index):
                cur = cur.next

            # 当循环结束时,cur指针指向的是要插入位置的前一个位置
            node.next = cur.next
            cur.next = node
            self.size += 1

    # 从链表指定位置删除元素
    def remove(self, index):
        if index < 0 or index >= self.size:
            raise Exception('Remove failed! illegal index')

        pre = self._head
        cur = self._head.next
        for _ in range(index):
            pre = cur
            cur = cur.next
        # 循环结束时,cur指针指向指定位置,pre指针指向前面一个位置
        tmp = cur
        pre.next = cur.next
        self.size -= 1
        return tmp.e

    # 从链表头部位置删除元素
    def remove_first(self):
        return self.remove(0)

    # 从链表尾部删除元素
    def remove_last(self):
        return self.remove(self.size - 1)

    # 对链表某一位置的元素重新赋值
    def setter(self
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值