基本数据结构——线性结构(有序表)

1. 什么是有序表(OrderedList)

有序表是一种数据项依照其某可比性质(如整数大小、字母表先后)来决定在列表中的位置。越“小”的数据项越靠近列表的头,越靠“前”。
在这里插入图片描述

2.抽象数据类型有序表(OrderedList)定义的操作

在这里插入图片描述

3.有序表OrderedList实现

在实现有序表的时候,需要记住的是,数据项的相对位置,取决于它们之间的“大小”比较。以整数数据项为例,(17,26,31,54,77,93)的链表形式如下图所示。
在这里插入图片描述
有序表(OrderedList)同样采用链表方法实现,Node定义相同,OrderedList也设置了一个head来保存链表表头的引用。

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

对于isEmpty/size/remove这些方法,与节点的次序无关,所以其实现跟UnorderedList是一样的。search/add方法则需要由修改。

3.1 有序表实现:search方法

无序表的search中,如果需要查找的数据项不存在,则会搜遍整个链表,知道表尾。
对于有序表来说,可以利用链表节点有序排列的特性,来为search节省不存在数据项的查找时间。一旦当前节点的数据项大于索要查找的数据项,则说明链表后面已经不可能再有要查找的数据项,可以直接返回False。
例如要在下图查找数据项45
在这里插入图片描述

python代码实现

class OrderedList:
    def __init__(self):
        self.head=None
        
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

3.2 有序表实现:add方法

相比于无序表,改变最大的方法是add,因为ad方法必须保证加入的数据项添加在合适的位置,以维护整个链表的有序性。
例如,在(7,26,54,77,93)的有序表中,加入数据项31,我们需要沿着链表,找到第一个比31大的数据项54,将31插入到54的前面
在这里插入图片描述
由于涉及到的插入位置是当前节点之前,而链表无法得到“前驱”节点的引用,所以同remove方法类似,引入一个previous的引用,跟随当前节点current。

python代码实现

#定义节点
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#修改下一个节点的指向引用
#定义有序表
class OrderedList:
    def __init__(self):
        self.head=None
#有序表实现add方法
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)

4.链表实现的算法分析

对于链表复杂度的分析,主要是看响应的方法是否涉及到链表的遍历。、
对于一个包含节点数为n的链表:
isEmpty是O(1),因为仅需要检查head是否为None
size是O(n),因为除了遍历到队尾,没有其他办法得知节点的数量
search/remove以及有序表的add方法复杂度为O(n),因为涉及到链表的遍历,按照概率其平均操作的次数是n/2
无序表的add方法的复杂度为O(1),因为仅需要插入到表头
链表实现的list跟python内置的列表数据类型,在有些相同方法的实现上的时间复杂度不同。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章