【数据结构与算法学习笔记-UnorderedList】

本文为学习笔记,感兴趣的读者可在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
  }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值