本文为学习笔记,感兴趣的读者可在MOOC中搜索《数据结构与算法Python版》或阅读《数据结构(C语言版)》(严蔚敏)
目录链接:https://blog.csdn.net/floating_heart/article/details/123991211
1.4 无序表UnorderedList
无序表与有序表是相对的。有序、无序是有序表就是指逻辑意义上的,有序表即表中的元素按某种规则已经排好了位置是,有一定顺序排列的,准确定义为:表中所有元素以递增或递减方式排列,并规定有序表中可存在元素值相同的元素。无序表就是数据的排列不具有顺序性。
一种数据项按照相对位置存放的数据集,被称为“无序表unordered list”其中数据项只按照存放位置来索引,如第1个、第2个……、最后一个等。
如一个考试分数的集合“54, 26, 93, 17, 77, 31”
如果用无序表来表示,就是[54, 26, 93, 17, 77, 31]
如果用有序表来表示,可能是[17, 26, 31, 54, 77, 93]
UnorderedList定义的操作
**List():**创建一个空列表
**add(item):**添加一个数据项到列表中,假设item原先不存在于列表中
**remove(item):**从列表中移除item,列表被修改,item原先应存在于表中
**search(item):**在列表中查找item,返回布尔类型值
**isEmpty():**返回列表是否为空
**size():**返回列表包含了多少数据项
**append(item):**添加一个数据项到表末尾,假设item原先不存在于列表中
**index(item):**返回数据项在表中的位置
**insert(pos, item):**将数据项插入到位置pos,假设item原先不存在与列表中,同时原列表具有足够多个数据项,能让item占据位置pos
**pop():**从列表末尾移除数据项,假设原列表至少有1个数据项
**pop(pos):**移除位置为pos的数据项,假设原列表存在位置pos
实现
采用链表的方案实现
列表数据结构要求保持数据项的前后相对位置,但这种前后位置的保持,并不要求数据项依次存放在连续的存储空间。
如下图,数据项存放位置并没有规则,但如果在数据项之间建立链接指向,就可以保持其前后相对位置
第一个和最后一个数据项需要显式标记出来,一个是队首,一个是队尾,后面再无数据了。
链表实现的最基本元素是节点Node
每个节点至少要包含2个信息:
数据项本身,以及指向下一个节点的引用信息
注意next为None(null)的意义是没有下一个节点了,这个很重要
采用链接节点的方式构建数据集来实现无序表
链表的第一个和最后一个节点最重要。如果想访问到链表中的所有节点,就必须从第一个节点开始沿着链接遍历下去。
所以无序表必须要有对第一个节点的引用信息。
随着数据项的加入,无序表的head始终指向链条中的第一个节点。
代码:Python
# 定义节点Node
class Node:
def __init__(self,initdata) -> None:
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
# 定义无序表UnorderedList
class UnorderedList:
def __init__(self) -> None:
# 设立一个属性head, 保存对第一个节点的引用
# 空表的head为None
self.head = None
def isEmpty(self):
# 无序表对象本身并不包含数据项
# 其中包含的head只是对首个节点Node的引用
# 判断空表的isEmpty()很容易实现
return self.head == None
def add(self,item):
# 由于无序表并没有限定数据项之间的顺序
# 新数据项可以加入到原表的任何位置
# 按照实现的性能考虑,应添加到最容易加入的位置上
temp = Node(item)
temp.setNext(self.head)
self.head = temp
def size(self):
# 从head开始遍历到表尾,用变量累加记录节点个数
current = self.head
count = 0
while current != None:
count += 1
current = current.getNext()
return count
def search(self,item):
# 从head开始遍历到表尾,判断当前节点是否为目标项
current = self.head
find = False
while current != None and not find:
if current.getData() == item:
find = True
else:
current = current.getNext()
return find
def remove(self,item):
# 在search current的同时,还需要维护前一个节点的引用 previous
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 append(self,item):
temp = self.head
# 是否是空链表
if temp == None:
self.head = Node(item)
else:
# 寻找最后一个节点
while temp.getNext() != None:
temp = temp.getNext()
# 为最后一个节点添加next
temp.setNext(Node(item))
def index(self,item):
# 循环查找,加入一个index记录数据项
current = self.head
index = 0
found = False
while current!= None and not found:
if current.getData() == item:
found = True
else:
current = current.getNext()
index += 1
# 是否找到
if found:
return index
else:
return False
def insert(self,pos,item):
temp = Node(item)
previous = None
current = self.head
# 寻找插入位置
for i in range(pos):
previous = current
current = current.getNext()
# 开始插入
if previous == None:
temp.setNext(current)
self.head = temp
else:
temp.setNext(current)
previous.setNext(temp)
def pop(self,pos = None):
# 判断pos参数
if pos == None or pos >= self.size():
pos = self.size()-1
elif pos < 0 :
pos = pos + self.size()
# 开始查找
previous = None
current = self.head
for i in range(pos):
previous = current
current = current.getNext()
# 提取结果
if previous == None:
result = current.getData()
self.head = current.getNext()
else:
result = current.getData()
previous.setNext(current.getNext())
return result
代码:JavaScript
class Node {
constructor(initdata) {
this.data = initdata
this.next = null
}
getData() {
return this.data
}
getNext() {
return this.next
}
setData(newdata) {
this.data = newdata
}
setNext(newnext) {
this.next = newnext
}
}
class UnorderedList {
constructor() {
this.head = null
}
isEmpty() {
return this.head == null
}
add(item) {
let temp = new Node(item)
temp.setNext(this.head)
this.head = temp
}
size() {
let current = this.head
let count = 0
while (current != null) {
count += 1
current = current.getNext()
}
return count
}
search(item) {
let current = this.head
let find = false
while (current != null && !find) {
if (current.getData() == item) {
find = true
} else {
current = current.getNext()
}
}
return find
}
remove(item) {
let previous = null
let current = this.head
let found = false
while (current != null && !found) {
if (current.getData() == item) {
found = true
} else {
previous = current
current = current.getNext()
}
}
if (previous == null) {
this.head = current.getNext()
} else {
previous.setNext(current.getNext())
}
}
append(item) {
let current = this.head
if (current == null) {
this.head = new Node(item)
} else {
while (current.getNext() != null) {
current = current.getNext()
}
current.setNext(new Node(item))
}
}
index(item) {
let current = this.head
let i = 0
let found = false
while (current != null && !found) {
if (current.getData() == item) {
found = true
} else {
i += 1
current = current.getNext()
}
}
if (found) {
return i
} else {
return found
}
}
insert(pos, item) {
let temp = Node(item)
let previous = null
let current = this.head
for (let i = 0; i < pos; i++) {
previous = current
current = current.getNext()
}
if (previous == null) {
temp.setNext(current)
this.head = temp
} else {
temp.setNext(current)
previous.setNext(temp)
}
}
pop(pos = null) {
if (pos == null || pos > this.size()) {
pos = this.size() - 1
} else if (pos < 0) {
pos = this.size() + pos
}
let previous = null
let current = this.head
let result = null
for (let i = 0; i < pos; i++) {
previous = current
current = current.getNext()
}
if (previous == null) {
result = current.getData()
this.head = current.getNext()
} else {
result = current.getData()
previous.setNext(current.getNext())
}
return result
}
}