python数据结构:列表

1.什么是列表

❖在前面基本数据结构中,采用PythonList来实现了多种线性数据结构
❖列表List是一种简单强大的数据集结构,提供了丰富的操作接口
但并不是所有的编程语言都提供了List数据类型,有时候需要程序员自己实现。
❖列表是一种数据项按照相对位置存放的数据集
特别的,被称为“无序表unordered list”
其中数据项只按照存放位置来索引,如第1个、第2个……、最后一个等。(为了简单起见,假设表中不存在重复数据项)
❖如一个考试分数的集合“54,26,93,17,77和31”
❖如果用无序表来表示,就是[54,26,93,17,77,31]

2.抽象数据类型:无序表List

2.1无序表List的操作如下:

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的数据项,假设原列表存在位置pos

3.采用链表实现无序表

为了实现无序表数据结构,可以采用链接表的方案。
❖虽然列表数据结构要求保持数据项的前后相对位置,
但这种前后位置的保持,
并不要求数据项依次存放在连续的存储空间

❖如下图,数据项存放位置并没有规则,
但如果在数据项之间建立链接指向,就可以保持其前后相对位置
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0w3SLlur-1584152535777)(attachment:image.png)]

3.1 链表实现:节点Node

❖链表实现的最基本元素是节点Node
每个节点至少要包含2个信息:数据项本身,以及指向下一个节点的引用信息
注意next为None的意义是没有下一个节点了,这个很重要
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9SDOyuDJ-1584152535779)(attachment:image.png)]

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
temp=Node()
temp._init_(93)
print(temp.getData())
print(temp.getNext())
93
None

3.2 链表实现: 无序表UnorderedList

可以采用链接节点的方式构建数据集来实现无序表
❖链表的第一个和最后一个节点最重要
如果想访问到链表中的所有节点,就必须从第一个节点开始沿着链接遍历下去
❖所以无序表必须要有对第一个节点的引用信息
❖设立一个属性head,保存对第一个节点的引用空表的head为None

class UnorderList:
    def __init__(self):
        self.head=None
mylist=UnorderList()
print(mylist.head)
None

随着数据项的加入,无序表的head始终指向链条中的第一个节点
❖注意!无序表mylist对象本身并不包含数据项(数据项在节点中)
其中包含的head只是对首个节点Node的引用
判断空表的isEmpty()很容易实现
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-v694jJcy-1584152535780)(attachment:image.png)]

❖接下来,考虑如何实现向无序表中添加数据项,实现add方法。
❖由于无序表并没有限定数据项之间的顺序
❖新数据项可以加入到原表的任何位置
❖按照实现的性能考虑,应添加到最容易加入的位置上。

❖由链表结构我们知道要访问到整条链上的所有数据项
❖都必须从表头head开始沿着next链接逐个向后查找
❖所以添加新数据项最快捷的位置是表头,整个链表的首位置。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tudZOhh8-1584152535782)(attachment:image.png)]

3.3 链表实现: add方法及实现

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ODIwoDE7-1584152535783)(attachment:1.png)]
❖链接次序很重要!链接次序很重要!链接次序很重要!
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-j42R9wFW-1584152535783)(attachment:2.png)]

3.4 链表实现: size

❖size:从链条头head开始遍历到表尾同时用变量累加经过的节点个数。
链式结构size的时间复杂度为O(n),顺序结构为O(1)。现在为链式

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

3.5 链表实现: search

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

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

3.6 链表实现: remove(item)方法

首先要找到item,这个过程跟search一样,但在删除节点时,需要特别的技巧
current指向的是当前匹配数据项的节点
而删除需要把前一个节点的next指向current的下一个节点
所以我们在search current的同时,还要维护前一个(previous)节点的引用
❖找到item之后,current指向item节点,previous指向前一个节点,开始执行删除,需要区分两种情况:
current是首个节点;或者是位于链条中间的节

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())
        
发布了51 篇原创文章 · 获赞 34 · 访问量 913

猜你喜欢

转载自blog.csdn.net/weixin_43412569/article/details/104855785
今日推荐