Python 数据结构与算法 5 有序表

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

node的定义如上一讲一样

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

ADT OList

  • Olist():创建一个空的有序表
  • add(item):在表中添加一个数据项,并保持整体顺序,此项原不存在
  • remove(item):从有序表中移除一个数据项,此项应存在,有序表被修改
  • search(item):在有序表中查找数据项,返回是否存在
  • isEmpty():是否空表
  • size():返回表中数据项的个数
  • index(item):返回数据项在表中的位置,此项应存在
  • pop():移除并返回有序表中最后一项,表中应至少存在一项
  • pop(pos):移除并返回有序表中指定位置的数据项,此位置应存在
    在实现有序表的时候,需要记住的是,数据项的相对位置,取决于它们之间的:"大小"比较
    如下图
    在这里插入图片描述

有序表Olist实现

  • 同样采用链表方式实现
  • Node定义相同
  • Olist也设置一个head来保存链表表头
class Olist:
    def __init__(self):
        self.head = None
  • 其中isEmpty/size/remove这些方法,与节点的次序无关,所以其实现跟Ulist是一样的.
    def isEmpty(self):
        return self.head == None
    def size(self):
        current = self.head
        count = 0

        while current != None:
            count = count+1
            current = current.getNext()
        return count
    def remove(self,item):
        current = self.head
        previous = None
        found = False
        while current != None and 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())
  • search方法实现
    在无序表的search中,如果需要查找的数据项不存在,则会搜遍整个链表,知道表尾
    但是对于有序表来说,可以利用链表节点有序排列的特性,来为search节省不存在数据项的查询时间

    一旦当前节点的数据项大于所要查找的数据项,则说明链表后面已经不可能再有要查找的数据项,可以直接返回False
    如:我们如果想要在下面的表查找45
    在这里插入图片描述
       def search(self,item):
        current = self.head
        found = False

        while current != None:
            if current.getData() ==item:
                found = True
                break
            else:
                if current.getData()>item:
                    break
                else:
                    current = current.getNext()
        return found
  • add方法
    相比无序表,改变最大的方法是add,因为add方法必须保证加入的数据项添加在合适的位置,以维护整个链表的有序性
    比如在(17,26,54,77,93)的有序表中,加入数据项31,我们需要沿着链表,找到第一个比31大的数据项54,将31插入到54的前面
    在这里插入图片描述
    由于涉及到的插入位置是当前节点之前,而链表无法得到"前驱"节点的引用,所以要跟remove方法类似,引入一个previous的引用,跟随当前节点current
    ,一旦找到首个比31大的数据项,previous就派上用场了
    def add(self,item):
        current = self.head
        previous = None
        N = Node(item)

        while current != None:
            if current.getData() > item:
                found = True
                break
            else:
                previous = current
                current = current.getNext()
        if previous == None:
            N.setNext(self.head)
            self.head = N
        else:
            N.setNext(current)
            previous.setNext(N)

综上:

class Olist:
    def __init__(self):
        self.head = None

    def isEmpty(self):
        return self.head == None
    def size(self):
        current = self.head
        count = 0

        while current != None:
            count = count+1
            current = current.getNext()
        return count
    def remove(self,item):
        current = self.head
        previous = None
        found = False
        while current != None and 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())
    def search(self,item):
        current = self.head
        found = False

        while current != None:
            if current.getData() ==item:
                found = True
                break
            else:
                if current.getData()>item:
                    break
                else:
                    current = current.getNext()
        return found
    def add(self,item):
        current = self.head
        previous = None
        N = Node(item)

        while current != None:
            if current.getData() > item:
                found = True
                break
            else:
                previous = current
                current = current.getNext()
        if previous == None:
            N.setNext(self.head)
            self.head = N
        else:
            N.setNext(current)
            previous.setNext(N)

u=Olist()
u.add(45)
u.add(48)
u.add(86)
u.remove(48)
print(u.search(45))
print(u.search(86))
print(u.size())

线性结构小结

  • 线性数据结构Linear DS将数据项以某种线性的次序组织起来

  • 栈Stack维持了数据项的后进先出LIFO的次序
    Stack的基本操作包括push,pop,isEmpty

  • 队列Queue维持了数据项先进先出FIFO的次序
    Queue的基本操作包括enqueue,dequeue,isEmpty

  • 双端队列Deque可以同时具备栈和队列的功能
    deque的主要操作包括addFront,addRear,removeFront,removeRear,isEmpty

  • 列表list是数据项能够维持相对位置的数据集

  • 链表的实现,可以保持列表维持相对位置的特点,而不需要连续的存储空间

  • 链表实现时,其各种方法,对链表头部head需要特别的处理

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值