单向链表
export const defaultEquals = (a, b) => {
return a === b;
}
export class Node {
constructor(element){
this._element = element;
this._next = undefined;
}
}
export class LinkedList {
constructor(equalsFn = defaultEquals){
this._count = 0;
this._head = undefined;
this._equalsFn = equalsFn;
}
push(element){
const node = new Node(element);
let current;
if(this._head == null){
this._head = node;
} else {
current = this._head;
while(current._next != null){
current = current._next;
}
current._next = node;
}
this._count++;
}
getElementAt(index){
if(index >= 0 && index < this._count){
let current = this._head;
for (let i = 0; i < index && current != null; i++) {
current = current._next;
}
return current;
}
return undefined
}
removeAt(index){
if(index >= 0 && index < this._count){
let current = this._head;
if(index == 0){
this._head = current._next;
} else {
const previous = this.getElementAt(index -1);
current = previous._next;
previous._next = current._next;
}
this._count--;
return current._element;
}
return undefined;
}
insert(element, index){
if(index >= 0 && index < this._count){
const node = new Node(element);
if(index == 0){
const current = this._head;
node._next = current;
this._head = node;
}else {
const previous = this.getElementAt(index -1);
const current = previous._next;
node._next = current;
previous._next = node;
}
this._count ++;
return true;
}
return false;
}
indexOf(element){
let current = this._head;
for(let i = 0; i < this._count && current != null; i++){
if(this._equalsFn(element, current._element)){
return i;
}
current = current._next;
}
return -1;
}
remove(element) {
const index = this.indexOf(element);
return this.removeAt(index);
}
size() {
return this._count;
}
isEmpty() {
return this.count === 0;
}
getHead() {
return this._head;
}
toString() {
if (this._head == null) {
return '';
}
let objString = `${this._head._element}`;
let current = this._head._next;
for (let i = 1; i < this.size() && current != null; i++) {
objString = `${objString},${current._element}`;
current = current._next;
}
return objString;
}
}
const list = new LinkedList();
console.log(list.isEmpty());
list.push(15);
list.push(10);
list.push(14);
list.push(11);
console.log(list.indexOf(14));
list.removeAt(list.indexOf(14))
list.remove(11);
list.insert(55,0);
list.insert(56,1);
console.log(list.size());
console.log(list.getHead());
console.log(list.isEmpty());
console.log(list.toString());
双向链表
import { defaultEquals, Node, LinkedList } from './LinkedList.js'
class DoublyNode extends Node {
constructor(element, next, prev){
super(element, next);
this._prev = prev;
}
}
class DoublyLinkedList extends LinkedList {
constructor(equalsFn = defaultEquals) {
super(equalsFn);
this._tail = undefined;
}
insert(element, index){
if (index >= 0 && index <= this._count) {
const node = new DoublyNode(element);
let current = this._head;
if(index === 0){
if (this._head == null) {
this._head = node;
this._tail = node;
} else {
node.next = this._head;
current._prev = node;
this._head = node;
}
}else if(index === this._count){
current = this._tail;
current._next = node;
node._prev = current;
node._next = node;
}else {
const previous = this.getElementAt(index - 1);
current = previous._next;
node._next = current;
previous._next = node;
current._prev = node;
node._prev = previous;
}
this._count++;
return true;
}
return false;
}
removeAt(index){
if (index >= 0 && index < this._count) {
let current = this._head;
if(index === 0){
this._head = current._next;
if (this.count === 1) {
this._tail = undefined;
} else {
this._head._prev = undefined;
}
}else if(index === this._count - 1){
current = this._tail;
this._tail = current._prev;
this._tail._next = undefined;
}else {
current = this.getElementAt(index);
const previous = current._prev;
previous._next = current._next;
current._next._prev = previous;
}
this._count--;
return current._element;
}
return undefined;
}
}