数据结构之无序表
可以使用链表实现;
要求保持数据项的前后相对位置,但并不要求数据项依次存放在连续的存储空间;
如果在数据项之间建立链接指向,就可以保持数据项的前后相对位置;
第一个数据和最后一个数据要标记出来;
链表实现的最基本元素为节点Node,每个节点至少包含两个信息:数据项本身,指向下一个节点的引用信息,当下一个节点为None时,表示此节点为列表的尾端,之后无数据;
class Node():
def __init__(self,initdata):
self.data = initdata
self.next = None
def getData(self):
return self.data
def getNext(self):
return self.next
def setData(self,newdata):
self.data = newdata
def setNext(self,newnext):
self.next = newnext
采用链接节点的方式构建数据集从而实现无序表;
链表的第一个和最后一个节点非常重要,如果想访问链表中所有节点,必须从第一个节点开始沿着链接遍历下去,故链表必须要有对第一个节点的引用信息,设立一个属性head,保存对第一个节点的引用信息,随着数据项的加入,head始终指向链表中的第一个节点;
1.add(item)方法
无序表不指定数据项加入的位置,因此按照性能考虑,应添加到最容易加入的位置,
也就是表头,故每次加入新的数据项之后,原来的表头即变为此数据项的下一项,此数据项变为表头;
2.size()方法
判断链表中数据项的个数,从链表头开始遍历至链表尾同时用变量累加经过的节点数;无数据项时链表长度为0;
3.search(item)方法
从链表头开始遍历到表尾,同时判断当前节点数据是否为要寻找的目标;
4.remove(item)方法
首先和search()方法的过程一样,首先遍历链表找到item,如果current节点为要删除的item节点,那么就需要把前一个节点的next指向current的下一个节点,故在search current 的同时,还有维护上一个(previous)节点的引用;另外,找到item之后,current指向item节点,previous指向前一个节点,在执行删除的时候,有两种情况:current为表头、或者位于链条中间的节点;
如果current为表头,那么current的下一个节点要更新变为表头;
如果位于链条中间,那么previous节点的next指向current节点的next节点;
5.append(item)方法
默认将数据项添加至链表尾端,要先将current定位到链表尾端,使用一个计数器count实现,首先将item转换Node的一个对象temp,当current定位到尾端之后,将current的next指向temp即可;
6.index(item)方法
返回指定数据项的索引,需要从head开始遍历,有一个变量count来记录索引,和search()相似,当找到item对应的数据项之后,输出索引即可;如果item不存在,即count等于链表的长度,则返回False;
5.insert(pos,item)方法
在指定位置插入item,需要从head开始遍历,使用一个变量count来计算,当count=pos时,停止遍历,current指向链表pos处的数据项,此时需要:首先将item转换为Node的一个对象temp,然后将current节点之前的节点previous的next更新为temp,然后将temp的next指向current节点;还需要判断pos是否为0,如果为0,那么就是在链表首端插入temp,此时的操作和add(item)方法相同;
6.pop()方法
默认弹出链表尾端的数据项,故需要从head遍历至尾端,当current定位到尾端之后,previous为倒数二个数据项,将previous的next更新为None即将current删除,返回cuurent指向的数据项;需要判断链表的大小是否为1,如果为1,弹出之后链表为空,将head更新为None即可;
7.pop(pos)方法
弹出指定位置的数据项,需要从head遍历至指定位置,需要一个变量来计数完成定位,当current定位到pos对应的节点时,需要将current之前的节点previous的next指向current节点的next;如果pos = 0,并且链表长度为1,表示弹出链表首端,且之后链表为空,需要将head置为None;如果pos=0,但链表长度大于1,则只需将head更新为current的next即可;
from Node import Node
class UnorderList():
def __init__(self):
self.head = None
def add(self,item):
temp = Node(item)
temp.setNext(self.head)
self.head = temp
def search(self,item):
current = self.head
found = False
while current!= None and not found:
if current.getData() == item:
found = True
else:
current = current.getNext()
return found
def remove(self,item):
current = self.head
previous = None
found = False
while not found:
if current.getData() == item:
found = True
else:
previous = current
current = current.getNext()
if previous == None:
self.head = current.getNext()
else:
previous.setNext(current.getNext())
def size(self):
current = self.head
count = 0
while current != None:
count += 1
current = current.getNext()
return count
def isEmpty(self):
return self.size() == 0
def append(self,item):
current = self.head
temp = Node(item)
count = 0
while count < self.size()-1:
current = current.getNext()
count += 1
current.setNext(temp)
def index(self,item):
current = self.head
find = False
count = 0
while not find and current!= None:
if current.getData() == item:
find = True
else:
current = current.getNext()
count += 1
if count == self.size() and not find:
return False
return count
def insert(self,pos,item):
current = self.head
previous = None
count = 0
while count < pos:
previous = current
current = current.getNext()
count +=1
if pos == 0:
self.add(item)
else:
temp = Node(item)
temp.setNext(current)
previous.setNext(temp)
def pop(self):
current = self.head
previous = None
count = 0
while count < self.size()-1:
previous = current
current = current.getNext()
count += 1
if self.size() == 1:
self.head = None
return current.getData()
else:
previous.setNext(None)
return current.getData()
def pop(self,pos):
current = self.head
previous = None
count = 0
if pos == 0:
self.head = current.getNext()
return current.getData()
while count < pos and current != None:
previous = current
current = current.getNext()
count += 1
previous.setNext(current.getNext())
return current.getData()