当前位置:   article > 正文

Python数据结构02-顺序表、链表_python-顺序结构-02

python-顺序结构-02

顺序表

顺序表的表中元素存储方式
在这里插入图片描述

顺序表完整信息包含两部分
1. 表中的元素集合
2. 有关表的整体情况的信息

顺序表两种实现方式
在这里插入图片描述

  1. 图a为一体式结构:表信息和元素存储区在内存连续存放。结构整体性强,易于管理,但元素存储区在创建顺序表后固定。
  2. 图b为分离式结构:表对象只有整个表有关的信息,元素存储区通过链接与基本表对象关联。
  3. 元素存储区替换时:一体式结构更换数据区需要整个表改变。分离式则只需改变数据区指针
  4. 元素存储区扩充时:分离式可以不改变表对象前提下扩充数据区(这种实现方式称为动态顺序表)
    扩充的两种策略:
    • 每次扩充增加固定数目的存储位置(线性增长)。特点:节省空间,若扩充操作频繁,则操作次数多。
    • 每次扩充容量加倍。特点:减少扩充操作次数,以空间换时间,推荐

顺序表操作复杂度
增加元素
a. 尾端加入元素,时间复杂度为O(1)
b. 非保序的加入元素(元素加入目标位置,目标位置所在元素移至表尾),时间复杂度为O(1)
c. 保序的元素加入,时间复杂度为O(n)

删除元素
a. 删除表尾元素,时间复杂度为O(1)
b. 非保序的元素删除(不常见,类似增加元素b),时间复杂度为O(1)
c. 保序的元素删除,时间复杂度为O(n)

Python中的顺序表

listtuple两种类型采用顺序表的实现

list的基本实现

list就是一种采用分离式技术实现的动态顺序表
Python的官方实现:
1. list建立空表(或者很小的表),系统分配一块能容纳8个元素的存储区;
2. 元素存储区满则一块4倍大的存储区。碰到阈值(阀值为50000)则改为加一倍的方法(避免太多空闲区)

链表

单链表操作

is_empty() 链表是否为空
length() 链表长度
travel() 遍历整个链表
add(item) 链表头部添加元素
append(item) 链表尾部添加元素
insert(pos, item) 指定位置添加元素
remove(item) 删除节点
search(item) 查找节点是否存在

单链表实现

class SingleNode(object):
    """单链表的结点"""

    def __init__(self, item):
        # _item存放数据元素
        self.item = item
        # _next是下一个节点的标识
        self.next = None
class SingleLinkList(object):
    "单链表"

    def __init__(self):
        self._head = None
    def is_empty(self):
        "判断链表是否为空"
        return self._head == None
    def length(self):
        "链表长度"
        p = self._head
        count = 0
        while p!=None:
            count+=1
            p = p.next
        return count
    def travel(self):
        "遍历链表,以列表形式返回所有值"
        p = self._head
        items = []
        while p!=None:
            items.append(p.item)
            p = p.next

        return items
    def add(self,item):
        "头插法插入元素"
        node = SingleNode(item)
        node.next = self._head
        self._head = node
    def append(self,item):
        node = SingleNode(item)
        p = self._head
        if p != None:
            while p.next!=None:
                p = p.next
        else:
            print("error")
            return None
        p.next = node
    def insert(self,pos,item):
        """指定位置添加元素"""
        # 若指定位置pos为第一个元素之前,则执行头部插入
        if pos <= 0:
            self.add(item)
        # 若指定位置超过链表尾部,则执行尾部插入
        elif pos > (self.length() - 1):
            self.append(item)
        # 找到指定位置
        else:
            node = SingleNode(item)
            count = 0
            # pre用来指向指定位置pos的前一个位置pos-1,初始从头节点开始移动到指定位置
            pre = self._head
            while count < (pos - 1):
                count += 1
                pre = pre.next
            # 先将新节点node的next指向插入位置的节点
            node.next = pre.next
            # 将插入位置的前一个节点的next指向新节点
            pre.next = node

    def remove(self,item):
        """删除节点"""
        cur = self._head
        pre = None
        while cur != None:
            # 找到了指定元素
            if cur.item == item:
                # 如果第一个就是删除的节点
                if not pre:
                    # 将头指针指向头节点的后一个节点
                    self._head = cur.next
                else:
                    # 将删除位置前一个节点的next指向删除位置的后一个节点
                    pre.next = cur.next
                break
            else:
                # 继续按链表后移节点
                pre = cur
                cur = cur.next
    def search(self,item):
        p = self._head
        while p!=None:
            if p.item == item:
                return True
            p = p.next
        return False

if __name__ == "__main__":
    ll = SingleLinkList()
    ll.add(1)
    ll.add(2)
    ll.append(3)
    ll.insert(2, 4)
    print("length:",ll.length())
    print(ll.travel())
    print(ll.search(3))
    print (ll.search(5))
    ll.remove(1)
    print ("length:",ll.length())
    print(ll.travel())
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110

单向循环链表

操作
is_empty() 判断链表是否为空
length() 返回链表的长度
travel() 遍历
add(value) 在头部添加一个节点
append(value) 在尾部添加一个节点
insert(pos, value) 在指定位置pos添加节点
remove(item) 删除一个节点
search(item) 查找节点是否存在
实现
不带头结点
技巧:循环链表使用do while进行遍历比较方便

class SignleNode(object):
    def __init__(self,value):
        self._next = None
        self._value = value

class SingleCirleList(object):
    def __init__(self):
        self._head = None
        self._tail = None

    def is_empty(self):
        "判断是否为空"
        return self._head == None
    def length(self):
        "求表长"
        p = self._head
        count = 0
        while True:
            if p==None:
                break
            p = p._next
            count+=1
            if p == self._head:
                break
        return count
    def travel(self):
        "遍历循环单链表"
        p = self._head
        values = []
        if self.is_empty():
            return values
        while True:
            values.append(p._value)
            p = p._next
            if p == self._head:
                break
        return values
    def add(self,value):
        "在循环单链表头部插入节点"
        item = SignleNode(value)
        if self.is_empty():
            self._head = item
            self._tail = item
            item._next = self._head
        else:
            item._next = self._head
            self._head = item
            self._tail._next = item
    def append(self,value):
        "在循环单链表尾部插入节点"
        item = SignleNode(value)
        if self.is_empty():
            self._head = item
            self._tail = item
            item._next = self._head
        else:
            item._next = self._tail._next
            self._tail._next = item
            self._tail = item
    def insert(self,pos,value):
        "在指定位置pos添加节点"
        if pos<=0:
            self.add(value)
        elif pos >= self.length():
            self.append(value)
        else:
            p = self._head
            while True:
                pos -= 1
                p = p._next
                if p == self._head or pos == 0:
                    break
            item = SignleNode(value)
            item._next = p._next
            p._next = item
    def remove(self,item):
        "删除一个节点,没有则什么都不做"
        p = self._head
        pre = self._tail
        while True:
            if p._value == item:
                pre._next = p._next
                break
            pre = p
            p = p._next
            if p == self._head:#实现do while
                break
    def search(self,item):
        "查找节点是否存在"
        p = self._head
        while True:
            if p._value == item:
                return True
            p = p._next
            if p == self._head:
                break
        return False
if  __name__ == "__main__":
    ll = SingleCirleList()
    ll.add(1)
    ll.add(2)
    print(ll.travel())
    ll.append(4)
    ll.insert(1,5)
    print("length:",ll.length())
    print(ll.travel())
    print(ll.search(2))
    print(ll.search(6))
    ll.remove(1)
    print(ll.travel())
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110

双向链表

操作
is_empty() 链表是否为空
length() 链表长度
travel() 遍历链表
add(item) 链表头部添加
append(item) 链表尾部添加
insert(pos, item) 指定位置添加
remove(item) 删除节点
search(item) 查找节点是否存在
实现

class Node(object):
    """双向链表节点"""
    def __init__(self, item):
        self.item = item
        self.next = None
        self.prev = None
class DLinkList(object):
    """双向链表"""
    def __init__(self):
        self._head = None
    def is_empty(self):
        """判断链表是否为空"""
        return self._head == None
    def length(self):
        """返回链表的长度"""
        cur = self._head
        count = 0
        while cur != None:
            count += 1
            cur = cur.next
        return count

    def travel(self):
        """遍历链表"""
        cur = self._head
        while cur != None:
            print cur.item,
            cur = cur.next
        print ""

    def add(self, item):
        """头部插入元素"""
        node = Node(item)
        if self.is_empty():
            # 如果是空链表,将_head指向node
            self._head = node
        else:
            # 将node的next指向_head的头节点
            node.next = self._head
            # 将_head的头节点的prev指向node
            self._head.prev = node
            # 将_head 指向node
            self._head = node
    def append(self, item):
        """尾部插入元素"""
        node = Node(item)
        if self.is_empty():
            # 如果是空链表,将_head指向node
            self._head = node
        else:
            # 移动到链表尾部
            cur = self._head
            while cur.next != None:
                cur = cur.next
            # 将尾节点cur的next指向node
            cur.next = node
            # 将node的prev指向cur
            node.prev = cur
    def search(self, item):
        """查找元素是否存在"""
        cur = self._head
        while cur != None:
            if cur.item == item:
                return True
            cur = cur.next
        return False
    def remove(self, item):
        """删除元素"""
        if self.is_empty():
            return
        else:
            cur = self._head
            if cur.item == item:
                # 如果首节点的元素即是要删除的元素
                if cur.next == None:
                    # 如果链表只有这一个节点
                    self._head = None
                else:
                    # 将第二个节点的prev设置为None
                    cur.next.prev = None
                    # 将_head指向第二个节点
                    self._head = cur.next
                return
            while cur != None:
                if cur.item == item:
                    # 将cur的前一个节点的next指向cur的后一个节点
                    cur.prev.next = cur.next
                    # 将cur的后一个节点的prev指向cur的前一个节点
                    cur.next.prev = cur.prev
                    break
                cur = cur.next
if __name__ == "__main__":
    ll = DLinkList()
    ll.add(1)
    ll.add(2)
    ll.append(3)
    ll.insert(2, 4)
    ll.insert(4, 5)
    ll.insert(0, 6)
    print "length:",ll.length()
    ll.travel()
    print ll.search(3)
    print ll.search(4)
    ll.remove(1)
    print "length:",ll.length()
    ll.travel()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/秋刀鱼在做梦/article/detail/802969
推荐阅读
相关标签
  

闽ICP备14008679号