一.什么是线性表
线性表是最基本、最简单、也是最常用的一种数据结构,它的定义是:由零个或多个数据元素组成的有限序列,线性表中数据元素之间的关系是一对一的关系,即除了第一个和最后一个数据元素之外,其它数据元素都是首尾相接的(注意,这句话只适用大部分线性表,而不是全部。比如,循环链表逻辑层次上也是一种线性表(存储层次上属于链式存储),但是把最后一个数据元素的尾指针指向了首位结点)。
线性表的两种物理结构:顺序存储结构和链式存储结构
1.顺序存储结构
定义:用一段地址连续的存储单元依次存储线性表的数据元素
顺序表的优点与缺点
优点:可以快速的存取访问表中的元素
缺点:插入和删除麻烦,需要移动大量的数据,容易造成存储空间碎片
顺序表的实现
#顺序表的实现
class SeqList(object):
def __init__(self,max=10):
self.max = max
self.num = 0
self.data = [None] * self.max
def isEmpty(self):
return self.num is 0
def isFull(self):
return self.num is self.max
def __getitem__(self,i):
if not isinstance(i,int):
raise TypeError
if 0 <= i < self.num:
return self.data[i]
else:
raise IndexError
def __setitem__(self,key,value):
if not isinstance(key,int):
raise TypeError
if 0 <= key < self.num:
self.data[key] = value
else:
raise IndexError
def getLoc(self,value):
n = 0
for j in range(self.num):
if self.data[j] == value:
return j
if j == self.num:
return -1
def count(self):
return self.num
def append(self,value):
if self.num > self.max:
print('The list is full')
else:
self.data[self.num] = value
self.num += 1
def insert(self,i,value):
if not isinstance(i,int):
raise TypeError
if i < 0 and i > self.num:
raise IndexError
for j in range(self.num,i,-1):
self.data[j] = self.data[j-1]
self.data[i] = value
self.num += 1
def remove(self,i):
if not isinstance(i,int):
raise TypeError
if i < 0 and i >= self.num:
raise IndexError
for j in range(i,self.num):
self.data[j] = self.data[j+1]
self.num -= 1
def printList(self):
for i in range(0,self.num):
print(self.data[i])
def destory(self):
self.__init__()
2.链式存储结构
定义:链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域,最后一个节点指针为空(Null)

链表的优点:插入和删除方便,不需要移动大量的数据,使用于插入和删除频繁的操作
链表的缺点:查找十分麻烦,每次查找都需要遍历链表
单链表(动态链表)的实现:
#链表的实现 class ListNode(object): def __init__(self,data): self.data = data self.next = None def getData(self): return self.data def setData(self,newData): self.data = newData def getNext(self): return self.next def setNext(self,nextNode): self.next = nextNode class UnorderedList(object): def __init__(self): self.head = None def getHead(self): return self.head def isEmpty(self): return self.head is None def add(self,item): node = ListNode(item) node.next = self.head self.head = node def size(self): current = self.head count = 0 while current is not None: count += 1 current = current.getNext return count def search(self,item): current = self.head found = False while current is not None and not found: if current.getData() == item: found = True else: current = current.getNext() return found def append(self,item): node = ListNode(item) if self.isEmpty(): self.head = node else: current = self.head while current.getNext() is not None: current = current.getNext() current.setNext(node) def remove(self,item): current = self.head privious = None found = False while not found: if current.getData() == item: found = True else: privious = current current = current.getNext() if privious is None: self.head = current.getNext() else: privious.setNext(current.getNext()) def getValue(self): current = self.head currarr = [] while current != None: currarr.append(current.getData()) current = current.getNext() return currarr
静态链表:用数组描述的链表
定义:对于线性链表,也可用一维数组来进行描述。第一个下标和最后一个下标不存放任何数据,第一个游标指向第一个没有数据的下标,最后一个游标指向第一个有数据的下标,最后一个有数据的游标指向0
优点:这种存储结构,仍需要预先分配一个较大的空间,但在作为线性表的插入和删除操作时不需移动元素,仅需修改指针(游标),故仍具有链式存储结构的主要优点
缺点:表长难以确定,失去了顺序存储结构随机存储的特性
下图为静态链表的插入操作:

循环链表
定义:循环链表是另一种形式的链式存贮结构。它的特点是表中最后一个结点的指针域指向头结点,整个链表形成一个环

循环链表的特点:
1.循环链表中没有NULL指针。涉及遍历操作时,其终止条件就不再是像非循环链表那样判别p或p->next是否为空,而是判别它们是否等于某一指定指针,如头指针或尾指针
2.在单链表中,从一已知结点出发,只能访问到该结点及其后续结点,无法找到该结点之前的其它结点。而在单循环链表中,从任一结点出发都可访问到表中所有结点,这一优点使某些运算在单循环链表上易于实现
循环链表的实现:
class Node(object):
def __init__(self,item):
self.item = item
self.next = None
class CycleSingleLinkList(object):
def __init__(self,node=None):
self.head = node
def isEmpty(self):
return self.head is None
def length(self):
if self.isEmpty():
return 0
current = self.head
count = 1
while current.next != self.head:
count += 1
current = current.next
return count
def travel(self):
if self.isEmpty():
print("")
return
current = self.head
while current.next != self.head:
print(current.item,end="")
current = current.next
print(current.item,end="")
print("")
def add(self,item):
node = Node(item)
if self.isEmpty():
node.next = node
self.head = node
else:
current = self.head
while current.next != self.head:
current = current.next
node.next = self.head
self.head = node
current.next = node
def append(self,item):
node = Node(item)
if self.isEmpty():
self.head = node
node.next = self.head
else:
current = self.head
while current.next != self.head:
current = current.next
current.next = node
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)
current = self.head
count = 0
while count < (pos - 1):
count += 1
current = current.next
node.next = current.next
current.next = node
def remove(self,item):
if self.isEmpty():
return
current = self.head
pre = None
if current.item == item:
if current.next != self.head:
while current.next != self.head:
current = current.next
current.next = self.head.next
self.head = self.head.next
else:
self.head = None
else:
pre = self.head
while current.next != self.head:
if current.item == item:
pre.next = current.next
return
else:
pre = current
current = current.next
if current.item == item:
pre.next = current.next
def search(self,item):
if self.isEmpty():
return False
current = self.head
if current.item == item:
return true
while current.next != self.head:
current = current.next
if current.item == item:
return True
return False
if __name__ == '__main__':
l = CycleSingleLinkList()
l.append(1)
l.append(2)
l.append(3)
l.add(4)
l.insert(2,5)
l.remove(5)
print(l.search(5))
print(l.length())
l.travel()
双向链表
定义:双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。一般我们都构造双向循环链表
双向链表实现:
#双向循环链表 class Node(object): def __init__(self,data=None): self.data = data self.next = None self.prev = None class dblLinkList(object): def __init__(self): head = Node() tail = Node() self.head = head self.tail = tail self.head.next = self.tail self.tail.pre = self.head def len(self): length = 0 node = self.head while node.next != self.tail: length += 1 node = node.next return length def append(self,data): node = Node(data) pre = self.tail.pre pre.next = node node.pre = pre self.tail.pre = node node.next = self.tail return node def get(self,index): length = self.len() index = index if index >= 0 else length + index if index >= length or index < 0:return None node = self.head.next while index: node = node.next index -= 1 return node.data def set(self,index,data): node = self.get(index) if node: node.data = data return node def insert(self,index,data): length = self.len() if abs(index + 1) > length: return False index = index if index >= 0 else index + 1 + length next_node = self.get(index) if next_node: node = Node(data) pre_node = next_node.pre pre_node.next = node node.pre = pre_node node.next = next_node next_node.pre = node return node def delete(self,index): node = self.get(index) if node: node.pre.next = node.next node.pre.pre = node.pre return True return False def clear(self): self.head.next = self.tail self.tail.pre = self.head if __name__ == '__main__': l = dblLinkList() l.append(111) l.append(222) l.append(333) print(l.get(0)) print(l.get(1)) print(l.get(2))