【数据结构与算法Python版学习笔记】基本数据结构——列表 List,链表实现

无序表链表

定义

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

抽象数据类型无序列表 UnorderedList

方法

  • list() 创建一个新的空列表。它不需要参数,而返回一个空列表。

  • add(item) 将新项添加到列表,没有返回值。假设元素不在列表中。

  • remove(item) 从列表中删除元素。需要一个参数,并会修改列表。此处假设元素在列表中。

  • search(item) 搜索列表中的元素。需要一个参数,并返回一个布尔值。

  • isEmpty() 判断列表是否为空。不需要参数,并返回一个布尔值。

  • size() 返回列表的元素数。不需要参数,并返回一个整数。

  • append(item) 在列表末端添加一个新的元素。它需要一个参数,没有返回值。假设该项目不在列表中。

  • index(item) 返回元素在列表中的位置。它需要一个参数,并返回位置索引值。此处假设该元素原本在列表中。

  • insert(pos,item) 在指定的位置添加一个新元素。它需要两个参数,没有返回值。假设该元素在列表中并不存在,并且列表有足够的长度满足参数提供的索引需要。

  • pop() 从列表末端移除一个元素并返回它。它不需要参数,返回一个元素。假设列表至少有一个元素。

  • pop(pos) 从指定的位置移除列表元素并返回它。它需要一个位置参数,并返回一个元素。假设该元素在列表中。

实现

image

  • 为了实现无序表数据结构,可以采用链接表的方案
  • 虽然列表数据结构要求保持数据项的前后相对位置,但这种前后位置的保持,并不要求数据项依次存放在连续的存储空间
  • 数据存放位置没有规则,但如果在数据项之间建立链向指向,就可以保持其前后相对位置
    第一个和最后一个数据项需要显示标记出来
  • 基本元素是节点Node
    • 每个节点至少包含2个信息:
      • 数据项本身
      • 指向下一个节点的引用信息,next为None代表没有下一个节点
  • 可以采用链接节点的方式构建数据集来实现无序表
  • 链表的第一个和最后一个节点最重要
    必须冲第一个节点head开始沿着链接遍历下去
class Node:
    def __init__(self, initdata):
        self.data = initdata
        self.next = None

    def getData(self):
        return self.data

    def getNext(self):
        return self.next

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

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

if __name__ == "__main__":
    temp = Node(93)
    print(temp.getData())
class UnorderedList:
    def __init__(self):
        self.head = None

    def isEmpty(self):
        return self.head == None

    def add(self, item):
        temp = Node(item)
        temp.setNext(self.head)
        self.head = temp

    def size(self):
        current = self.head
        count = 0
        while current != None:
            count += 1
            current = current.getNext()
        return count

    def search(self, item):
        current = self.head
        found = False
        while current != None and not found:
            if current.getData() == item:
                found = True
            else:
                current = current.getNext()
        return found

    def remove(self, item):
        current = self.head
        previous = None
        found = False
        while not found:
            if current.getData() == item:
                found = True
            else:
                previous = current
                current = current.getNext()

        if previous == None:
            self.head = current.getNext()
        else:
            previous.setNext(current.getNext())

有序表

定义

  • 有序表是一种数据项依据其某种可比性质(如整数大小,字母表先后)来决定在列表中的位置
  • 越“小”的数据项越靠近列表的头,越靠“前”

抽象数据类型:有序列表

操作

  • OrderedList():创建一个新的空有序列表。它返回一个空有序列表并且不需要传递任何参数。

  • add(item):在保持原有顺序的情况下向列表中添加一个新的元素,新的元素作为参数传递进函数而函数无返回值。假设列表中原先并不存在这个元素。

  • remove(item):从列表中删除某个元素。欲删除的元素作为参数,并且会修改原列表。假设原列表中存在欲删除的元素。

  • search(item):在列表中搜索某个元素,被搜索元素作为参数,返回一个布尔值。

  • isEmpty():测试列表是否为空,不需要输入参数并且其返回一个布尔值。

  • size():返回列表中元素的数量。不需要参数,返回一个整数。

  • index(item):返回元素在列表中的位置。需要被搜索的元素作为参数输入,返回此元素的索引值。假设这个元素在列表中。

  • pop():删除并返回列表中的最后一项。不需要参数,返回删除的元素。假设列表中至少有一个元素。

  • pop(pos):删除并返回索引 pos 指定项。需要被删除元素的索引值作为参数,并且返回这个元素。假设该元素在列表中。

实现

  • 采用链表方法实现
  • Node定义相同
  • OrderedList也设置一个head来保存链表表头的引用
  • search方法
    • 无序表中,如果需要查找的数据项不存在,则会搜遍整个链表,直到表尾
    • 对于有序表,可以利用链表节点有序排列的特性,来为search节省不存在数据项的查找时间
  • add方法
    • 必须保证加入数据添加在合适的位置,以维护整个链表的有序性
    • 要和remove方法类似,引用一个previous的引用,跟随当前节点current
class Node:
    def __init__(self, initdata):
        self.data = initdata
        self.next = None

    def getData(self):
        return self.data

    def getNext(self):
        return self.next

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

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

if __name__ == "__main__":
    temp = Node(93)
    print(temp.getData())
def OrderedList:
    def __init__(self):
        self.head = None

    def isEmpty(self):
        return self.head == None

    def add(self, item):
        current = self.head
        previous = None
        stop= False
        while current != None and  not stop:
            if current.getData()>item:
                stop=True
            else:
                previous=current
                current=current.getNext()

        temp=Node(item)
        if previous==None:
            temp.setNext(self.head)
            self.head=temp
        else:
            temp.setNext(current)
            previous.setNext(temp)

    def size(self):
        current = self.head
        count = 0
        while current != None:
            count += 1
            current = current.getNext()
        return count

    def search(self, item):
        current = self.head
        found = False
        stop= False
        while current != None and not found and not stop:
            if current.getData() == item:
                found = True
            else:
                if current.getData()>item:
                    stop=True
                else:
                    current = current.getNext()
        return found

    def remove(self, item):
        current = self.head
        previous = None
        found = False
        while not found:
            if current.getData() == item:
                found = True
            else:
                previous = current
                current = current.getNext()

        if previous == None:
            self.head = current.getNext()
        else:
            previous.setNext(current.getNext())

链表实现的算法分析

  • 对于链表复杂度的分析,主要看方法是否涉及到链表的遍历
    • isEmpty O(1)
    • size O(n)
    • search/remove O(n)
    • 有序表 add O(n)
    • 无序表 add O(1)
  • 链表实现的List,跟python内置的列表数据类型,在有些相同方法的实现上的时间复杂度不同。
    原因在于python内置的列表数据类型是基于顺序存储来实现的,并进行了优化
posted @ 2021-04-22 13:21  砥才人  阅读(228)  评论(0编辑  收藏  举报