数据结构15: 有序表抽象数据类型

57 篇文章 12 订阅
47 篇文章 12 订阅

目录

 

一、什么是有序表orderedlist ?

二、orderedlist定义的操作

1、search方法

2、add方法

3、所有代码

四、链表实现的算法分析


一、什么是有序表orderedlist ?

有序表是一种数据项依照某种可比性质(如整数大小、字母表先后)来决定在列表中的位置

越小的数据项越靠近列表的头,越靠前

二、orderedlist定义的操作

有序表数据定义的操作如下:

List(): 创建一个空的有序表
add(item): 添加一个数据项到列表中,并保持整体的顺序,假设item原先不存在与列表中
remove(item): 从列表中移除item,这时列表被修改,item原先应该存在于列表中
search(item): 在列表中查找item,返回的是bool类型值
isEmpty(): 返回列表是否为空
size(): 返回列表包含了多少数据项
index(item): 返回数据项在列表中的位置,此项应该存在
pop(): 从列表末尾移除数据项,假设原列表至少一个数据项
pop(pos): 移除位置pos的数据项

三、有序表OrderedList的实现

在实现有序表的时候需要记住的是,数据项的相对位置,取决于他们之间的大小比较

以整数数据项为例,(17,26, 31, 54, 77, 93)的链表形式如图:

我们同样采用链表的形式实现,首先也是设置一个head来保存链表表头的引用。

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

对于isEmpty/size/remove这些方法,与节点的次序无关,所以它们的实现跟underedlist是一样的。但是search和add方法需要修改。

1、search方法

在无序表的search中,如果要查找的数据项不存在,则需要遍历整个链表,直到表尾。

但是对于有序表来说,可以利用链表节点有序排列的特性,来为search节省不存在数据项的查找时间。当数据项不存在时,可以节省时间。

怎么做到的呢?就是一旦当前节点的数据项大于所要查找的数据项,则说明链表后面已经不可能再有要查找的数据项,可以直接返回False。

如下图中要查找数据项45:

代码实现:

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

2、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
        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 is None:        # 第一个节点就比要插入的数据大
            temp.setNext(self.head)
            self.head = temp
        else:
            temp.setNext(current)   # 和下一行不能反了
            previous.setNext(temp)

3、所有代码

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

    def getData(self):
        return self.data  # 返回的数据项

    def getNext(self):
        return self.next  # 返回next

    def setData(self, newdata):
        self.data = newdata  # 设置新的数据项

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


class Orderedlist:
    def __init__(self):
        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 is 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:
            print(current.getData())
            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:       # current是首个节点的情况
            self.head = current.getNext()
        else:
            previous.setNext(current.getNext())

四、链表实现的算法分析

对于链表算法复杂度的分析,主要看相应的方法是否涉及到链表的遍历

当链表包含的节点数为n时:

  • isEmpty是O(1),因为仅需要检查head是否为None
  • size是O(n),因为必须遍历到表尾
  • search/remove以及有序表的add方法,则是O(n),因为涉及到表的遍历,按照概率其平均操作的次数是n/2
  • 无序表的add方法是O(1),因为仅需要插入到表头。

链表实现的List,跟python内置的列表数据类型,在有些方法的实现上时间复杂度不同,主要是因为python内置的列表数据类型是基于顺序存储来实现的,并进行了优化。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值