这是我参与2022首次更文挑战的第17天,活动详情查看:2022首次更文挑战」。
我个人觉得要想进大厂,就必须学习了解算法和数据结构,经历了多次面试之后,也知道了算法和数据结构的重要性,所以,我也打算从今天开始,进入学习,下载了一下电子书,边看书,边跟着书的例子来敲一下代码,下面就开始总结一下对算法和数据结构的学习吧。
第十七天:继续了解链表
-
有序链表
有序链表是保持元素有序的链表结构。除了使用排序算法之外,我们还可以将元素插入到正确的位置来保证链表的有序性。
如果要对插入的数据进行排序,首先我们得要构建一个对比方法
const Compare = { LESS_THAN: -1, BIGGER_THAN: 1 } function defaultCompare(a, b) { if(a === b) return 0 return a < b ? Compare.LESS_THAN : Compare.BIGGER_THAN; }有了对比方法,我们的有序列表还是继承单向链表
class SortedLinkedList extends LinkedList { constructor() { super() this.compareFn = defaultCompare } }前面我们已经有了单向列表的一些方法,有序列表可以直接利用前面的方法去构建自己的方法。
function insert(element, index = 0) { if(this.isEmpty()) { return super.insert(element, 0) } const pos = this.getIndexNextSortedElement(element) return super.insert(element, pos) } function getIndexNextSortedElement(element) { let current = this.head let i = 0 for(; i < this.size(); i++) { const comp = this.compareFn(element, current.element) if(comp < Compare.LESS_THAN) { return i } current = current.next } return i }如果是空的链表的话,可以直接调用继承的insert方法,插入到第一个位置上。
另一种情况就是链表已经存在,因为我们的有序链表不能插入任意位置,位置都是根据规则排序好插入进去的,所以我们只需要传一个element参数就好。
首先就是得有一个方法去获取该元素应该插入的位置,原理就是从头开始找,当传入的元素的值小于当前的值,那么就直接返回这个索引,如果一直都没有找到,那么找个i也加到了最后,也是直接返回这个索引就好。
找到索引之后,和插入第一个元素一样,直接调用继承的insert方法。
-
创建StackLinkedList类
我们还可以使用LinkedList类去构建起他数据结构,例如栈、队列和双向队列。
-
下面就用链表实现栈
class StackLinkedList { constructor() { this.items = new DoublyLinkedList() } push() { this.items.push(element) } pop() { if(this.isEmpty()) return null this.item.removeAt(this.size() - 1) } }对于栈,我们会向链表尾部添加元素,也会从链表尾部移除元素。所以使用了双向链表,因为双向链表最后一个元素有尾指针,无须迭代整个链表的元素就能获取它。双向链表可以直接获取头尾的元素,减少过程的小号,它的时间复杂度和原始的Stack实现相同,为O(1)
-