├── .idea
├── .gitignore
├── PlayWithDataStructure_SourceCode_In_Python.iml
├── inspectionProfiles
│ ├── Project_Default.xml
│ └── profiles_settings.xml
├── misc.xml
├── modules.xml
└── vcs.xml
├── LinkedList
├── DoublyLinkedList.py
├── DoublyLinkedNode.py
├── DoublyLinkedOperate.py
├── README.md
├── SinglyLinkedList.py
├── SinglyLinkedNode.py
├── SinglyLinkedOperate.py
└── __pycache__
│ └── SinglyLinkedNode.cpython-38.pyc
├── Queue
├── ArrayQueue.py
├── CircularLinkedQueue.py
├── LinkedQueue.py
├── Queue.py
└── README.md
├── README.md
├── Stack
├── ArrayStack.py
├── LinkedStack.py
├── README.md
└── Stack.py
└── String
├── KMPMatch.py
├── README.md
├── SimpleMatch.py
└── String.py
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 | # Datasource local storage ignored files
5 | /dataSources/
6 | /dataSources.local.xml
7 | # Editor-based HTTP Client requests
8 | /httpRequests/
9 |
--------------------------------------------------------------------------------
/.idea/PlayWithDataStructure_SourceCode_In_Python.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/.idea/inspectionProfiles/Project_Default.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/.idea/inspectionProfiles/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/LinkedList/DoublyLinkedList.py:
--------------------------------------------------------------------------------
1 | from LinkedList.DoublyLinkedNode import DoublySimplyListNode
2 |
3 |
4 | class DoublyLinkedBase:
5 | """管理双向链表的基本类(使用双侧哨兵结点)"""
6 |
7 | def __init__(self):
8 | self._header = DoublySimplyListNode(None) # 头部哨兵结点
9 | self._trailer = DoublySimplyListNode(None) # 尾部哨兵结点
10 | self._header.next = self._trailer
11 | self._trailer.prev = self._header
12 | self._size = 0
13 |
14 | def __len__(self):
15 | """返回链表中元素的数量"""
16 | return self._size
17 |
18 | def is_empty(self):
19 | """返回链表是否为空"""
20 | return self._size == 0
21 |
22 | def insert_between(self, value, prev, next):
23 | """向链表中添加新结点"""
24 | node = DoublySimplyListNode(value, prev, next)
25 | prev.next = node
26 | next.prev = node
27 | self._size += 1
28 | return node
29 |
30 | def delete_node(self, node):
31 | """从链表中删除结点"""
32 | prev = node.prev
33 | next = node.next
34 | prev.next = next
35 | next.prev = prev
36 | self._size -= 1
37 | value = node.value
38 | node.prev = node.next = node.val = None
39 | return value
40 |
--------------------------------------------------------------------------------
/LinkedList/DoublyLinkedNode.py:
--------------------------------------------------------------------------------
1 | class DoublySimplyListNode:
2 | """双链表结点"""
3 |
4 | __slots__ = "value", "next", "prev" # 使用__slots__减少内存占用
5 |
6 | def __init__(self, value, next: "DoublySimplyListNode" = None, prev: "DoublySimplyListNode" = None):
7 | self.value = value
8 | self.next = next
9 | self.prev = prev
10 |
11 | def __str__(self):
12 | if self.next and self.next.value:
13 | return str(self.value) + "<->" + str(self.value)
14 | else:
15 | return str(self.value) + "<->" + "None"
16 |
--------------------------------------------------------------------------------
/LinkedList/DoublyLinkedOperate.py:
--------------------------------------------------------------------------------
1 | from typing import List
2 |
3 | from LinkedList.DoublyLinkedNode import DoublySimplyListNode
4 |
5 |
6 | # 双链表的添加操作(在给定结点后添加)
7 | def add_node_by_prev(prev: "DoublySimplyListNode", value):
8 | node = DoublySimplyListNode(value) # 使用给定值初始化新结点(node)
9 | node.prev = prev # 令新结点(node)的前驱指针指向给定结点(prev)
10 | node.next = prev.next # 令新结点(node)的后续指针指向给定结点(prev)的后一个结点
11 |
12 | prev.next = node # 令给定结点(prev)的后驱指针指向新结点
13 | node.next.prev = node # 令后一个节点的前驱指针指向新结点
14 |
15 |
16 | # 双链表的删除操作(删除给定结点)
17 | def delete_node_by_node(node: "DoublySimplyListNode"):
18 | node.prev.next, node.next.prev = node.next, node.prev # 令给定结点前一个结点的后驱指针指向给定结点的后驱结点,后一个结点的前驱指针指向给定结点的前驱结点
19 |
20 |
21 | # 双链表的整表创建
22 | def build_doubly_list_node(values: List):
23 | node = head = DoublySimplyListNode(None) # 创建头结点,node指向尾结点(此时即头结点)
24 | for value in values:
25 | new = DoublySimplyListNode(value) # 创建新结点
26 | new.prev = node # 令新结点的前驱指针指向当前节点
27 | new.next = head # 令新结点的后继指针指向当前节点
28 |
29 | node.next = new # 并令当前链表尾部的终端结点指向新结点
30 | node = node.next # node重新指向尾结点(即新创建的节点)
31 | head.prev = node # 令头结点的前驱指针指向链表尾部的终端结点
32 | return head
33 |
--------------------------------------------------------------------------------
/LinkedList/README.md:
--------------------------------------------------------------------------------
1 | ## SinglyLinkedNode 单链表结点
2 | ```python
3 | class SinglyLinkedNode:
4 | """单链表结点"""
5 |
6 | __slots__ = "value", "next" # 使用__slots__减少内存占用
7 |
8 | def __init__(self, value, next: "SinglyLinkedNode" = None):
9 | self.value = value # 数据域
10 | self.next = next # 指针域
11 |
12 | def __str__(self):
13 | return str(self.value) + "->" + str(self.next)
14 | ```
15 |
16 | ## SinglyLinkedOperate 单链表的基本操作:读取、插入、删除、整表创建
17 |
18 | ```python
19 | from typing import List
20 |
21 | from LinkedList.SinglyLinkedNode import SinglyLinkedNode
22 |
23 |
24 | # 单链表的读取(给定读取坐标)
25 | def get_node_by_index(head: "SinglyLinkedNode", index: int):
26 | for _ in range(index + 1): # 寻找第index个结点(从0开始计数)的前一个结点,如果链表长度不足则不删除
27 | if not head.next:
28 | return None
29 | head = head.next
30 | else:
31 | return head.value
32 |
33 |
34 | # 单链表的添加操作(在给定结点后添加)
35 | def add_node_by_prev(prev: "SinglyLinkedNode", value):
36 | node = SinglyLinkedNode(value) # 使用给定值初始化新结点(node)
37 | node.next = prev.next # 令新结点(node)指向给定结点(prev)的下一个结点
38 | prev.next = node # 令给定结点(prev)指向新结点(node)
39 |
40 |
41 | # 单链表的添加操作(给定插入坐标)
42 | def add_node_by_index(head: "SinglyLinkedNode", index: int, value):
43 | idx = -1 # 因为从头结点开始遍历,故使用头结点的坐标-1
44 | while idx < index and head.next: # 寻找第index个结点(从0开始计数),如果链表长度不足则添加在链表尾部
45 | head = head.next
46 | idx += 1
47 | add_node_by_prev(head, value) # 在第index个结点后添加新结点
48 |
49 |
50 | # 单链表的删除操作(在给定结点后删除)
51 | def delete_node_by_prev(prev: "SinglyLinkedNode"):
52 | prev.next = prev.next.next # 令给定结点(prev)直接指向被删除结点的下一个结点
53 |
54 |
55 | # 单链表的删除操作(给定删除坐标)
56 | def delete_node_by_index(head: "SinglyLinkedNode", index: int):
57 | for _ in range(index): # 寻找第index个结点(从0开始计数)的前一个结点,如果链表长度不足则不删除
58 | if not head.next:
59 | break
60 | head = head.next
61 | else:
62 | delete_node_by_prev(head)
63 |
64 |
65 | # 单链表的整表创建
66 | def build_singly_list_node(values: List):
67 | node = head = SinglyLinkedNode(None) # 创建头结点,node指向尾结点(此时即头结点)
68 | for value in values:
69 | node.next = SinglyLinkedNode(value) # 创建新结点,并令当前链表尾部的终端结点指向新结点
70 | node = node.next # node重新指向尾结点(即新创建的节点)
71 | return head
72 | ```
73 |
74 | ## SinglyLinkedList 管理单链表的基本类:读取、插入、删除
75 |
76 | ```python
77 | from LinkedList.SinglyLinkedNode import SinglyLinkedNode
78 |
79 |
80 | class SinglyLinkedList:
81 | """管理单向链表的基本类(使用头结点)"""
82 |
83 | def __init__(self):
84 | """初始化单向链表"""
85 | self._head = SinglyLinkedNode(None) # 创建头结点
86 | self._size = 0
87 |
88 | def __len__(self):
89 | """返回链表中元素的数量"""
90 | return self._size
91 |
92 | def is_empty(self):
93 | """返回链表是否为空"""
94 | return self._size == 0
95 |
96 | def get(self, index: int):
97 | """依据坐标读取变量:返回链表中第index个元素的值"""
98 | if index < 0 or index >= self._size:
99 | return -1
100 | curr = self._head
101 | for _ in range(index + 1):
102 | curr = curr.next
103 | return curr.value
104 |
105 | def add_at_head(self, value):
106 | """在头结点前添加结点"""
107 | self.add_at_index(0, value)
108 |
109 | def add_at_tail(self, value):
110 | """在尾结点之后添加结点"""
111 | self.add_at_index(self._size, value)
112 |
113 | def add_at_index(self, index: int, value):
114 | """在指定坐标前添加结点(若坐标无效则不添加):在链表中第index个元素前插入值为value的结点"""
115 | if index < 0 or index > self._size:
116 | return
117 | self._size += 1
118 | prev = self._head
119 | for _ in range(index):
120 | prev = prev.next
121 | node = SinglyLinkedNode(value, prev.next)
122 | prev.next = node
123 |
124 | def delete_at_index(self, index: int):
125 | """依据坐标删除结点(若坐标无效则不删除)"""
126 | if index < 0 or index >= self._size:
127 | return
128 | self._size -= 1
129 | prev = self._head
130 | for _ in range(index):
131 | prev = prev.next
132 | prev.next = prev.next.next
133 | ```
134 |
135 | ## DoublyLinkedNode 双链表结点
136 |
137 | ```python
138 | class DoublySimplyListNode:
139 | """双链表结点"""
140 |
141 | __slots__ = "value", "next", "prev" # 使用__slots__减少内存占用
142 |
143 | def __init__(self, value, next: "DoublySimplyListNode" = None, prev: "DoublySimplyListNode" = None):
144 | self.value = value
145 | self.next = next
146 | self.prev = prev
147 |
148 | def __str__(self):
149 | if self.next and self.next.value:
150 | return str(self.value) + "<->" + str(self.value)
151 | else:
152 | return str(self.value) + "<->" + "None"
153 | ```
154 |
155 | ## DoublyLinkedOperate 双链表的基本操作:插入、删除、整表创建
156 |
157 | ```python
158 | from typing import List
159 |
160 | from LinkedList.DoublyLinkedNode import DoublySimplyListNode
161 |
162 |
163 | # 双链表的添加操作(在给定结点后添加)
164 | def add_node_by_prev(prev: "DoublySimplyListNode", value):
165 | node = DoublySimplyListNode(value) # 使用给定值初始化新结点(node)
166 | node.prev = prev # 令新结点(node)的前驱指针指向给定结点(prev)
167 | node.next = prev.next # 令新结点(node)的后续指针指向给定结点(prev)的后一个结点
168 |
169 | prev.next = node # 令给定结点(prev)的后驱指针指向新结点
170 | node.next.prev = node # 令后一个节点的前驱指针指向新结点
171 |
172 |
173 | # 双链表的删除操作(删除给定结点)
174 | def delete_node_by_node(node: "DoublySimplyListNode"):
175 | node.prev.next, node.next.prev = node.next, node.prev # 令给定结点前一个结点的后驱指针指向给定结点的后驱结点,后一个结点的前驱指针指向给定结点的前驱结点
176 |
177 |
178 | # 双链表的整表创建
179 | def build_doubly_list_node(values: List):
180 | node = head = DoublySimplyListNode(None) # 创建头结点,node指向尾结点(此时即头结点)
181 | for value in values:
182 | new = DoublySimplyListNode(value) # 创建新结点
183 | new.prev = node # 令新结点的前驱指针指向当前节点
184 | new.next = head # 令新结点的后继指针指向当前节点
185 |
186 | node.next = new # 并令当前链表尾部的终端结点指向新结点
187 | node = node.next # node重新指向尾结点(即新创建的节点)
188 | head.prev = node # 令头结点的前驱指针指向链表尾部的终端结点
189 | return head
190 | ```
191 |
192 | ## DoublyLinkedList 管理双链表的基本类:插入、删除
193 |
194 | ```python
195 | from LinkedList.DoublyLinkedNode import DoublySimplyListNode
196 |
197 |
198 | class DoublyLinkedBase:
199 | """管理双向链表的基本类(使用双侧哨兵结点)"""
200 |
201 | def __init__(self):
202 | self._header = DoublySimplyListNode(None) # 头部哨兵结点
203 | self._trailer = DoublySimplyListNode(None) # 尾部哨兵结点
204 | self._header.next = self._trailer
205 | self._trailer.prev = self._header
206 | self._size = 0
207 |
208 | def __len__(self):
209 | """返回链表中元素的数量"""
210 | return self._size
211 |
212 | def is_empty(self):
213 | """返回链表是否为空"""
214 | return self._size == 0
215 |
216 | def insert_between(self, value, prev, next):
217 | """向链表中添加新结点"""
218 | node = DoublySimplyListNode(value, prev, next)
219 | prev.next = node
220 | next.prev = node
221 | self._size += 1
222 | return node
223 |
224 | def delete_node(self, node):
225 | """从链表中删除结点"""
226 | prev = node.prev
227 | next = node.next
228 | prev.next = next
229 | next.prev = prev
230 | self._size -= 1
231 | value = node.value
232 | node.prev = node.next = node.val = None
233 | return value
234 | ```
235 |
--------------------------------------------------------------------------------
/LinkedList/SinglyLinkedList.py:
--------------------------------------------------------------------------------
1 | from LinkedList.SinglyLinkedNode import SinglyLinkedNode
2 |
3 |
4 | class SinglyLinkedList:
5 | """管理单向链表的基本类(使用头结点)"""
6 |
7 | def __init__(self):
8 | """初始化单向链表"""
9 | self._head = SinglyLinkedNode(None) # 创建头结点
10 | self._size = 0
11 |
12 | def __len__(self):
13 | """返回链表中元素的数量"""
14 | return self._size
15 |
16 | def is_empty(self):
17 | """返回链表是否为空"""
18 | return self._size == 0
19 |
20 | def get(self, index: int):
21 | """依据坐标读取变量:返回链表中第index个元素的值"""
22 | if index < 0 or index >= self._size:
23 | return -1
24 | curr = self._head
25 | for _ in range(index + 1):
26 | curr = curr.next
27 | return curr.value
28 |
29 | def add_at_head(self, value):
30 | """在头结点前添加结点"""
31 | self.add_at_index(0, value)
32 |
33 | def add_at_tail(self, value):
34 | """在尾结点之后添加结点"""
35 | self.add_at_index(self._size, value)
36 |
37 | def add_at_index(self, index: int, value):
38 | """在指定坐标前添加结点(若坐标无效则不添加):在链表中第index个元素前插入值为value的结点"""
39 | if index < 0 or index > self._size:
40 | return
41 | self._size += 1
42 | prev = self._head
43 | for _ in range(index):
44 | prev = prev.next
45 | node = SinglyLinkedNode(value, prev.next)
46 | prev.next = node
47 |
48 | def delete_at_index(self, index: int):
49 | """依据坐标删除结点(若坐标无效则不删除)"""
50 | if index < 0 or index >= self._size:
51 | return
52 | self._size -= 1
53 | prev = self._head
54 | for _ in range(index):
55 | prev = prev.next
56 | prev.next = prev.next.next
57 |
--------------------------------------------------------------------------------
/LinkedList/SinglyLinkedNode.py:
--------------------------------------------------------------------------------
1 | class SinglyLinkedNode:
2 | """单链表结点"""
3 |
4 | __slots__ = "value", "next" # 使用__slots__减少内存占用
5 |
6 | def __init__(self, value, next: "SinglyLinkedNode" = None):
7 | self.value = value # 数据域
8 | self.next = next # 指针域
9 |
10 | def __str__(self):
11 | return str(self.value) + "->" + str(self.next)
12 |
--------------------------------------------------------------------------------
/LinkedList/SinglyLinkedOperate.py:
--------------------------------------------------------------------------------
1 | from typing import List
2 |
3 | from LinkedList.SinglyLinkedNode import SinglyLinkedNode
4 |
5 |
6 | # 单链表的读取(给定读取坐标)
7 | def get_node_by_index(head: "SinglyLinkedNode", index: int):
8 | for _ in range(index + 1): # 寻找第index个结点(从0开始计数)的前一个结点,如果链表长度不足则不删除
9 | if not head.next:
10 | return None
11 | head = head.next
12 | else:
13 | return head.value
14 |
15 |
16 | # 单链表的添加操作(在给定结点后添加)
17 | def add_node_by_prev(prev: "SinglyLinkedNode", value):
18 | node = SinglyLinkedNode(value) # 使用给定值初始化新结点(node)
19 | node.next = prev.next # 令新结点(node)指向给定结点(prev)的下一个结点
20 | prev.next = node # 令给定结点(prev)指向新结点(node)
21 |
22 |
23 | # 单链表的添加操作(给定插入坐标)
24 | def add_node_by_index(head: "SinglyLinkedNode", index: int, value):
25 | idx = -1 # 因为从头结点开始遍历,故使用头结点的坐标-1
26 | while idx < index and head.next: # 寻找第index个结点(从0开始计数),如果链表长度不足则添加在链表尾部
27 | head = head.next
28 | idx += 1
29 | add_node_by_prev(head, value) # 在第index个结点后添加新结点
30 |
31 |
32 | # 单链表的删除操作(在给定结点后删除)
33 | def delete_node_by_prev(prev: "SinglyLinkedNode"):
34 | prev.next = prev.next.next # 令给定结点(prev)直接指向被删除结点的下一个结点
35 |
36 |
37 | # 单链表的删除操作(给定删除坐标)
38 | def delete_node_by_index(head: "SinglyLinkedNode", index: int):
39 | for _ in range(index): # 寻找第index个结点(从0开始计数)的前一个结点,如果链表长度不足则不删除
40 | if not head.next:
41 | break
42 | head = head.next
43 | else:
44 | delete_node_by_prev(head)
45 |
46 |
47 | # 单链表的整表创建
48 | def build_singly_list_node(values: List):
49 | node = head = SinglyLinkedNode(None) # 创建头结点,node指向尾结点(此时即头结点)
50 | for value in values:
51 | node.next = SinglyLinkedNode(value) # 创建新结点,并令当前链表尾部的终端结点指向新结点
52 | node = node.next # node重新指向尾结点(即新创建的节点)
53 | return head
54 |
--------------------------------------------------------------------------------
/LinkedList/__pycache__/SinglyLinkedNode.cpython-38.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ChangxingJiang/PlayWithDataStructure_SourceCode_In_Python/96db56a2efac7d38d54a06cd5725bd057d945db0/LinkedList/__pycache__/SinglyLinkedNode.cpython-38.pyc
--------------------------------------------------------------------------------
/Queue/ArrayQueue.py:
--------------------------------------------------------------------------------
1 | class Queue:
2 | """顺序存储结构的队列(循环队列)"""
3 |
4 | DEFAULT_CAPACITY = 10 # 队列的默认长度(若长度不足则每次扩展到之前的2倍)
5 |
6 | def __init__(self):
7 | """初始化一个空队列"""
8 | self._data = [None] * self.DEFAULT_CAPACITY # 队列存储数组
9 | self._size = 0 # 队列长度
10 | self._front = 0 # 队头元素的坐标
11 |
12 | def __len__(self):
13 | """返回队列内元素数量"""
14 | return self._size
15 |
16 | def is_empty(self):
17 | """返回队列是否为空"""
18 | return self._size == 0
19 |
20 | def clear(self):
21 | """将队列清空"""
22 | self._data = [None] * self.DEFAULT_CAPACITY
23 | self._size = 0
24 | self._front = 0
25 |
26 | def first(self):
27 | """若队列存在且非空,返回队列的队头元素"""
28 | if self.is_empty():
29 | raise ValueError("Queue is Empty")
30 | return self._data[self._front]
31 |
32 | def dequeue(self):
33 | """删除队列中的队头元素并返回该元素的值"""
34 | if self.is_empty():
35 | raise ValueError("Queue is Empty")
36 | answer = self._data[self._front] # 提取队头元素的值
37 | self._data[self._front] = None
38 | self._front = (self._front + 1) % len(self._data) # 计算新的队头元素坐标
39 | self._size -= 1
40 | return answer
41 |
42 | def enqueue(self, value):
43 | """插入新元素value到队列中并成为队尾元素"""
44 | if self._size == len(self._data): # 判断队列长度是否超出数组限制
45 | self._resize(2 * len(self._data))
46 | avail = (self._front + self._size) % len(self._data) # 计算队尾元素坐标
47 | self._data[avail] = value
48 | self._size += 1
49 |
50 | def _resize(self, cap):
51 | """修改存储队列的数组长度"""
52 | old = self._data
53 | self._data = [None] * cap
54 | walk = self._front
55 | for i in range(self._size): # 遍历之前的队列
56 | self._data[i] = old[walk]
57 | walk = (walk + 1) % len(old)
58 | self._front = 0
59 |
--------------------------------------------------------------------------------
/Queue/CircularLinkedQueue.py:
--------------------------------------------------------------------------------
1 | from LinkedList.SinglyLinkedNode import SinglyLinkedNode
2 | from Queue.Queue import Queue
3 |
4 |
5 | class CircularLinkedQueue(Queue):
6 | """链式存储结构的队列(循环链表)"""
7 |
8 | def __init__(self):
9 | super().__init__()
10 | self._tail = None # 尾指针
11 | self._size = 0 # 队列的元素数量
12 |
13 | def __len__(self):
14 | """返回队列中元素的数量"""
15 | return self._size
16 |
17 | def is_empty(self):
18 | """返回队列是否为空"""
19 | return self._size == 0
20 |
21 | def clear(self):
22 | """将队列清空"""
23 | self._tail = None # 尾指针
24 | self._size = 0 # 队列的元素数量
25 |
26 | def first(self):
27 | """若队列存在且非空,返回队列的队头元素"""
28 | if self.is_empty():
29 | raise ValueError("Queue is Empty")
30 | return self._tail.next.value
31 |
32 | def dequeue(self):
33 | """删除队列中的队头元素并返回该元素的值"""
34 | if self.is_empty():
35 | raise ValueError("Queue is Empty")
36 | head = self._tail.next
37 | if self._size == 1:
38 | self._tail = None
39 | else:
40 | self._tail.next = head.next # 令尾结点直接指向原头结点的下一个结点
41 | self._size -= 1
42 | return head.value
43 |
44 | def enqueue(self, value):
45 | """插入新元素value到队列中并成为队尾元素"""
46 | node = SinglyLinkedNode(value, None) # 构造链表对象
47 | if self.is_empty():
48 | node.next = node
49 | else:
50 | node.next = self._tail.next # 令新结点指向头结点
51 | self._tail.next = node # 令原来的尾结点指向新结点
52 | self._tail = node # 令尾指针指向新的尾结点(即新结点)
53 | self._size += 1
54 |
--------------------------------------------------------------------------------
/Queue/LinkedQueue.py:
--------------------------------------------------------------------------------
1 | from LinkedList.SinglyLinkedNode import SinglyLinkedNode
2 | from Queue.Queue import Queue
3 |
4 |
5 | class LinkedQueue(Queue):
6 | """链式存储结构的队列(单链表)"""
7 |
8 | def __init__(self):
9 | super().__init__()
10 | self._head = None # 头指针
11 | self._tail = None # 尾指针
12 | self._size = 0 # 队列中元素的数量
13 |
14 | def __len__(self):
15 | """返回队列中元素的数量"""
16 | return self._size
17 |
18 | def is_empty(self):
19 | """返回队列是否为空"""
20 | return self._size == 0
21 |
22 | def clear(self):
23 | """将队列清空"""
24 | self._head = None
25 | self._tail = None
26 | self._size = 0
27 |
28 | def first(self):
29 | """若队列存在且非空,返回队列的队头元素"""
30 | if self.is_empty():
31 | raise ValueError("Queue is Empty")
32 | return self._head.value
33 |
34 | def dequeue(self):
35 | """删除队列中的队头元素并返回该元素的值"""
36 | if self.is_empty():
37 | raise ValueError("Queue is Empty")
38 | ans = self._head.value
39 | self._head = self._head.next
40 | self._size -= 1
41 | if self.is_empty():
42 | self._tail = None
43 | return ans
44 |
45 | def enqueue(self, value):
46 | """插入新元素value到队列中并成为队尾元素"""
47 | node = SinglyLinkedNode(value) # 构造链表对象
48 | if self.is_empty():
49 | self._head = node
50 | else:
51 | self._tail.next = node
52 | self._tail = node
53 | self._size += 1
54 |
--------------------------------------------------------------------------------
/Queue/Queue.py:
--------------------------------------------------------------------------------
1 | class Queue:
2 | """队列的结构定义"""
3 |
4 | def __init__(self):
5 | """初始化一个空队列"""
6 | pass
7 |
8 | def __len__(self):
9 | """返回队列内元素数量"""
10 | pass
11 |
12 | def is_empty(self):
13 | """返回队列是否为空"""
14 | pass
15 |
16 | def clear(self):
17 | """将队列清空"""
18 | pass
19 |
20 | def first(self):
21 | """若队列存在且非空,返回队列的队头元素"""
22 | pass
23 |
24 | def dequeue(self):
25 | """删除队列中的队头元素并返回该元素的值"""
26 | pass
27 |
28 | def enqueue(self, value):
29 | """插入新元素value到队列中并成为队尾元素"""
30 | pass
31 |
--------------------------------------------------------------------------------
/Queue/README.md:
--------------------------------------------------------------------------------
1 | ## Queue 队列的结构定义
2 |
3 | ```python
4 | class Queue:
5 | """队列的结构定义"""
6 |
7 | def __init__(self):
8 | """初始化一个空队列"""
9 | pass
10 |
11 | def __len__(self):
12 | """返回队列内元素数量"""
13 | pass
14 |
15 | def is_empty(self):
16 | """返回队列是否为空"""
17 | pass
18 |
19 | def clear(self):
20 | """将队列清空"""
21 | pass
22 |
23 | def first(self):
24 | """若队列存在且非空,返回队列的队头元素"""
25 | pass
26 |
27 | def dequeue(self):
28 | """删除队列中的队头元素并返回该元素的值"""
29 | pass
30 |
31 | def enqueue(self, value):
32 | """插入新元素value到队列中并成为队尾元素"""
33 | pass
34 | ```
35 |
36 | ## ArrayQueue 顺序存储结构的队列(循环队列)
37 |
38 | ```python
39 | class Queue:
40 | """顺序存储结构的队列(循环队列)"""
41 |
42 | DEFAULT_CAPACITY = 10 # 队列的默认长度(若长度不足则每次扩展到之前的2倍)
43 |
44 | def __init__(self):
45 | """初始化一个空队列"""
46 | self._data = [None] * self.DEFAULT_CAPACITY # 队列存储数组
47 | self._size = 0 # 队列长度
48 | self._front = 0 # 队头元素的坐标
49 |
50 | def __len__(self):
51 | """返回队列内元素数量"""
52 | return self._size
53 |
54 | def is_empty(self):
55 | """返回队列是否为空"""
56 | return self._size == 0
57 |
58 | def clear(self):
59 | """将队列清空"""
60 | self._data = [None] * self.DEFAULT_CAPACITY
61 | self._size = 0
62 | self._front = 0
63 |
64 | def first(self):
65 | """若队列存在且非空,返回队列的队头元素"""
66 | if self.is_empty():
67 | raise ValueError("Queue is Empty")
68 | return self._data[self._front]
69 |
70 | def dequeue(self):
71 | """删除队列中的队头元素并返回该元素的值"""
72 | if self.is_empty():
73 | raise ValueError("Queue is Empty")
74 | answer = self._data[self._front] # 提取队头元素的值
75 | self._data[self._front] = None
76 | self._front = (self._front + 1) % len(self._data) # 计算新的队头元素坐标
77 | self._size -= 1
78 | return answer
79 |
80 | def enqueue(self, value):
81 | """插入新元素value到队列中并成为队尾元素"""
82 | if self._size == len(self._data): # 判断队列长度是否超出数组限制
83 | self._resize(2 * len(self._data))
84 | avail = (self._front + self._size) % len(self._data) # 计算队尾元素坐标
85 | self._data[avail] = value
86 | self._size += 1
87 |
88 | def _resize(self, cap):
89 | """修改存储队列的数组长度"""
90 | old = self._data
91 | self._data = [None] * cap
92 | walk = self._front
93 | for i in range(self._size): # 遍历之前的队列
94 | self._data[i] = old[walk]
95 | walk = (walk + 1) % len(old)
96 | self._front = 0
97 | ```
98 |
99 | ## LinkedQueue 链式存储结构的队列(单链表)
100 |
101 | ```python
102 | from LinkedList.SinglyLinkedNode import SinglyLinkedNode
103 | from Queue.Queue import Queue
104 |
105 |
106 | class LinkedQueue(Queue):
107 | """链式存储结构的队列(单链表)"""
108 |
109 | def __init__(self):
110 | super().__init__()
111 | self._head = None # 头指针
112 | self._tail = None # 尾指针
113 | self._size = 0 # 队列中元素的数量
114 |
115 | def __len__(self):
116 | """返回队列中元素的数量"""
117 | return self._size
118 |
119 | def is_empty(self):
120 | """返回队列是否为空"""
121 | return self._size == 0
122 |
123 | def clear(self):
124 | """将队列清空"""
125 | self._head = None
126 | self._tail = None
127 | self._size = 0
128 |
129 | def first(self):
130 | """若队列存在且非空,返回队列的队头元素"""
131 | if self.is_empty():
132 | raise ValueError("Queue is Empty")
133 | return self._head.value
134 |
135 | def dequeue(self):
136 | """删除队列中的队头元素并返回该元素的值"""
137 | if self.is_empty():
138 | raise ValueError("Queue is Empty")
139 | ans = self._head.value
140 | self._head = self._head.next
141 | self._size -= 1
142 | if self.is_empty():
143 | self._tail = None
144 | return ans
145 |
146 | def enqueue(self, value):
147 | """插入新元素value到队列中并成为队尾元素"""
148 | node = SinglyLinkedNode(value) # 构造链表对象
149 | if self.is_empty():
150 | self._head = node
151 | else:
152 | self._tail.next = node
153 | self._tail = node
154 | self._size += 1
155 | ```
156 |
157 | ## CircularLinkedQueue 链式存储结构的队列(循环链表)
158 |
159 | ```python
160 | from LinkedList.SinglyLinkedNode import SinglyLinkedNode
161 | from Queue.Queue import Queue
162 |
163 |
164 | class CircularLinkedQueue(Queue):
165 | """链式存储结构的队列(循环链表)"""
166 |
167 | def __init__(self):
168 | super().__init__()
169 | self._tail = None # 尾指针
170 | self._size = 0 # 队列的元素数量
171 |
172 | def __len__(self):
173 | """返回队列中元素的数量"""
174 | return self._size
175 |
176 | def is_empty(self):
177 | """返回队列是否为空"""
178 | return self._size == 0
179 |
180 | def clear(self):
181 | """将队列清空"""
182 | self._tail = None # 尾指针
183 | self._size = 0 # 队列的元素数量
184 |
185 | def first(self):
186 | """若队列存在且非空,返回队列的队头元素"""
187 | if self.is_empty():
188 | raise ValueError("Queue is Empty")
189 | return self._tail.next.value
190 |
191 | def dequeue(self):
192 | """删除队列中的队头元素并返回该元素的值"""
193 | if self.is_empty():
194 | raise ValueError("Queue is Empty")
195 | head = self._tail.next
196 | if self._size == 1:
197 | self._tail = None
198 | else:
199 | self._tail.next = head.next # 令尾结点直接指向原头结点的下一个结点
200 | self._size -= 1
201 | return head.value
202 |
203 | def enqueue(self, value):
204 | """插入新元素value到队列中并成为队尾元素"""
205 | node = SinglyLinkedNode(value, None) # 构造链表对象
206 | if self.is_empty():
207 | node.next = node
208 | else:
209 | node.next = self._tail.next # 令新结点指向头结点
210 | self._tail.next = node # 令原来的尾结点指向新结点
211 | self._tail = node # 令尾指针指向新的尾结点(即新结点)
212 | self._size += 1
213 | ```
214 |
215 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 《大话数据结构》配套源码(Python版)
2 |
3 | > 该书随书源码的语言为C;我参考书中内容和配套源码,写了一套Python格式的配套源码。**这套配套源码并非直接翻译C语言的配套源码**,而是结合我的理解略作了修改,这些修改包括:
4 | >
5 | > * 将指针参数等C语言特性改为Python习惯的方法
6 | > * 修改变量名的命名由将驼峰式改为下划线式
7 | > * 移除部分Python中不需要手动处理的垃圾回收函数和方法
8 | > * 补充了部分相关的类和函数
9 | >
10 | > 作者:长行
11 | >
12 | > 时间:2020.07.12
13 |
14 | ## LinkedList 链表 (第3章 - 第2部分)
15 |
16 | SinglyLinkedNode 单链表结点
17 |
18 | SinglyLinkedOperate 单链表的基本操作:读取、插入、删除、整表创建
19 |
20 | SinglyLinkedList 管理单链表的基本类:读取、插入、删除
21 |
22 | DoublyLinkedNode 双链表结点
23 |
24 | DoublyLinkedOperate 双链表的基本操作:插入、删除、整表创建
25 |
26 | DoublyLinkedList 管理双链表的基本类:插入、删除
27 |
28 | ## Stack 栈 (第4章 - 第1部分)
29 |
30 | Stack 栈的结构定义
31 |
32 | ArrayStack 顺序存储结构的栈(Python列表存储)
33 |
34 | LinkedStack 链式存储结构的栈(单链表存储)
35 |
36 | ## Queue 队列 (第4章 - 第2部分)
37 |
38 | Queue 队列的结构定义
39 |
40 | ArrayQueue 顺序存储结构的队列(循环队列)
41 |
42 | LinkedQueue 链式存储结构的队列(单链表)
43 |
44 | CircularLinkedQueue 链式存储结构的队列(循环链表)
45 |
46 | ## String 串 (第5章)
47 |
48 | String 串的抽象数据类型及基本操作示例
49 |
50 | SimpleMatch 朴素的模式匹配算法
51 |
52 | KMPMatch KMP的朴素匹配算法
53 |
54 |
--------------------------------------------------------------------------------
/Stack/ArrayStack.py:
--------------------------------------------------------------------------------
1 | from Stack.Stack import Stack
2 |
3 |
4 | class ArrayStack(Stack):
5 | """顺序存储结构的栈(Python列表存储)"""
6 |
7 | def __init__(self):
8 | """初始化一个空栈"""
9 | super().__init__()
10 | self._data = []
11 |
12 | def __len__(self):
13 | """返回栈内元素数量"""
14 | return len(self._data)
15 |
16 | def is_empty(self):
17 | """返回栈是否为空栈"""
18 | return len(self._data) == 0
19 |
20 | def clear(self):
21 | """清空栈"""
22 | self._data.clear()
23 |
24 | def top(self):
25 | """若栈存在且非空,则返回栈顶元素"""
26 | if self.is_empty():
27 | raise ValueError("Stack is Empty")
28 | return self._data[-1]
29 |
30 | def push(self, value):
31 | """若栈存在,则插入新元素value到栈中并成为栈顶元素"""
32 | self._data.append(value)
33 |
34 | def pop(self):
35 | """若栈存在,则删除栈顶元素并返回其值"""
36 | if self.is_empty():
37 | raise ValueError("Stack is Empty")
38 | return self._data.pop()
39 |
--------------------------------------------------------------------------------
/Stack/LinkedStack.py:
--------------------------------------------------------------------------------
1 | from LinkedList.SinglyLinkedNode import SinglyLinkedNode
2 | from Stack.Stack import Stack
3 |
4 |
5 | class LinkedStack(Stack):
6 | """链式存储结构的栈(单链表存储)"""
7 |
8 | def __init__(self):
9 | super().__init__()
10 | self._head = None # 头指针
11 | self._size = 0 # 栈中元素的数量
12 |
13 | def __len__(self):
14 | """返回栈中元素的数量"""
15 | return self._size
16 |
17 | def is_empty(self):
18 | """返回栈是否为空"""
19 | return self._size == 0
20 |
21 | def clear(self):
22 | """清空栈"""
23 | self._head = None
24 | self._size = 0
25 |
26 | def push(self, value):
27 | """向栈中压入元素"""
28 | self._head = SinglyLinkedNode(value, self._head) # 构造链表对象
29 | self._size += 1
30 |
31 | def top(self):
32 | """查询栈顶元素"""
33 | if self.is_empty():
34 | raise ValueError("Stack is Empty")
35 | return self._head.value
36 |
37 | def pop(self):
38 | """取出栈顶元素"""
39 | if self.is_empty():
40 | raise ValueError("Stack is Empty")
41 | ans = self._head.value
42 | self._head = self._head.next
43 | self._size -= 1
44 | return ans
45 |
--------------------------------------------------------------------------------
/Stack/README.md:
--------------------------------------------------------------------------------
1 | ## Stack 栈的结构定义
2 |
3 | ```python
4 | class Stack:
5 | """栈的结构定义"""
6 |
7 | def __init__(self):
8 | """初始化一个空栈"""
9 | pass
10 |
11 | def __len__(self):
12 | """返回栈内元素数量"""
13 | pass
14 |
15 | def is_empty(self):
16 | """返回栈是否为空栈"""
17 | pass
18 |
19 | def clear(self):
20 | """清空栈"""
21 | pass
22 |
23 | def top(self):
24 | """若栈存在且非空,则返回栈顶元素"""
25 | pass
26 |
27 | def push(self, value):
28 | """若栈存在,则插入新元素value到栈中并成为栈顶元素"""
29 | pass
30 |
31 | def pop(self):
32 | """若栈存在,则删除栈顶元素并返回其值"""
33 | pass
34 | ```
35 |
36 | ## ArrayStack 顺序存储结构的栈(Python列表存储)
37 |
38 | ```python
39 | from Stack.Stack import Stack
40 |
41 |
42 | class ArrayStack(Stack):
43 | """顺序存储结构的栈(Python列表存储)"""
44 |
45 | def __init__(self):
46 | """初始化一个空栈"""
47 | super().__init__()
48 | self._data = []
49 |
50 | def __len__(self):
51 | """返回栈内元素数量"""
52 | return len(self._data)
53 |
54 | def is_empty(self):
55 | """返回栈是否为空栈"""
56 | return len(self._data) == 0
57 |
58 | def clear(self):
59 | """清空栈"""
60 | self._data.clear()
61 |
62 | def top(self):
63 | """若栈存在且非空,则返回栈顶元素"""
64 | if self.is_empty():
65 | raise ValueError("Stack is Empty")
66 | return self._data[-1]
67 |
68 | def push(self, value):
69 | """若栈存在,则插入新元素value到栈中并成为栈顶元素"""
70 | self._data.append(value)
71 |
72 | def pop(self):
73 | """若栈存在,则删除栈顶元素并返回其值"""
74 | if self.is_empty():
75 | raise ValueError("Stack is Empty")
76 | return self._data.pop()
77 | ```
78 |
79 | ## LinkedStack 链式存储结构的栈(单链表存储)
80 |
81 | [SinglyLinkedNode(单链表结点)](https://dataartist.blog.csdn.net/article/details/107294965)
82 |
83 | ```python
84 | from LinkedList.SinglyLinkedNode import SinglyLinkedNode
85 | from Stack.Stack import Stack
86 |
87 |
88 | class LinkedStack(Stack):
89 | """链式存储结构的栈(单链表存储)"""
90 |
91 | def __init__(self):
92 | super().__init__()
93 | self._head = None # 头指针
94 | self._size = 0 # 栈中元素的数量
95 |
96 | def __len__(self):
97 | """返回栈中元素的数量"""
98 | return self._size
99 |
100 | def is_empty(self):
101 | """返回栈是否为空"""
102 | return self._size == 0
103 |
104 | def clear(self):
105 | """清空栈"""
106 | self._head = None
107 | self._size = 0
108 |
109 | def push(self, value):
110 | """向栈中压入元素"""
111 | self._head = SinglyLinkedNode(value, self._head) # 构造链表对象
112 | self._size += 1
113 |
114 | def top(self):
115 | """查询栈顶元素"""
116 | if self.is_empty():
117 | raise ValueError("Stack is Empty")
118 | return self._head.value
119 |
120 | def pop(self):
121 | """取出栈顶元素"""
122 | if self.is_empty():
123 | raise ValueError("Stack is Empty")
124 | ans = self._head.value
125 | self._head = self._head.next
126 | self._size -= 1
127 | return ans
128 | ```
--------------------------------------------------------------------------------
/Stack/Stack.py:
--------------------------------------------------------------------------------
1 | class Stack:
2 | """栈的结构定义"""
3 |
4 | def __init__(self):
5 | """初始化一个空栈"""
6 | pass
7 |
8 | def __len__(self):
9 | """返回栈内元素数量"""
10 | pass
11 |
12 | def is_empty(self):
13 | """返回栈是否为空栈"""
14 | pass
15 |
16 | def clear(self):
17 | """清空栈"""
18 | pass
19 |
20 | def top(self):
21 | """若栈存在且非空,则返回栈顶元素"""
22 | pass
23 |
24 | def push(self, value):
25 | """若栈存在,则插入新元素value到栈中并成为栈顶元素"""
26 | pass
27 |
28 | def pop(self):
29 | """若栈存在,则删除栈顶元素并返回其值"""
30 | pass
31 |
--------------------------------------------------------------------------------
/String/KMPMatch.py:
--------------------------------------------------------------------------------
1 | def get_next(t):
2 | """通过计算返回子串t的next数组"""
3 | i = 0
4 | j = -1
5 | next = [-1] * len(t)
6 | while i < len(t) - 1:
7 | if j == -1 or t[i] == t[j]:
8 | i += 1
9 | j += 1
10 | next[i] = j
11 | else:
12 | j = next[j] # 若字符不相同,则j值回溯
13 | return next
14 |
15 |
16 | def index_kmp(s: str, t: str, pos: int):
17 | """KMP模式匹配算法"""
18 | i = pos # i用于主串s中当前位置下标,若pos不为1则从pos位置开始匹配
19 | j = 0 # j用于子串t中当前位置下标值
20 | next = get_next(t)
21 | while i < len(s) and j < len(t):
22 | if j == -1 or s[i] == t[j]:
23 | i += 1
24 | j += 1
25 | else:
26 | j = next[j]
27 | if j >= len(t):
28 | return i - len(t)
29 | else:
30 | return -1
31 |
32 |
33 | def get_next_val(t):
34 | """通过计算返回子串t的next数组(改进算法)"""
35 | i = 0
36 | j = -1
37 | next = [-1] * len(t)
38 | while i < len(t) - 1:
39 | if j == -1 or t[i] == t[j]:
40 | i += 1
41 | j += 1
42 | if t[i] != t[j]:
43 | next[i] = j
44 | else:
45 | next[i] = next[j]
46 | else:
47 | j = next[j] # 若字符不相同,则j值回溯
48 | return next
49 |
50 |
51 | def index_kmp_mend(s: str, t: str, pos: int):
52 | """KMP模式匹配算法(改进算法)"""
53 | i = pos # i用于主串s中当前位置下标,若pos不为1则从pos位置开始匹配
54 | j = 0 # j用于子串t中当前位置下标值
55 | next = get_next_val(t)
56 | while i < len(s) and j < len(t):
57 | if j == -1 or s[i] == t[j]:
58 | i += 1
59 | j += 1
60 | else:
61 | j = next[j]
62 | if j >= len(t):
63 | return i - len(t)
64 | else:
65 | return -1
66 |
67 |
68 | if __name__ == "__main__":
69 | print(get_next("abcdex")) # [-1, 0, 0, 0, 0, 0]
70 | print(get_next("abcabx")) # [-1, 0, 0, 0, 1, 2]
71 | print(get_next("ababaaaba")) # [-1, 0, 0, 1, 2, 3, 1, 1, 2]
72 | print(get_next("aaaaaaaab")) # [-1, 0, 1, 2, 3, 4, 5, 6, 7]
73 | print(index_kmp("abcdefgab", "abcdex", 0)) # -1
74 | print(index_kmp("abcabfgab", "abcabx", 0)) # -1
75 |
76 | print(get_next_val("ababaaaba")) # [-1, 0, -1, 0, -1, 3, 1, 0, -1]
77 | print(get_next_val("aaaaaaaab")) # [-1, -1, -1, -1, -1, -1, -1, -1, 7]
78 |
79 | print(index_kmp_mend("abcdefgab", "abcdex", 0)) # -1
80 | print(index_kmp_mend("abcabfgab", "abcabx", 0)) # -1
81 |
--------------------------------------------------------------------------------
/String/README.md:
--------------------------------------------------------------------------------
1 | ## 串的抽象数据类型
2 |
3 | ```python
4 | def str_assign(chars: List[str]):
5 | """生成一个其值等于字符串常量chars的串"""
6 | return "".join(chars)
7 |
8 |
9 | def str_copy(s: str):
10 | """由串s复制得串t"""
11 | return copy.deepcopy(s)
12 |
13 |
14 | def string_empty(s: str):
15 | """若串s为空,则返回True,否则返回False"""
16 | return not s
17 |
18 |
19 | def str_length(s: str):
20 | """返回串s的元素个数,即串的长度"""
21 | return len(s)
22 |
23 |
24 | def concat(s1: str, s2: str):
25 | """返回s1和s2联接而成的新串"""
26 | return s1 + s2
27 |
28 |
29 | def sub_string(s: str, pos: int, length: int):
30 | """返回串s的第pos个字符起长度为length的子串"""
31 | if 0 <= pos <= pos + length <= len(s):
32 | return s[pos: length]
33 |
34 |
35 | def index(s: str, t: str, pos):
36 | """若主串s中存在和串t值相同的子串,则返回它在主串s中第pos个字符之后第一次出现的位置,否则返回0"""
37 | if 0 <= pos < len(s):
38 | if t in s[pos:]:
39 | return s[pos:].index(t)
40 | return 0
41 |
42 |
43 | def replace(s: str, t: str, v: str):
44 | """用V替换主串s中出现的所有与t相等的不重叠的子串"""
45 | return s.replace(t, v)
46 |
47 |
48 | def str_insert(s: str, pos: int, t: str):
49 | """在串s的第pos个字符之前插入串t"""
50 | if 0 <= pos <= len(s):
51 | return s[:pos] + t + s[pos:]
52 |
53 |
54 | def str_delete(s: str, pos: int, length: int):
55 | """在传s中删除第pos个字符起长度为length的子串"""
56 | if 0 <= pos <= pos + length <= len(s):
57 | return s[:pos] + s[pos + length:]
58 | ```
59 |
60 | ## 朴素的模式匹配算法
61 |
62 | > 时间复杂度:O(N×M),其中N为字符串s的长度,M为字符串t的长度
63 |
64 | ```python
65 | def index_simple(s: str, t: str, pos: int):
66 | """朴素的模式匹配算法"""
67 | i = pos # i用于主串s中当前位置下标,若pos不为1则从pos位置开始匹配
68 | j = 0 # j用于子串t中当前位置下标值
69 | while i < len(s) and j < len(t):
70 | if s[i] == t[j]:
71 | i += 1
72 | j += 1
73 | else:
74 | i = i - j + 1
75 | j = 0
76 | if j >= len(t):
77 | return i - len(t)
78 | else:
79 | return -1
80 |
81 |
82 | def index_simple_2(s: str, t: str, pos: int):
83 | """朴素的模式匹配算法"""
84 | while pos + len(t) <= len(s):
85 | if s[pos:pos + len(t)] == t:
86 | return pos
87 | pos += 1
88 | else:
89 | return -1
90 | ```
91 |
92 | ## KMP模式匹配算法
93 |
94 | > 时间复杂度:O(N+M),其中N为字符串s的长度,M为字符串t的长度
95 |
96 | ```python
97 | def get_next(t):
98 | """通过计算返回子串t的next数组"""
99 | i = 0
100 | j = -1
101 | next = [-1] * len(t)
102 | while i < len(t) - 1:
103 | if j == -1 or t[i] == t[j]:
104 | i += 1
105 | j += 1
106 | next[i] = j
107 | else:
108 | j = next[j] # 若字符不相同,则j值回溯
109 | return next
110 |
111 |
112 | def index_kmp(s: str, t: str, pos: int):
113 | """KMP模式匹配算法"""
114 | i = pos # i用于主串s中当前位置下标,若pos不为1则从pos位置开始匹配
115 | j = 0 # j用于子串t中当前位置下标值
116 | next = get_next(t)
117 | while i < len(s) and j < len(t):
118 | if j == -1 or s[i] == t[j]:
119 | i += 1
120 | j += 1
121 | else:
122 | j = next[j]
123 | if j >= len(t):
124 | return i - len(t)
125 | else:
126 | return -1
127 |
128 |
129 | def get_next_val(t):
130 | """通过计算返回子串t的next数组(改进算法)"""
131 | i = 0
132 | j = -1
133 | next = [-1] * len(t)
134 | while i < len(t) - 1:
135 | if j == -1 or t[i] == t[j]:
136 | i += 1
137 | j += 1
138 | if t[i] != t[j]:
139 | next[i] = j
140 | else:
141 | next[i] = next[j]
142 | else:
143 | j = next[j] # 若字符不相同,则j值回溯
144 | return next
145 |
146 |
147 | def index_kmp_mend(s: str, t: str, pos: int):
148 | """KMP模式匹配算法(改进算法)"""
149 | i = pos # i用于主串s中当前位置下标,若pos不为1则从pos位置开始匹配
150 | j = 0 # j用于子串t中当前位置下标值
151 | next = get_next_val(t)
152 | while i < len(s) and j < len(t):
153 | if j == -1 or s[i] == t[j]:
154 | i += 1
155 | j += 1
156 | else:
157 | j = next[j]
158 | if j >= len(t):
159 | return i - len(t)
160 | else:
161 | return -1
162 | ```
--------------------------------------------------------------------------------
/String/SimpleMatch.py:
--------------------------------------------------------------------------------
1 | def index_simple(s: str, t: str, pos: int):
2 | """朴素的模式匹配算法"""
3 | i = pos # i用于主串s中当前位置下标,若pos不为1则从pos位置开始匹配
4 | j = 0 # j用于子串t中当前位置下标值
5 | while i < len(s) and j < len(t):
6 | if s[i] == t[j]:
7 | i += 1
8 | j += 1
9 | else:
10 | i = i - j + 1
11 | j = 0
12 | if j >= len(t):
13 | return i - len(t)
14 | else:
15 | return -1
16 |
17 |
18 | def index_simple_2(s: str, t: str, pos: int):
19 | """朴素的模式匹配算法"""
20 | while pos + len(t) <= len(s):
21 | if s[pos:pos + len(t)] == t:
22 | return pos
23 | pos += 1
24 | else:
25 | return -1
26 |
--------------------------------------------------------------------------------
/String/String.py:
--------------------------------------------------------------------------------
1 | import copy
2 | from typing import List
3 |
4 |
5 | def str_assign(chars: List[str]):
6 | """生成一个其值等于字符串常量chars的串"""
7 | return "".join(chars)
8 |
9 |
10 | def str_copy(s: str):
11 | """由串s复制得串t"""
12 | return copy.deepcopy(s)
13 |
14 |
15 | def string_empty(s: str):
16 | """若串s为空,则返回True,否则返回False"""
17 | return not s
18 |
19 |
20 | def str_length(s: str):
21 | """返回串s的元素个数,即串的长度"""
22 | return len(s)
23 |
24 |
25 | def concat(s1: str, s2: str):
26 | """返回s1和s2联接而成的新串"""
27 | return s1 + s2
28 |
29 |
30 | def sub_string(s: str, pos: int, length: int):
31 | """返回串s的第pos个字符起长度为length的子串"""
32 | if 0 <= pos <= pos + length <= len(s):
33 | return s[pos: length]
34 |
35 |
36 | def index(s: str, t: str, pos):
37 | """若主串s中存在和串t值相同的子串,则返回它在主串s中第pos个字符之后第一次出现的位置,否则返回0"""
38 | if 0 <= pos < len(s):
39 | if t in s[pos:]:
40 | return s[pos:].index(t)
41 | return 0
42 |
43 |
44 | def replace(s: str, t: str, v: str):
45 | """用V替换主串s中出现的所有与t相等的不重叠的子串"""
46 | return s.replace(t, v)
47 |
48 |
49 | def str_insert(s: str, pos: int, t: str):
50 | """在串s的第pos个字符之前插入串t"""
51 | if 0 <= pos <= len(s):
52 | return s[:pos] + t + s[pos:]
53 |
54 |
55 | def str_delete(s: str, pos: int, length: int):
56 | """在传s中删除第pos个字符起长度为length的子串"""
57 | if 0 <= pos <= pos + length <= len(s):
58 | return s[:pos] + s[pos + length:]
59 |
--------------------------------------------------------------------------------