线性表——数据结构与算法 总结2

1. 顺序表(Sequential List)

逻辑相邻,物理相邻:存储空间紧凑,不必为节点间的逻辑关系而增加额外的存储开销。

所有元素存放在一片地址连续的存储单元中,需要开辟连续存储空间,造成存储空间“碎片”。

插入、删除操作需要移动表中约一半的元素,当n较大时,顺序表的效率低。

 按位查找:顺序表的时间为O(1),是随机存取

插入和删除:顺序表需移动表长约一半的元素,时间为O(n) 

顺序表的存储密度为1,而链表的存储密度小于1。仅从存储密度看,顺序表的存储空间利用率高。

但顺序表需要预先分配初始空间,所有数据占用一整片地址连续的内存空间。

以下代码是顺序表的基本操作:

class SequentialList(Object):

    def __init__(self, size = 50):  # 初始化线性表,定义线性表的最大长度为50
        self.max = size
        self.data = [None]*self.max
        self.num = 0  # 表中元素的个数

    def is_empty(self):  # 判断线性表是否为空
        return self.num is 0

    def is_full(self):  # 判断线性表是否为满
        return self.num is self.max

    def length(self):  # 返回线性表中元素的个数
        return self.num

    def append(self.value):  # 在表尾插入一个元素
        if self.num > self.max:
            print("List is full.")
        else:
            self.data[self.num] = value
            self.num += 1

    def prepend(self.value):  # 在表头位置插入一个元素
        if self.num >= self.max:
            print("List is full")
        else:
            for i in range(self.num, 0, -1):
                self.data[i] = self.data[i-1]  # 每个元素往后移一位
            self.data[0] = value
            self.num += 1

    def reverse(self):  # 逆转顺序表的顺序
        i = 0
        number = self.num-1
        while i <= number:
            self.prepend(self.data.pop(i))
            i += 1
        return self.data
    

2. 链表(Linked List)

数据元素存放在任意的存储单元中,这组存储单元可以是连续的,也可以是不连续的。

通过指针域来反映数据元素的逻辑关系。

链表是一种物理存储单元上非连续、非顺序的存储结构。

数据元素的逻辑顺序是通过链表中的指针链接次序实现的。

按位查找:链表的时间为O(n),是顺序存取。

插入和删除:链表不需要移动元素,在给出某个合适位置的指针后,插入和删除所需时间为O(1)

(1)单链表

每个结点只设置一个指向其后继结点的指针成员,这样的链表简称单链表。

基本操作:

1)插入和删除结点操作

2)整体建立单链表(头插法和尾插法)

头插法:

尾插法:

以下代码是线性表的基本操作:

class SingleNode:  # 单链表的节点
    def __init__(self, elem = None):
        self.elem = elem  # 存放数据
        self.next = None  # 下一个节点的链接

class SingleLinkList:
    def __init__(self):
        self.head = SingleNode()
        self.head.next = None

    def is_empty(self):  # 判断单链表是否为空
        return self.head.next == None

    def length(self):  # 获取链表长度
        p = self.head
        count = 0
        while p != None:
            count += 1
            p = p.next
        return count

    def traverse(self):  # 遍历链表
        p = self.head.next
        while p != None:
            print(p.elem, end=' ')
            p = p.next
        print('\n')

    def prepend(self, elem):  # 链表头添加元素
        node = SingleNode(elem)
        node.next = self.head.next
        self.head.next = node

    def append(self, elem):  # 链表尾部添加元素
        p = self.head
        s = SingleNode(elem)
        while p.next != None:
            p = p.next
        p.next = s

    def locate_item(self, elem):  # 找某个元素的下标
        index = 0
        p = self.head.next
        while p != None:
            if p.elem == elem:
                return index
            index += 1
            p = p.next
    
    def reverse(self):  # 逆转链表
        p = self.head.next
        self.head.next = None
        while p != None:
            temp = p.next
            p.next = self.head.next
            self.head.next = p
            p = temp

        lst = []
        cur = self.head.next
        while cur != None:
            lst.append(cur.elem)
            cur = cur.next
        return lst

(2)双链表

如果每个结点中设置两个指针成员,分别用以指向其前驱结点和后继结点,这样的链表简称双链表。

基本操作:与单链表类似,设计结点插入和删除的操作改为双链表方式即可。

1. 插入和删除结点操作

插入结点操作:将结点s插入到双链表中p结点的后面

删除结点操作:删除双链表中的p结点

2. 整体建立双链表

头插法和尾插法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值