基本数据结构 — — 列表

  • 节点类
# 定义节点类:
class Node:

    # 初始化
    def __init__(self, data):
        self.data = data
        self.next = None    # 下一个节点为None

    # 获取当前位置(当前指针指向)的数据
    def getData(self):
        return self.data

    # 在当前位置(当前指针指向)写入数据
    def setData(self, data):
        self.data = data

    # 获取下一位置(指针下一个指向)的数据
    def getNext(self):
        return self.next

    # 在下一位置(指针下一个指向)写入数据:
    def setNext(self, next_node):
        self.next = next_node    # next_node为下一个节点的意思
  • 无序列表类
# 定义无序列表类(链表):
class UnorderList:

    # 初始化
    def __init__(self):
        self.head = None    # 头部没有指向任何节点

    # 检查链表是否为空
    def isEmpty(self):
        return self.head == None    # 头部没有指向任何节点(即空链表)

    # 往无序列表的左端添加元素
    def add(self, data):
        tmp = Node(data)    # 创建一个名为tmp的节点
        tmp.setNext(self.head)    # 将tmp节点与已有的链表结构head节点链接起来(即tmp节点下一个指向为head节点,让新增元素与原链表进行拼接)
        self.head = tmp    # 此时新的头节点变成了(tmp节点+旧头节点)

    # 查看链表的长度
    def length(self):
        count = 0    # 用于计算访问了多少个节点?
        current = self.head    # 令当前节点为头节点
        # 开始访问节点,当前节点不为空时:
        while current != None:
            current = current.getNext()   # 当前节点往后窜一位
            count += 1    # 访问数+1

        return count    # 返回访问数

    # 查找链表中的元素
    def search(self, data):
        beFound = False    # 初始化时设定该元素还未找到
        current = self.head    # 令当前节点为头节点
        while current != None:
            currentData = current.getData()    # 获取当前节点上的内容
            if currentData == data:    # 当前获取的内容与所要寻找的内容相同时
                beFound = True    # 该元素找到了

            current = current.getNext()    # 当前节点往后挪一位

        return beFound

    # 移除链表中的元素
    def remove(self, data):
        previous = None    # 初始化前一节点为空
        current = self.head    # 令当前节点为头节点
        beFound = False    # 初始化时设定该元素还未找到
        # 开始访问节点,当前节点不为空时:
        while current != None:
            # 如果当前节点的内容与所需移除的内容相同时:
            if current.getData() == data:
                beFound = True    # 该元素找到了
                break    # 退出while循环
            else:
                previous = current    # 令前一节点为当前节点
                current = current.getNext()    # 当前节点往后挪一位

        # 删除最左端元素时执行下面一行代码
        if previous == None:
            self.head = current.getNext()    # 令头节点指向当前节点的下一节点(移除后拼接)
        else:
            # 删除超出链表范围的元素时执行下面一行代码
            if current == None:
                raise Exception('ValueError: list.remove(x): x not in list')
            # 删除非最左端元素时执行下面一行代码
            else:
                previous.setNext(current.getNext())    # 令前一节点与“当前节点的下一个指向”链接(即让目标元素脱轨,其他元素拼接)

    # 清空链表
    def clear(self):
        self.head = None    # 令头节点不指向任何节点

    # 往链表右端添加元素
    def append(self, data):
        tmp = Node(data)    # 创建一个名为tmp的节点
        # 如果链表为空
        if self.head == None:
            self.head = tmp    # 令头节点指向tmp节点
        # 如果链表不为空
        else:
            current = self.head    # 令当前节点指向头节点
            # 当前节点的下一节点不为空时
            while current.getNext() != None:
                current = current.getNext()    # 当前节点往后挪一位
            # 当前节点的下一节点为空时(到达最右端)
            else:
                current.setNext(tmp)    # 令当前节点与tmp节点链接(即当前节点下一个指向为tmp节点,让原链表与新增元素进行拼接)

    # 在链表任意位置插入元素
    # 当 position<0 或 position>length-1 时,分别在左右端插入元素(未实现)
    def insert(self, position, data):
        assert(position <= self.length())    # 当所选位置超出链表范围时报错
        tmp = Node(data)    # 创建一个名为tmp的节点
        current_position = 0    # 当前节点的位置为0
        previous = None    # 令前一节点为空
        current = self.head    # 令当前节点为头节点
        # 当前节点的位置小于目标位置时
        while current_position < position:
            previous = current    # 令前一节点为当前节点
            current = current.getNext()    # 当前节点往后挪一位
            current_position += 1    # 当前节点的位置+1

        # 在非最左端插入元素时执行下面两行代码
        if previous != None:
            previous.setNext(tmp)    # 令前一节点与tmp节点链接(即前一节点下一个指向为tmp节点,让前一节点与tmp节点拼接)
            tmp.setNext(current)    # 令tmp节点与当前节点链接(即tmp节点下一个指向为当前节点,让tmp节点与当前节点拼接)
        # 在最左端插入元素时执行下面两行代码
        else:
            tmp.setNext(current)    # 令tmp节点与当前节点链接(即tmp节点下一个指向为当前节点,让tmp节点与当前节点拼接)
            self.head = tmp    # 此时新的头节点变成了(tmp节点+旧头节点)

    # 在链表中寻找下标
    def index(self, data):
        assert(self.isEmpty() == False)    # 当链表为空时报错
        current_position = 0    # 当前节点的位置为0
        current = self.head    # 令当前节点为头节点
        # 当前节点不为空时:
        while current != None:
            # 如果当前数据与目标数据相等
            if current.getData() == data:
                break    # 退出while循环

            current = current.getNext()    # 当前节点往后挪一位
            current_position += 1    # 当前节点的位置+1

        # 如果当前节点为空时(达到最右端):
        if current == None:
            raise Exception('ValueError: list.remove(x): x not in list')

        return current_position    # 返回当前节点位置

    # 不传入参数时,默认删除链表中最右端元素
    # 传入参数时,删除链表中对应位置上的元素
    def pop(self, position=None):
        # 情况一:如果不传入参数
        if position == None:
            assert (self.isEmpty() == False)    # 当链表为空时报错
            previous = None    # 令前一节点为空
            current = self.head    # 令当前节点为头节点
            # 当下一节点不为空时:
            while current.getNext() != None:
                previous = current    # 令前一节点等于当前节点
                current = current.getNext()    # 当前节点往后挪一位

            # 如果链表中只有一个元素
            if previous == None:
                self.head = None    # 链表不指向任何元素(链表变空)
            # 如果链表中元素不止一个
            else:
                previous.setNext(None)    # 令前一节点与None链接(即前一节点下一个指向为None,让前一节点与None拼接)
        # 情况二:如果传入参数
        elif position != None:
            assert (self.isEmpty() == False and 0 <= position < self.length())    # 当链表为空和所选位置超出链表范围时报错
            current_position = 0    # 当前节点的位置为0
            previous = None  # 初始化前一节点为空
            current = self.head  # 令当前节点为头节点
            # 当前节点的位置小于等于目标位置时:
            while current_position <= position:
                current_data = current.getData()    # 获取当前节点数据
                previous = current  # 令前一节点为当前节点
                # 如果当前位置与目标位置相同时
                if current_position == position:
                    break    # 退出while循环
                # 如果当前位置与目标位置不相同时
                else:
                    current = current.getNext()  # 当前节点往后挪一位
                    current_position += 1  # 当前节点的位置+1

            # 当链表中元素不止一个时执行下面一行代码
            if previous != None:
                previous.setNext(current.getNext())    # 令前一节点与当前节点的下一指向链接(即前一节点下一个指向为“当前节点的下一指向”,让前一节点与“当前节点的下一指向”拼接)
            # 当链表中只有一个元素时执行下面一行代码
            else:
                self.head = None    # 令头节点不指向任何元素

            return current_data    # 当传入参数时才有返回值

    # 打印链表中的内容
    def __repr__(self):
        start = '['    # 设置链表的固定开头
        end = ']'    # 设置链表的固定结尾
        current = self.head    # 令当前节点为头节点
        # 当前节点不为空时:
        while current != None:
            start += str(current.getData()) + ', '    # 往start中加入“当前节点数据和‘, ’”
            current = current.getNext()  # 当前节点往后挪一位

        # 如果start的长度大于1
        if len(start) > 1:
            start = start[:-2] + end    # 字符串拼接
        # 如果start的长度小于等于1
        else:
            start = start + end    # 字符串拼接

        return start    # 返回start(列表的样子)

    # 返回下标对应的值
    def __getitem__(self, index):
        assert(index >= 0 and index < self.length())    # 当index超出链表范围时报错
        current = self.head    # 令当前节点为头节点
        # 当下标不为0时:
        while index != 0:
            current = current.getNext()    # 当前节点往后挪一位
            index -= 1    # 下标-1

        return current.getData()    # 返回当前节点的数据

    # 设置给定下标的值
    def __setitem__(self, index, value):
        assert(index >= 0 and index < self.length())    # 当index超出链表范围时报错
        current = self.head    # 令当前节点为头节点
        # 当下标不为0时:
        while index != 0:
            current = current.getNext()    # 当前节点往后挪一位
            index -= 1    # 下标-1

        current.setData(value)    # 令当前节点与value链接(即当前节点下一个指向为value,让当前节点与value拼接)
  • 有序列表类
# 定义有序列表类:
class OrderList(UnorderList):

    # 初始化
    def __init__(self):
        super().__init__()    # 继承无序列表

    # isEmpty()、length()、remove()等的实现和父类(UnorderList类)一样

    # 查找元素
    def search(self, data):
        beFound = False    # 还未找到
        current = self.head    # 令当前节点为头节点
        while current != None:
            currentData = current.getData()    # 获取节点上的内容
            if currentData == data:    # 当前获取的内容与所要寻找的内容相同时
                beFound = True
                break
            elif currentData > data:    # 遇到其值大于目标元素的节点时
                beFound = False
                break

            current = current.getNext()   # 当前节点往后窜一位

        return beFound

    # 在左边添加元素
    def add(self, data):
        current = self.head    # 令当前节点为头节点
        previous = None
        stop = False
        # 当前节点不为空且?
        while current != None and not stop:
            if current.getData() > data:
                stop = True
            else:
                previous =current
                current = current.getNext()

        tmp = Node(data)    # 创建一个名为tmp的节点
        if previous != None:
            tmp.setNext(current)
            previous.setNext(tmp)
        else:
            tmp.setNext(self.head)
            self.head = tmp

你可能感兴趣的:(基本数据结构 — — 列表)