Linked list – One-way linked list?
Unidirectional linked list structure diagram:
As can be seen from the structured diagram, a single necklace table uses a set of arbitrary memory space to store data elements, starting with the head pointer, its pointer to the next node, and the last pointer to null. In this case, each node has data itself and a pointer to the next node
After analyzing the structure, let’s use JS code to achieve it
1: initializes a node information, which is used to generate each node
// Initialize the node information
// 1: the pointer is null
// 2: data points to stored data
class Node {
constructor(key){
this.next = null;
this.key = key; }}Copy the code
2: initializes the one-way linked list
class List {
constructor(){
this.head = new Node('head'); }}Copy the code
We use constructors to implement our list. I have directly generated the head node of the list to facilitate insertion and deletion later
3: Insert a new node
We know that each node in the list has a pointer to the next node, so what if we want to insert a new node? In fact, we just need to change the pointer point, we will insert the node pointer to the current node pointer, and the current node pointer to the node we need to insert
We first need a lookup function that says, where do we want to insert the node
// Find the node
find(item){
let currentNode = this.head;
while(currentNode.key! ==item) {if(currentNode.next === null) {return 'Not found'
}
currentNode = currentNode.next;
}
return currentNode
}
Copy the code
Insert node implementation
// Insert a new node after an element
insert(newKey,item){
/ / the new element
let newNode = new Node(newKey);
let current = this.find(item);
// Change the pointer pointer
if(current === 'Not found') {return
}
newNode.next=current.next;
current.next=newNode;
}
Copy the code
Remove nodes
Remove nodes as well as insert node, we only need to change node Pointers point to the new node, but because of remove when we need to change the parent node pointer to the pointer to the current node, all we need to first check to delete a node’s parent, so how to realize, actually very simple, We just need to know that the property of the node that the pointer to the node points to is equal to the value we are looking for, and in this case the node is the parent node we want
Find the parent node
// find Key equality
findUpNode(newKey){
let currentNode = this.head;
while(currentNode.next! = =null&& currentNode.next.key! ==newKey) { currentNode = currentNode.next }return currentNode
}
Copy the code
Deleting a node
// To delete a node, you change the direction of next, pointing the current node next to the next node next next
deleteNode(newKey){
let upNode = this.findUpNode(newKey);
if(upNode.next! = =null){
upNode.next = upNode.next.next
}
}
Copy the code
OK!!!!!! Here we have the full functionality of a one-way list. I have added a view method to view the elements in our list. The complete code is attached below
class Node {
constructor(key){
this.next = null;
this.key = key; }}class List {
constructor(){
this.head = new Node('head');
}
// Find the node
find(item){
let currentNode = this.head;
while(currentNode.key! ==item) {if(currentNode.next === null) {return 'Not found'
}
currentNode = currentNode.next;
}
return currentNode
}
// Insert a new node after an element
insert(newKey,item){
let newNode = new Node(newKey);
let current = this.find(item);
if(current === 'Not found') {return
}
newNode.next=current.next;
current.next=newNode;
}
// Find the previous node of a node
findUpNode(newKey){
let currentNode = this.head;
while(currentNode.next! = =null&& currentNode.next.key! ==newKey) { currentNode = currentNode.next }return currentNode
}
// Delete a node
deleteNode(newKey){
let upNode = this.findUpNode(newKey);
if(upNode.next! = =null){
upNode.next = upNode.next.next
}
}
// View the current list and print out each node
view(){
let currentNode = this.head;
while(currentNode.next! = =null ) {
console.log(currentNode.next.key)
currentNode=currentNode.next
}
}
}
let list = new List();
list.insert('Joe'.'head')
list.insert('bill'.'Joe')
list.findUpNode('bill')
list.deleteNode('bill')
console.log(list.findUpNode('bill'))
console.log(list.view())
Copy the code
Linked lists – Two – way linked lists
The prev pointer points to the previous node, and the prev pointer points to NULL for the head node and the next pointer points to NULL for the tail node. Let’s implement a bidirectional list!
Ps: Prev and next are both Pointers
Initializing a node information is used to generate each node
class Node {
constructor(key){
this.prev = null;
this.key = key;
this.next = null; }}Copy the code
Ps: We initialize one more pointer to a prev than to a unidirectional list
Initialize a bidirectional linked list
class List {
constructor(){
this.head = new Node('head'); }}Copy the code
Still declare a new head node directly
Insert a new node
The principle of insertion is the same as that of a one-way linked list and we won’t talk about it anymore
// Find the node
find(item){
let currentNode = this.head;
while(currentNode.key! ==item) {if(currentNode.next === null) {return 'Not found'
}
currentNode = currentNode.next;
}
return currentNode
}
// Insert the node
insert(newKey,item){
/ / the new element
let newNode = new Node(newKey);
let currentNode = this.find(item);
Next of the new node points to next of the current node and next of the current node points to the new node
if(currentNode === 'Not found') {return 'Insert node cannot be found'
}
if(currentNode.next! = =null){
newNode.next = currentNode.next;
newNode.prev = currentNode;
newNode.next.prev = newNode;
currentNode.next = newNode;
}else{
newNode.next = null; newNode.prev = currentNode; currentNode.next = newNode; }}Copy the code
Note that the insertion of the bidirectional list needs to determine whether it is the last node, and we need to change the pointer of the node’s prev and next Pointers
Remove nodes
Delete node is simpler than singly linked list, we don’t need to look up the parent node, go directly to change the prev pointer pointing to, but we need to figure out whether delete node and end node for the corresponding operation, just change node Pointers point to, pay special attention to, we need to delete the node pointer to null, Otherwise, the bidirectional list would be messed up
deleteNode(item){
let currentNode = this.find(item)
if(currentNode === 'Not found') {return 'Node to be deleted does not exist'
}
// We need to check whether the node is a head and tail node
if(currentNode.next! = =null&& currentNode.prev! = =null) {// Neither head nor tail node
currentNode.prev.next = currentNode.next;
currentNode.next.prev = currentNode.prev;
currentNode.next = null;
currentNode.prev = null;
} else if(currentNode.next === null) {/ / end nodes
currentNode.prev.next = null;
currentNode.prev = null;
} else if(currentNode.prev === null) {/ / head node
currentNode.next.prev = null;
currentNode.next = null; }}Copy the code
Here is the complete code for the bidirectional list, still adding a view function to view our list
// Initialize the node information
// 1: the pointer is null
// 2: data points to stored data
class Node {
constructor(key){
this.prev = null;
this.key = key;
this.next = null; }}// Initializes the bidirectional linked list
class List {
constructor(){
this.head = new Node('head');
}
// Find the node
find(item){
let currentNode = this.head;
while(currentNode.key! ==item) {if(currentNode.next === null) {return 'Not found'
}
currentNode = currentNode.next;
}
return currentNode
}
// Insert the node
insert(newKey,item){
/ / the new element
let newNode = new Node(newKey);
let currentNode = this.find(item);
Next of the new node points to next of the current node and next of the current node points to the new node
if(currentNode === 'Not found') {return 'Insert node cannot be found'
}
if(currentNode.next! = =null){
newNode.next = currentNode.next;
newNode.prev = currentNode;
newNode.next.prev = newNode;
currentNode.next = newNode;
}else{
newNode.next = null; newNode.prev = currentNode; currentNode.next = newNode; }}// Delete a node, which is easier than a single necklace table because you don't need to look up the previous node to change the prev pointer
deleteNode(item){
let currentNode = this.find(item)
if(currentNode === 'Not found') {return 'Node to be deleted does not exist'
}
// We need to check whether the node is a head and tail node
if(currentNode.next! = =null&& currentNode.prev! = =null) {// Neither head nor tail node
currentNode.prev.next = currentNode.next;
currentNode.next.prev = currentNode.prev;
currentNode.next = null;
currentNode.prev = null;
} else if(currentNode.next === null) {/ / end nodes
currentNode.prev.next = null;
currentNode.prev = null;
} else if(currentNode.prev === null) {/ / head node
currentNode.next.prev = null;
currentNode.next = null; }}/ / check
view(){
let currentNode = this.head;
while(currentNode.next ! = =null) {
console.log(currentNode.next.key)
currentNode=currentNode.next
}
}
}
let list = new List();
list.insert('Joe'.'head')
list.insert('bill'.'Joe')
list.insert('Cathy'.'bill')
list.deleteNode('bill')
console.log(list.view())
Copy the code
OK, by learning from the two list if we fully mastered the knowledge of the list, may be used less than in our development, but not hinder us to explore, after all, you may be asked when the interview, how to determine a linked list is two-way linked list, or how to judge the list is circular linked list (i.e., the list is end to end), OK, Leave a little tail for you to explore!
😄😄😄 don’t forget to like 😄😄😄