数据结构与算法Python版 有序表的链表实现


一、有序表

有序表Ordered List

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

  • 越“小”的数据项越靠“前“,数据项不仅适用于整数,还适用于所有定义了__gt__方法(即’>'操作符)的Python数据类型或对象。
    在这里插入图片描述

抽象数据类型:有序表

方法名描述备注
OrderedList()创建一个空的有序表
add(item)在表中添加一个数据项,并保持整体顺序,此项原不存在
remove(item)从有序表中移除一个数据项,此项应存在,有序表被修改(删除成功返回True,若item不存在返回False)
search(item)在有序表中查找数据项,返回是否存在返回值为布尔类型
isEmpty()是否空表返回值为布尔类型
size()返回表中数据项的个数返回值为整数
index(item)返回数据项在表中的位置,此项应存在返回值为整数。(若item不存在返回False)
pop()移除并返回有序表中最后一项,表中应至少存在一项移除并返回最后一项数据。(若表为空返回False)
pop(pos)移除并返回有序表中指定位置的数据项,此位置应存在(若原列表没有足够多的数据返回False)

二、采用链表实现有序表

算法描述

  • 节点Node的定义,与上一节无序表中所用链表相同,也设置一个head来保存链表表头的引用
  • 对于isEmpty/size/remove这些方法,与节点的次序无关 , 其实现与上一节无序表相同
  • search方法:利用链表节点有序排列的特性,一旦当前节点的数据项大于所要查找的数据项,则说明链表后面已经不可能再有要查找的数据项,可以直接返回False
  • add方法:必须保证加入的数据项添加在合适的位置。引入一个previous的引用,跟随当前节点current。一旦找到首个比新增数据大的数据项,利用previous进行插入

采用链表实现抽象数据类型有序表

#导入节点Node类,与上一节无序表使用的Node一样(略)


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

    def is_empty(self):
        return self.head == None

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

    def remove(self, item):
        # 表为空
        if self.is_empty():
            return False

        previous: Node = None
        current = self.head
        while current != None:
            if current.get_data() == item:
                if previous == None:  # 第1个数据项即为要删除的数据项
                    self.head = current.get_next()
                else:
                    previous.set_next(current.get_next())
                return True
            previous = current
            current = current.get_next()

        return False

    def add(self, item):
        # 表为空
        if self.is_empty():
            temp = Node(item)
            self.head = temp
            return

        previous: Node = None
        current = self.head
        while current != None:
            if item < current.get_data():  # 新数据项比当前项少
                temp = Node(item, current)
                if previous == None:  # 当前项为第1个
                    self.head = temp
                else:
                    previous.set_next(temp)
                return

            previous = current
            current = current.get_next()

        # 新数据项比表中所有数据项都大
        temp = Node(item)
        previous.set_next(temp)

    def index(self, item):
        # 从链表头head开始遍历到表尾,并计数,同时判断当前节点的数据项是否目标
        current = self.head
        count = 0
        while current != None:
            if current.get_data() == item:
                return count
            current = current.get_next()
            count += 1
        return False

    def search(self, item):
        current = self.head
        while current != None:
            if current.get_data() == item:
                return True
            if current.get_data() > item:  # 当前项(及后面的项)大于查找项,返回False
                return False
            current = current.get_next()

        return False  # 找不到返回False

    def pop(self, pos=None):
        # 空表
        if self.is_empty():
            return False

        # 位置pos不存在
        size = self.size()
        if pos != None and pos >= size:
            return False

        # 不指定pos时,将pos指向最后一项
        if pos == None:
            pos = size - 1

        previous: Node = None
        current = self.head
        for i in range(pos):  # 当前项指向pos位置
            previous = current
            current = current.get_next()
        if previous == None:  # 当前项指向位置0的情况
            data = current.get_data()
            self.head = current.get_next()
            return data
        else:
            data = current.get_data()
            previous.set_next(current.get_next())
            return data

    def get_items_str(self):
        # 返回表中数据项,按顺序排列成一行,以-->隔开
        result = "Head"
        current = self.head
        while current != None:
            result += " --> "
            result += str(current.get_data())
            current = current.get_next()
        return result

三、有序表测试

对上面定义的有序表数据类型进行测试,打印测试结果

ord_list = OrderedList()
for i in range(1, 10, 2):
    ord_list.add(i)

print(ord_list.is_empty())
print(f"此时表中内容:{ord_list.get_items_str()}\n")

ord_list.add(4)
print(ord_list.size())
print(f"此时表中内容:{ord_list.get_items_str()}\n")

print(ord_list.search(5))
ord_list.remove(5)
print(ord_list.search(5))
print(f"此时表中内容:{ord_list.get_items_str()}\n")

print(ord_list.index(7))
print(ord_list.index(88))
print(f"此时表中内容:{ord_list.get_items_str()}\n")

print(ord_list.pop())
print(f"此时表中内容:{ord_list.get_items_str()}\n")

print(ord_list.pop(1))
print(f"此时表中内容:{ord_list.get_items_str()}\n")

print(ord_list.pop(2))
print(f"此时表中内容:{ord_list.get_items_str()}\n")


### 输出结果
False
此时表中内容:Head --> 1 --> 3 --> 5 --> 7 --> 9      

6
此时表中内容:Head --> 1 --> 3 --> 4 --> 5 --> 7 --> 9

True
False
此时表中内容:Head --> 1 --> 3 --> 4 --> 7 --> 9      

3
False
此时表中内容:Head --> 1 --> 3 --> 4 --> 7 --> 9      

9
此时表中内容:Head --> 1 --> 3 --> 4 --> 7

3
此时表中内容:Head --> 1 --> 4 --> 7

7
此时表中内容:Head --> 1 --> 4

您正在阅读的是《数据结构与算法Python版》专栏!关注不迷路~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值