python线性表

顺序表

顺序表,将元素顺序地存放在一块连续的存储区里,元素间的顺序关系由它们的存储顺序自然表示。
在这里插入图片描述
数据元素本身连续存储,每个元素所占的存储单元大小固定相同,元素的下标是其逻辑地址,而元素存储的物理地址(实际内存地址)可以通过存储区的起始地址Loc (e0)加上逻辑地址(第i个元素)与存储单元大小(c)的乘积计算而得,即:Loc(ei) = Loc(e0) + c*i,时间复杂度为O(1)。
如果元素的大小不统一,则须采用图b的元素外置的形式,将实际数据元素另行存储,而顺序表中各单元位置保存对应元素的地址信息(即链接)
顺序表完整信息=元素集合+整体情况信息【元素个数+容量】
顺序表的两种实现方式:
在这里插入图片描述
一体式:完整信息在一个表中
分离式:表中只存整体情况信息,外链实际元素集合;动态顺序表:容量可以在使用中动态变化
顺序表的操作:增加和删除,各分为尾部O(1)、非保序O(1)、保序O(n)
python中list和tuple,更多是用list,分离式技术实现的动态顺序表
ist实现采用了如下的策略:在建立空表(或者很小的表)时,系统分配一块能容纳8个元素的存储区;在执行插入操作(insert或append)时,如果元素存储区满就换一块4倍大的存储区。但如果此时的表已经很大(目前的阀值为50000),则改变策略,采用加一倍的方法。引入这种改变策略的方式,是为了避免出现过多空闲的存储位置。
单向链表

创建一个链表中的节点类(item,next)
class Node():
    def __init__(self,item):#节点初始条件有值
        self.item=item
        self.next=None

#创建链表的类
class SingleLink():
    #初始化,给定链表的头部属性
    def  __init__(self,node=None):
        self.__head=node
    #判断链表是否为空,即判断链表的head指针是否指向空
    def is_empty(self):
        return self.__head==None #为None返回True,不为None,False


    #判断链表的长度
    def length(self):
        if self.is_empty():
            return 0
        else:
            currentnode=self.__head #代表currentnode指向当前节点的游标与head指针指向同一个节点
            lengthcount=1#对比注释部分另一个方法,lengthcount=0
            while currentnode.next!=None:
                lengthcount+=1
                currentnode=currentnode.next
            return lengthcount


    #遍历整个链表
    def travel(self):
        if self.is_empty():
            return None
        else:
            allitemlist = []
            currentnode = self.__head
            allitemlist.append(currentnode.item)#先加入第一个
            while currentnode.next != None:
                currentnode = currentnode.next#尽管最后一个currentnode.next==None,但已经加入过
                allitemlist.append(currentnode.item)
            return allitemlist


    #链表头部加入元素
    def add(self,newitem):
        newnode = Node(newitem)
        if self.is_empty():
            self.__head = newnode
        else:
            newnode.next = self.__head
            self.__head = newnode




    #尾部添加元素,需要判断是否为空
    def append(self,newitem):
        newnode=Node(newitem)
        if self.is_empty():#类之间的函数调用用self.func
            self.__head = newnode
        else:
            currentnode=self.__head
            while currentnode.next!=None:
                currentnode=currentnode.next
            currentnode.next = newnode




    #指定位置添加元素,根据位置分为头部添加,尾部添加,中间位置添加,中间位置添加时需找到添加位置的前一个节点
    def insert(self,position,newitem):
        if position <=0:
            self.add(newitem)
        elif position >= self.length():#大于等于链表长度
            self.append(newitem)
        else:
            currentnode=self.__head
            positioncount=0
            newnode=Node(newitem)
            while positioncount<(position-1):#currentnode为插入位置前一个的节点
                currentnode=currentnode.next
                positioncount+=1
            newnode.next=currentnode.next
            currentnode.next=newnode





    #删除节点,再循环条件内查找
    def remove(self,item):
        currentnode = self.__head
        prenode = None
        while currentnode!=None:  # 判断是否找到
            if currentnode.item == item:  # 找到删除的值对应的节点
                if prenode == None:  # 如果前一个节点为空,则当前节点为第一个节点
                    self.__head = currentnode.next
                else:
                    prenode.next = currentnode.next
                break#注意break
            else:
                prenode = currentnode  # 将当前节点给前一个节点
                currentnode = currentnode.next  # 当前节点为其next的指向
        # 如果找到,判断curentnode是否为第一个节点


    #查找节点
    def search(self,item):
        currentnode=self.__head
        Found=False
        while not Found and currentnode!=None:#此处是currentnode,最后一个值也可找
            if currentnode.item==item:
                 Found=True
            else:
                currentnode=currentnode.next
        return Found






    #更新链表某个位置的值
    def update(self,position,newitem):
        if (position<0) or (position>self.length()):
            return False
        else:
            currentnode=self.__head
            positioncount=0
            while positioncount<position:
                currentnode=currentnode.next

                positioncount+=1
            currentnode.item=newitem




    #清空链表
    def clear(self):
        self.__head=None

单向循环链表

class Node():
    def __init__(self, item):
        self.item=item
        self.next=None

class SingleCircleLink():
    def __init__(self,node=None):
        self.__head=node


    #判断链表是否为空
    def is_empty(self):
        if self.__head==None:
            return True


    #返回链表的长度
    def length(self):
        if self.is_empty():#判断是否为空
            return 0
        else:
            currentnode=self.__head
            lengthcount=1
            while currentnode.next!=self.__head:
                lengthcount+=1
                currentnode=currentnode.next
        return lengthcount

    #遍历整个链表
    def travel(self):
        if self.is_empty():
            return None
        else:
            allitemlist = []
            currentnode=self.__head
            allitemlist.append(currentnode.item)
            while currentnode.next!=self.__head:
                currentnode=currentnode.next
                allitemlist.append(currentnode.item)
            return allitemlist

    #在头部添加一个节点
    def add(self,newitem):
        newnode=Node(newitem)
        if self.is_empty():
            self.__head=newnode
            newnode.next=self.__head#此句是将新插入节点的next指向头部,实现单向循环
        else:
            currentnode=self.__head#currentnode用来找尾节点
            while currentnode.next!=self.__head:
                currentnode=currentnode.next
            newnode.next=self.__head
            currentnode.next=newnode#将尾部节点的next连接到newnode
            self.__head=newnode#将head指针给newnode


    #在尾部添加一个节点
    def append(self,newitem):
        newnode=Node(newitem)
        if self.is_empty():
            self.__head = newnode
            newnode.next = self.__head#此句是将新插入节点的next指向头部,实现单向循环
        else:
            currentnode = self.__head  # currentnode用来找尾节点
            while currentnode.next != self.__head:
                currentnode = currentnode.next
            currentnode.next=newnode
            newnode.next=self.__head



    #在任意位置添加一个节点
    def insert(self,position,newitem):
        newnode=Node(newitem)
        if position <=0:
            self.add(newitem)
        elif position >= self.length()-1:
            self.append(newitem)
        else:
            currentnode=self.__head
            positioncount=0
            while positioncount<(position-1):#注意此时的currrentnode指向的插入位置的前一个节点
                currentnode=currentnode.next
                positioncount+=1
            newnode.next=currentnode.next
            currentnode.next=newnode


    #删除一个节点
    def remove(self,item):
        if self.is_empty():
            return 0
        else:
            currentnode=self.__head
            prenode=None
            while  currentnode.next!=self.__head:#因为循环为currentnode.next,所以需单独考虑最后一个节点的匹配情况,如110所示
                if currentnode.item==item:
                    if prenode == None:  # 删除的是第一个节点
                        searchnode = self.__head
                        self.__head = currentnode.next
                        while searchnode.next != self.__head:
                            searchnode = searchnode.next
                        searchnode.next = self.__head  # 替换最后一个节点的__head值
                    else:
                        prenode.next = currentnode.next  # 还没到最后一个节点
                    break
                else:
                    prenode=currentnode
                    currentnode=currentnode.next
            if currentnode.item==item:#考虑最后一个节点
                if currentnode==self.__head:#如果最后一个节点是头节点,则链表为空
                    self.__head=None
                else:
                    prenode.next=self.__head#其他更改前一个prenode.next指向head


    #查找一个节点
    def search(self,item):
        if self.is_empty():
            return False
        else:
            currentnode=self.__head
            if currentnode.item == item:#放在外面,相当于currentnode.next=self.__head也进行了判断,避免了最后一个元素无法判断
                return True
            else:
                while currentnode.next!=self.__head:
                    currentnode=currentnode.next
                    if currentnode.item==item:
                        return True
            return False



    #更新链表某个位置的值,索引从0开始
    def update(self,position,newitem):
        if (position<0) or (position>self.length()):
            return False
        else:
            currentnode=self.__head
            positioncount=0
            while positioncount<position:
                currentnode=currentnode.next
                # currentnode=currentnode.getnext()
                positioncount+=1
            currentnode.item=newitem

双向链表 pre\next

class Node():
    def __init__(self,item):
        self.item=item
        self.next=None
        self.pre= None


class DoubleLink():
    def __init__(self,node=None): #可以先构造一个node=Node(100)
        self.__head=node


    #判断是否为空
    def is_empty(self):
        return self.__head==None

   #判断长度
    def length(self):
        if self.is_empty():
            return 0
        else:
            currentnode=self.__head
            lengthcount=1#注意此处为1,为0时不需要判断为空的情况
            while currentnode.next!=None:
                lengthcount+=1
                currentnode=currentnode.next
            return lengthcount

    #遍历链表
    def travel(self):
        if self.is_empty():
            return None
        else:
            allitemlist=[]
            currentnode=self.__head
            allitemlist.append(currentnode.item)
            while currentnode.next!=None:
                currentnode=currentnode.next
                allitemlist.append(currentnode.item)
            return allitemlist

    #头部添加
    def add(self,newitem):
         newnode=Node(newitem)
         self.__head.pre=newnode
         newnode.next = self.__head
         self.__head = newnode
         # newnode.next.pre = newnode  # 此为双向链表增加的,新增节点的next指向的节点的pre为新增的节点


    #尾部添加
    def append(self,newitem):
        newnode=Node(newitem)
        if self.is_empty():
            self.__head=newnode

            # newnode.pre=None 等于None不需要改变就为默认
            # newnode.next=None
        else:
            currentnode=self.__head
            while currentnode.next!=None:
                currentnode=currentnode.next
            currentnode.next=newnode
            newnode.pre=currentnode#新增的
            # newnode.next=None 等于None不需要改变就为默认


    #任意位置添加
    def insert(self,position,newitem):
        if position <=0:
            self.add(newitem)
        elif position >= self.length():
            self.append(newitem)
        else:
            positioncount=0
            newnode=Node(newitem)
            currentnode=self.__head
            while positioncount <(position-1):#要插入位置的前一个
                currentnode=currentnode.next
                positioncount+=1
            #在currentnode后插入
            newnode.next = currentnode.next
            newnode.pre=currentnode
            currentnode.next.pre=newnode
            currentnode.next = newnode


    #删除某一元素
    def remove(self,item):
        currentnode=self.__head
        Found=False
        while  currentnode!=None:
            if currentnode.item==item:
                if currentnode.pre == None:  # 若果删除的是第一个
                    self.__head = currentnode.next
                elif currentnode.next == None:  # 如果删除的是最后一个
                    currentnode.pre.next = currentnode.next
                else:  # 如果是中间,因为此处有pre属性,所以相比之前,后两种不能合并
                    currentnode.pre.next = currentnode.next
                    currentnode.next.pre = currentnode.pre
                break
            else:
                currentnode=currentnode.next



    #查找某一个元素
    def search(self,item):
        currentnode=self.__head
        Found=False
        while not Found and currentnode!=None:
            if currentnode.item==item:
                Found= True
            else:
                currentnode=currentnode.next

  • 7
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值