线性结构:无序列表

文章目录

      • 无序表定义
      • 链表定义
      • 链表实现

无序表定义

列表List是一种简单强大的数据集结构提供了丰富的操作接口

  • 但并不是所有的编程语言都提供了List数据类型,有时候需要程序员自己实现。

一种数据项按照相对位置存放的数据集

  • 称为“无序表unordered list”其中数据项只按照存放位置来索引,如第1个、第2个……、最后一个等。(为了简单起见,假设表中不存在重复数据项)

无序表操作定义

  • List():创建一个空列表
  • add(item):添加一个数据项到列表中,假设item原先不存在于列表中
  • remove(item):从列表中移除item,列表被修改, item原先应存在于表中
  • search(item):在列表中查找item,返回布尔类型值
  • isEmpty():返回列表是否为空
  • size():返回列表包含了多少数据项
  • append(item):添加一个数据项到表末尾,假设item原先不存在于列表中
  • index(item):返回数据项在表中的位置
  • insert(pos, item):将数据项插入到位置pos,假设item原先不存在与列表中,同时原列表具有足够多个数据项,能让item占据位置pos
  • pop():从列表末尾移除数据项,假设原列表至少有1个数据项
  • pop(pos):移除位置为pos的数据项,假设原列表存在位置
class AList:
    def __init__(self):
        self.items = []

    def add(self, item):
        self.items + [item]

    def remove(self, item):
        self.items.remove(item)

    def search(self, item):
        return item in self.items

    def is_empty(self):
        return self.items == []

    def size(self):
        return len(self.items)

    def append(self, item):
        self.items.append(item)

    def index(self, item):
        return self.items.index(item)

    def insert(self, pos, item):
        self.items.insert(pos, item)

    def pop(self):
        return self.items.pop()

    def pop(self, pos):
        return self.items.pop(pos)

链表定义

为了实现无序表数据结构,可以采用链接表的方案。

  • 虽然列表数据结构要求保持数据项的前后相对位置,但这种前后位置的保持,并不要求数据项依次存放在连续的存储空间

数据项存放位置并没有规则,但如果在数据项之间建立链接指向,就可以保持其前后相对位置

  • 第一个和最后一个数据项需要显式标记出来,一个是队首,一个是队尾,后面再无数据了。
线性结构:无序列表_第1张图片

链表实现的最基本元素是节点Node

  • 每个节点至少要包含2个信息:数据项本身,以及指向下一个节点的引用信息注意next为None的意义是没有下一个节点了
线性结构:无序列表_第2张图片
class Node:
    def __init__(self, initdata):
        self.data = initdata
        self.next = None

    def get_data(self):
        return self.data

    def get_next(self):
        return self.next

    def set_data(self, newdata):
        self.data = newdata

    def set_next(self, newnext):
        self.next = newnext

无序表:UnorderedList

可以采用链接节点的方式构建数据集来实现无序表

链表的第一个和最后一个节点最重要

  • 如果想访问到链表中的所有节点,就必须从第一个节点开始沿着链接遍历下去
线性结构:无序列表_第3张图片

无序表对第一个节点的引用

class UnorderedList:
    # 属性head保存对第一个节点的引用,空表head为None
    def __init__(self):
        self.head = None

my_list = UnorderedList()
print(my_list.head)  # None

随着数据项的加入,无序表的head始终指向链条中的第一个节点

  • 注意!无序表mylist对象本身并不包含数据项(数据项在节点中)其中包含的head只是对首个节点Node的引用
  • 判断空表的isEmpty()
    • return self.head == None

链表实现

add方法

  • 由链表结构我们知道要访问到整条链上的所有数据项都必须从表头head开始沿着next链接逐个向后查找

  • 所以添加新数据项最快捷的位置是表头,整个链表的首位置。

线性结构:无序列表_第4张图片

相当于insert(0),链表:最先加入的数据项会成为最后一项,最后加入的会成为第一项。

    def add(self, item):  # 从表头添加
        temp = Node(item)  # 创建一个新节点
        # 链接次序很重要
        temp.set_next(self.head)  # 设置新节点指向原来的头节点 
        self.head = temp  # 添加后将新节点设置为新的头节节点
线性结构:无序列表_第5张图片

size方法

size :从链条头head开始遍历到表尾同时用变量累加经过的节点个数。

线性结构:无序列表_第6张图片
    def size(self):
        current = self.head  # 设置当前结点指向表头
        count = 0
        while current != None:
            count += 1
            current = current + 1
            current = current.get_next()
        return count

search方法

从链表头head开始遍历到表尾,同时判断当前节点的数据项是否目标

线性结构:无序列表_第7张图片
    def search(self, item):
        current = self.head
        found = False
        while current != None and not found:
            if current.get_data() == item:
                found = True
            else:
                current = current.get_next()
        return found

remove方法

首先要找到item ,这个过程跟search一样

  • 但在删除节点时,current指向的是当前匹配数据项的节点
  • 而删除需要把前一个节点的next指向current的下一个节点
  • 所以我们在search current的同时,还要维护前一个(previous)节点的引用
线性结构:无序列表_第8张图片

找到item之后, current指向item节点,previous指向前一个节点,开始执行删除,需要区分两种情况:

  • current是首个节点;或者是位于链条中间的节点
    def remove(self, item):
        current = self.head  # 当前节点
        previous = None  # 前序节点初始化为None
        found = False
        while current != None and not found:
            if current.get_data() == item:
                found = True  # 找到就结束循环
            else:
                previous = current  # 前序节点更新为当前节点
                current = current.get_next()  # 当前节点更新为下一个节点
        if previous == None:  # 如果删除元素是第一个数据项
            self.head = current.get_next()  # 将头节点指向当前下一个节点
        else:
            previous.set_next(current.get_next())  # 将前序节点指向当前下一个节点

你可能感兴趣的:(数据结构与算法,windows,python,开发语言)