顺序表和链表

一,顺序表

定义:将元素顺序地存放在一块连续的存储区里,元素间的顺序关系由它们的存储顺序自然表示。

顺序表包含:表头和数据区

  • 连续内存存放表头和数据区:表头包括:容量、元素个数

    • 在数据区地址前开辟8个字节内存分别存储容量和元素个数(都是整型,存储整型需要4字节)

    • 容量不够需开辟新的内存时,数据区和表头区都要重新拷贝覆盖

  • 表头和数据区分离存储:表头包括:容量、元素个数、数据区地址

    • 单独开辟一块内存用来存储表头,表头保存数据区的地址

    • 容量不够需开辟新的内存时,只需要拷贝数据区,然后将表头指向新的内存地址

 

二,链表

定义:将元素存放在通过链接构造起来的一系列存储块中。

  • 一种线性表,不像顺序表一样连续存储数据,而是在每个节点(存储单元)里存放下一个节点的地址

  • 每个结点保存元素的值和指向下一个结点的内存地址

  • 链表查找元素时需要每次从头结点开始查找

1.链表与顺序表的对比

链表失去了顺序表直接定位读取的优点。同时链表由于增加了结点的指针域,空间开销比较大,但对于存储空间的使用要相对灵活

链表与顺序表各操作的复杂度如下:

操作链表顺序表
访问元素 O(n) O(1)
头部插入/删除 O(1) O(n)
尾部插入/删除 O(n) O(1)
中间插入/删除 O(n) 在于遍历 O(n) 在于数据挪位

注意虽然表面看起来复杂度都是O(n), 但是链表和顺序表在插入和删除时进行的是完全不同的操作。链表的主要耗时操作是遍历查找,删除和插入操作本身复杂度是O(1)。顺序表查找很快,主要耗时操作是拷贝覆盖;因为除了目标元素在尾部的特殊情况,顺序表进行插入和删除时需要对操作点之后的所有元素进行后移位操作,则只能通过拷贝和覆盖的方法进行。

 

2.python代码实现单链表

 1 class Node:
 2     """结点实现类"""
 3     def __init__(self, item):
 4         self.elem = item
 5         self.next = None
 6  7  # node = Node(100) 
 8    
 9 10 class SingleLinkList:
11     """单链表"""
12     def __init__(self, node=None):
13         self.__head = node
14     
15     def is_empty(self):
16         """链表是否为空"""
17         return self.__head == None
18 19     def length(self):
20         """链表长度"""
21         # cur游标,用来移动遍历结点
22         cur = self.__head
23         # count记录数量
24         count = 0
25         while cur != None:
26             count += 1
27             cur = cur.next
28         return count
29 30     def travel(self):
31         """遍历整个链表"""
32         cur = self.__head
33         while cur != None:
34             print(cur.elem, end=" ")
35             cur = cur.next
36         print("")
37 38     def add(self, item):
39         """链表头部添加元素,头插法"""
40         node = Node(item)
41         node.next = self.__head
42         self.__head = node   # 新插入的结点作为头结点
43 44     def append(self, item):
45         """链表尾部添加元素,尾插法"""
46         node = Node(item)
47         if self.is_empty():
48             self.__head = node
49         else:
50             cur = self.__head
51             while cur.next != None:
52                 cur = cur.next
53             cur.next = node
54 55     def insert(self, pos, item):
56         """指定位置添加元素
57         :params pos 从0开始
58         """
59         if pos <= 0:
60             self.add(item)
61         elif pos > (self.length()-1):
62             self.append(item)
63         else:
64             pre = self.__head
65             count = 0
66             while count < (pos-1):
67                 count += 1
68                 pre = pre.next
69             # 当退出循环后,pre指向pos-1位置
70             node = Node(item)
71             node.next = pre.next
72             pre.next = node
73 74     def remove(self, item):
75         """删除结点"""
76         cur = self.__head
77         pre = None
78         while cur != None:
79             if cur.elem == item:
80                 # 先判断此节点是否是头结点
81                 if cur == self.__head:
82                     self.__head = cur.next
83                 else:
84                     pre.next = cur.next
85                 break
86             else:
87                 pre = cur
88                 cur = cur.next
89 90     def search(self, item):
91       """查找结点是否存在"""
92        cur = self.__head
93     while cur != None:
94       if cur.elem == item:
95         return True
96       else:
97         cur = cur.next
98     return False

 

python中的数据结构

1.python中变量标识的本质

变量保存的不是元素的值,而是值的地址

如:a,b=b,a 只是将a和b保存的地址做了交换;

python中一个变量a之所以无需声明类型,但能够保存各种不同的类型,包括基础类型,函数等,就是因为变量仅保存的是对象的地址,通过地址获取具体的值(不像c等语言一样,变量使用前必须声明类型)

原文地址:https://www.cnblogs.com/Deaseyy/p/13624379.html