跟我一起学“仓颉”算法-单链表
·
目录
一、单链表
单链表是线性表的链式存储,逻辑上相邻的数据在计算机内的存储位置不一定相邻。通过节点进行寻找下一个元素的位置,节点包括:指针和数据。因为指针的指向都是一个方向,所以叫单链表。
二、实现
package Algorithm.list
/*
* 集合
*/
public interface List<E> {
func add(element: E): Unit
func remove(index: Int64): Option<E>
func clear(): Unit
func isEmpty(): Bool
func size(): Int64
func deepClone(): List<E>
func indexOf(element: Option<E>): Int64
func contains(element: Option<E>): Bool
func get(index: Int64): Option<E>
}
/*
* 单链表需要的Node
*/
private class Node<E> {
// 指针
private var _next: Option<Node<E>>
// 数据
private var _element: Option<E>
public init(_next: Option<Node<E>>, _element: Option<E>) {
this._element = _element
this._next = _next
}
public mut prop next: Option<Node<E>> {
get() {
return this._next
}
set(_next) {
this._next = _next
}
}
public mut prop element: Option<E> {
get() {
return this._element
}
set(_element) {
this._element = _element
}
}
}
/*
* 单链表数组
*/
public class MyLinkedList<E> <: List<E> {
// 保存当前元素长度
private var length = 0
private static let NOT_FOUND: Int64 = -1
// 头节点
private var first: Option<Node<E>> = Option<Node<E>>.None
/*
* 集合长度
*/
public override func size(): Int64 {
return this.length
}
/*
* 集合是否为空
*/
public override func isEmpty(): Bool {
return this.length == 0
}
/*
* 判断元素是否存在
*/
public override func contains(element: Option<E>): Bool {
return indexOf(element) != NOT_FOUND
}
/*
* 检查数组是否越界
*/
public func checkIndex(index: Int64): Unit {
if (index < 0 || index >= this.length) {
throw IndexOutOfBoundsException("索引越界, 允许范围(0, ${this.length - 1}),当前索引: ${index}")
}
}
/*
* 在末尾添加元素
*/
public override func add(element: E): Unit {
var node = Node(Option<Node<E>>.None, element)
if(first.isNone()){
this.first = node
} else {
var last = this.first
while(last.getOrThrow().next.isSome()){
last = last.getOrThrow().next
}
last.getOrThrow().next = node
}
this.length++
}
/*
* 根据索引删除元素
*/
public override func remove(index: Int64): Option<E> {
checkIndex(index)
var oldNode = this.first
if (index == 0) {
this.first = this.first.getOrThrow().next
} else {
var pre = node(index - 1)
oldNode = pre.next
var next = pre.next.getOrThrow().next
pre.next = next
}
this.length--
return oldNode.getOrThrow().element
}
/*
* 清空链表
*/
public override func clear(): Unit {
this.length = 0
first = Option<Node<E>>.None
}
/*
* 深克隆数组
*/
public override func deepClone(): List<E> {
let newElement = MyLinkedList<E>()
var node = this.first
for (_ in 0..this.length) {
newElement.add(node.getOrThrow().element.getOrThrow())
node = node.getOrThrow().next
}
return newElement
}
/*
* 查找元素对应的下标
*/
public override func indexOf(element: Option<E>): Int64 {
var node = this.first
if (element.isNone()) {
for (i in 0..this.length) {
if (node.getOrThrow().element.isNone()) {
return i
}
node = node.getOrThrow().next
}
} else {
for (i in 0..this.length) {
if (node.getOrThrow().element.isSome()) {
return i
}
node = node.getOrThrow().next
}
}
return NOT_FOUND
}
/*
* 获取对应索引的值
*/
public override func get(index: Int64): Option<E> {
// 越界处理
checkIndex(index)
return node(index).element
}
/*
* 获取节点
*/
private func node(index: Int64): Node<E> {
// 越界处理
checkIndex(index)
// 获取头节点
var optNode = this.first.getOrThrow()
for (_ in 0..index) {
optNode = optNode.next.getOrThrow()
}
return optNode
}
}
测试代码
package Algorithm
import Algorithm.list.*
main(): Int64 {
let arr = MyLinkedList<Int64>()
println("添加元素")
arr.add(0)
arr.add(11)
arr.add(22)
arr.add(33)
arr.add(44)
arr.add(55)
arr.add(66)
arr.add(77)
arr.add(88)
arr.add(99)
arr.add(100)
for (i in 0..arr.size()) {
print("${arr.get(i).getOrThrow()} ")
}
println("数组长度: ${arr.size()}")
println("删除元素")
arr.remove(0)
for (i in 0..arr.size()) {
print("${arr.get(i).getOrThrow()} ")
}
println("数组长度: ${arr.size()}")
println("克隆数组")
let newArr = arr.deepClone()
newArr.add(1000)
for (i in 0..newArr.size()) {
print("${newArr.get(i).getOrThrow()} ")
}
println("数组长度: ${newArr.size()}")
println("原始数组")
for (i in 0..arr.size()) {
print("${arr.get(i).getOrThrow()} ")
}
println("数组长度: ${arr.size()}")
return 0
}
三、小结
本章为大家详细的介绍了仓颉数据结构与算法中单链表的内容,下一章,为大家带来双向链表的内容。最后,创作不易,如果大家觉得我的文章对学习仓颉数据结构与算法有帮助的话,就动动小手,点个免费的赞吧!收到的赞越多,我的创作动力也会越大哦,谢谢大家🌹🌹🌹!!!
昇腾计算产业是基于昇腾系列(HUAWEI Ascend)处理器和基础软件构建的全栈 AI计算基础设施、行业应用及服务,https://devpress.csdn.net/organization/setting/general/146749包括昇腾系列处理器、系列硬件、CANN、AI计算框架、应用使能、开发工具链、管理运维工具、行业应用及服务等全产业链
更多推荐

所有评论(0)