常见数据结构有线性表(数组与链表),栈与队列,树与二叉树,图。
1.线性表
线性表是最常用且最简单的一种数据结构,它是数据元素的有限序列。线性表有两种实现形式,第一种是用一组连续的存储单元依次存储线性表的数据元素,使用数组存储线性表的元素,也就是python里面的List。第二种就是用一组任意的存储单元存储线性表的数据元素,使用链表存储线性表的元素,这里存储单元可以连续,也可以不连续,也就是python里面的LinkedList。
http://www.runoob.com/python3/python3-list.html 这个链接里面有python3 list的常见操作。
上面是数组,下面是链表。
# LinkList单链表
class Node(object):
def __init__(self, data, next):
self.data = data
self.next = next
class LinkList(object):
def __init__(self):
self.root = None
# 给单链表添加元素节点
def addNode(self, data):
if self.root is None:
self.root = Node(data=data, next=None)
return self.root
else:
# 有头结点,则需要遍历到尾部节点,进行链表增加操作
curr = self.root
while curr.next is not None:
curr = curr.next
curr.next = Node(data=data, next=None)
return self.root
# 在链表的尾部添加新节点,底层调用addNode方法即可
def append(self, value):
self.addNode(data=value)
# 在链表首部添加节点
def preAppend(self, value):
if self.root is None:
self.root = Node(value, None)
else:
newRoot = Node(value, None)
# 更新root索引
newRoot.next = self.root
self.root = newRoot
# 在链表的指定位置添加节点
def insert(self, index, value):
if self.root is None:
return
if index<= 0 or index >self.size():
print('index %d 非法,应该审视一下您的插入节点在整个链表的位置!')
return
elif index == 1:
# 如果index == 1,则在链表首部添加即可
self.preAppend(value)
elif index == self.size() + 1:
# 如果index正好比当前链表长度大一,则添加在尾部即可
self.append(value)
else:
# 如此,在链表中部添加新节点,直接进行添加即可。需要使用计数器来维护插入未知
counter = 2
pre = self.root
cursor = self.root.next
while cursor is not None:
if counter == index:
temp = Node(value, None)
pre.next = temp
temp.next = cursor
break
else:
counter += 1
pre = cursor
cursor = cursor.next
# 删除指定位置上的节点
def delNode(self, index):
if self.root is None:
return
if index <= 0 or index > self.size():
print('index %d 非法,应该审视一下您的删除节点在整个链表的位置!')
return
# 对第一个位置需要小心处理
if index == 1:
self.root = self.root.next
else:
pre = self.root
cursor = pre.next
counter = 2
while cursor is not None:
if index == counter:
print('can be here!')
pre.next = cursor.next
break
else:
pre = cursor
cursor = cursor.next
counter += 1
# 删除值为value的链表节点元素
def delValue(self, value):
if self.root is None:
return
# 对第一个位置需要小心处理
if self.root.data == value:
self.root = self.root.next
else:
pre = self.root
cursor = pre.next
while cursor is not None:
if cursor.data == value:
pre.next = cursor.next
# 千万记得更新这个节点,否则会出现死循环。
cursor = cursor.next
continue
else:
pre = cursor
cursor = cursor.next
# 判断链表是否为空
def isEmpty(self):
if self.root is None or self.size() == 0:
return True
else:
return False
# 删除链表及其内部所有元素
def truncate(self):
if self.root is None or self.size() == 0:
return
else:
cursor = self.root
while cursor is not None:
cursor.data = None
cursor = cursor.next
self.root = None
cursor = None
# 获取指定位置的节点的值
def getValue(self, index):
if self.root is None or self.size() == 0:
print('当前链表为空!')
return None
if index <= 0 or index > self.size():
print('index %d不合法!'%index)
return None
else:
counter = 1
cursor = self.root
while cursor is not None:
if index == counter:
return cursor.data
else:
counter += 1
cursor = cursor.next
# 获取链表尾部的值,且不删除该尾部节点
def peek(self):
return self.getValue(self.size())
# 获取链表尾部节点的值,并删除该尾部节点
def pop(self):
if self.root is None or self.size() == 0:
print('当前链表已经为空!')
return None
elif self.size() == 1:
top = self.root.data
self.root = None
return top
else:
pre = self.root
cursor = pre.next
while cursor.next is not None:
pre = cursor
cursor = cursor.next
top = cursor.data
cursor = None
pre.next = None
return top
# 单链表逆序实现
def reverse(self):
if self.root is None or self.size() == 1:
return
else:
pre = None
cursor = self.root
while cursor is not None:
# print('逆序操作')
post = cursor.next
cursor.next = pre
pre = cursor
cursor = post
# 千万不要忘记把逆序后的头结点赋值给root,否则无法正确显示
self.root = pre
# 删除链表中的重复元素
def delDuplecate(self):
# 使用一个map来存放即可,类似于变形的'桶排序'
dic = {}
if self.root is None:
return
if self.size() == 1:
return
pre = self.root
cursor = pre.next
# 为字典赋值
temp = self.root
while temp is not None:
dic[str(temp.data)] = 0
temp = temp.next
temp = None
# 开始实施删除重复元素的操作
while cursor is not None:
if dic[str(cursor.data)] == 1:
pre.next = cursor.next
cursor = cursor.next
else:
dic[str(cursor.data)] += 1
pre = cursor
cursor = cursor.next
# 修改指定位置节点的值
def updateNode(self, index, value):
if self.root is None:
return
if index < 0 or index > self.size():
return
if index == 1:
self.root.data = value
return
else:
counter = 2
cursor = self.root.next
while cursor is not None:
if counter == index:
cursor.data = value
break
cursor = cursor.next
counter += 1
# 获取单链表的大小
def size(self):
counter = 0
if self.root is None:
return counter
else:
cursor = self.root
while cursor is not None:
counter += 1
cursor = cursor.next
return counter
# 打印链表自身元素
def print(self):
if self.root is None:
return
else:
cursor = self.root
while cursor is not None:
print(cursor.data, end='\t')
cursor = cursor.next
print()
if __name__ == '__main__':
# 创建一个链表对象
array = LinkList()
# 判断当前链表是否为空
print("链表为空{}".format(array.isEmpty()))
# 判断当前链表是否为空
array.addNode(1)
print("链表为空{}".format(array.isEmpty()))
# 添加一些节点,方便操作
array.addNode(2)
array.addNode(3)
array.addNode(4)
array.addNode(6)
array.addNode(5)
array.addNode(6)
array.addNode(7)
array.addNode(3)
# 打印当前链表所有值
print('打印当前链表所有值')
array.print()
# 测试对链表求size的操作
print("链表的size: " + str(array.size()))
# 测试指定位置节点值的获取
print('测试指定位置节点值的获取')
print(array.getValue(1))
print(array.getValue(array.size()))
print(array.getValue(7))
# 测试删除链表中指定值,可重复性删除
print('测试删除链表中指定值,可重复性删除')
array.delNode(4)
array.print()
array.delNode(3)
array.print()
# 去除链表中的重复元素
print('去除链表中的重复元素')
array.delDuplecate()
array.print()
# 指定位置的链表元素的更新测试
print('指定位置的链表元素的更新测试')
array.updateNode(6, 99)
array.print()
# 测试在链表首部添加节点
print('测试在链表首部添加节点')
array.preAppend(77)
array.preAppend(108)
array.print()
# 测试在链表尾部添加节点
print('测试在链表尾部添加节点')
array.append(99)
array.append(100)
array.print()
# 测试指定下标的插入操作
print('测试指定下标的插入操作')
array.insert(1, 10010)
array.insert(3, 333)
array.insert(array.size(), 99999)
array.print()
# 测试peek 操作
print('测试peek 操作')
print(array.peek())
array.print()
# 测试pop 操作
print('测试pop 操作')
print(array.pop())
array.print()
# 测试单链表的逆序输出
print('测试单链表的逆序输出')
array.reverse()
array.print()
# 测试链表的truncate操作
print('测试链表的truncate操作')
array.truncate()
array.print()
下面是单向循环链表,至于双向链表和双向循环链表以后有时间再补上吧。
# sinCycLinkedList 单向循环链表
class Node(object):
"""节点"""
def __init__(self, item):
self.item = item
self.next = None
class SinCycLinkedlist(object):
"""单向循环链表"""
def __init__(self):
self._head = None
def is_empty(self):
"""判断链表是否为空"""
return self._head == None
def length(self):
"""返回链表的长度"""
# 如果链表为空,返回长度0
if self.is_empty():
return 0
count = 1
cur = self._head
while cur.next != self._head:
count += 1
cur = cur.next
return count
def travel(self):
"""遍历链表"""
if self.is_empty():
return
cur = self._head
print(cur.item,)
while cur.next != self._head:
cur = cur.next
print(cur.item,)
print("")
def add(self, item):
"""头部添加节点"""
node = Node(item)
if self.is_empty():
self._head = node
node.next = self._head
else:
#添加的节点指向_head
node.next = self._head
# 移到链表尾部,将尾部节点的next指向node
cur = self._head
while cur.next != self._head:
cur = cur.next
cur.next = node
#_head指向添加node的
self._head = node
def append(self, item):
"""尾部添加节点"""
node = Node(item)
if self.is_empty():
self._head = node
node.next = self._head
else:
# 移到链表尾部
cur = self._head
while cur.next != self._head:
cur = cur.next
# 将尾节点指向node
cur.next = node
# 将node指向头节点_head
node.next = self._head
def insert(self, pos, item):
"""在指定位置添加节点"""
if pos <= 0:
self.add(item)
elif pos > (self.length()-1):
self.append(item)
else:
node = Node(item)
cur = self._head
count = 0
# 移动到指定位置的前一个位置
while count < (pos-1):
count += 1
cur = cur.next
node.next = cur.next
cur.next = node
def remove(self, item):
"""删除一个节点"""
# 若链表为空,则直接返回
if self.is_empty():
return
# 将cur指向头节点
cur = self._head
pre = None
# 若头节点的元素就是要查找的元素item
if cur.item == item:
# 如果链表不止一个节点
if cur.next != self._head:
# 先找到尾节点,将尾节点的next指向第二个节点
while cur.next != self._head:
cur = cur.next
# cur指向了尾节点
cur.next = self._head.next
self._head = self._head.next
else:
# 链表只有一个节点
self._head = None
else:
pre = self._head
# 第一个节点不是要删除的
while cur.next != self._head:
# 找到了要删除的元素
if cur.item == item:
# 删除
pre.next = cur.next
return
else:
pre = cur
cur = cur.next
# cur 指向尾节点
if cur.item == item:
# 尾部删除
pre.next = cur.next
def search(self, item):
"""查找节点是否存在"""
if self.is_empty():
return False
cur = self._head
if cur.item == item:
return True
while cur.next != self._head:
cur = cur.next
if cur.item == item:
return True
return False
if __name__ == "__main__":
ll = SinCycLinkedlist()
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(7))
ll.remove(1)
print("length:",ll.length())
ll.travel()
下一篇我会具体讲一讲数据结构中的栈与队列。