如封面 ^_^
詳細點解釋的話。。那不如抄書吧
慣例,抄書交給截圖 -。-
javascript
圖片截取自[數據結構(C語言版)].嚴蔚敏_吳偉民java
//節點類
class LinkedListNode {
constructor(data){
this.data = data
this.next = null
}
}
//鏈表類
const head = Symbol("head")
class LinkedList {
constructor(){
this[head] = null
}
//增長節點
add(data){
const newNode = new LinkedListNode(data)
if (this[head] === null) {
this[head] = newNode
} else {
let current = this[head]
while(current.next){
current = current.next
}
current.next = newNode
}
}
//查找當前節點
findAt(index){
if (index > -1) {
let current = this[head]
let i = 0
while(current !== null){
if(i === index){
return current
}
current = current.next
i++
}
} else {
return undefined
}
}
find(data){
let current = this[head]
while((current !== null) && (current.data !== data)){
current = current.next
}
return current === null ? undefined : current
}
//查找前一個節點
findPrevAt(index){
if(index < 1){
return undefined
}
let current = this[head]
let previous = null
let i = 0
while(current !== null){
if(i === index){
return previous
}
previous = current
current = current.next
i++
}
return undefined
}
findPrev(data){
let current = this[head]
let previous = null
while(current !== null){
if(current.data === data){
return previous === null ? undefined : previous
}
previous = current
current = current.next
}
return undefined
}
//刪除節點
removeAt(index){
//邊界
if(this[head] === null || index < 0){
console.error('節點不存在')
return undefined
}
//第一個節點
if(index === 0){
const node = this[head]
this[head] = this[head].next
return node
}
const current = this.findAt(index)
const previous = this.findPrevAt(index)
//未找到節點
if(current === undefined){
console.error('節點不存在')
return undefined
}
//最後一個節點
if(current.next === null){
previous.next = null
return current
}
//中間節點
previous.next = current.next
return current
}
remove(data){
//邊界
if(this[head] === null){
console.error('節點不存在')
return undefined
}
const current = this.find(data)
const previous = this.findPrev(data)
//節點未找到
if(current === undefined){
console.error('節點不存在')
return undefined
}
//第一個節點
if(previous === undefined){
const node = this[head]
this[head] = this[head].next
return node
}
//最後一個節點
if(current.next === null){
previous.next = null
return current
}
//中間節點
previous.next = current.next
return current
}
//插入節點
insertAt(node, index){
//在前面插入
if(index < 0){
const current = this[head]
this[head] = new LinkedListNode(node)
this[head].next = current
return
}
let current = this.findAt(index)
if(current === undefined){
console.error('節點不存在')
return undefined
}
const newNode = new LinkedListNode(node)
newNode.next = current.next
current.next = newNode
}
insert(node, data){
let current = this.find(data)
if(current === undefined){
console.error('節點不存在')
return undefined
}
const newNode = new LinkedListNode(node)
newNode.next = current.next
current.next = newNode
}
//可迭代
*[Symbol.iterator](){
let current = this[head]
while(current !== null){
yield current.data
current = current.next
}
}
}
複製代碼
//test
const list = new LinkedList()
list.add('0')
list.add('1')
list.add('2')
list.add('3')
list.add('4')
for(let i of list){
console.log(i)
}
複製代碼
將兩個有序鏈表合併爲一個新的有序鏈表並返回。新鏈表是經過拼接給定的兩個鏈表的全部節點組成的。node
輸入:1->2->4, 1->3->4
輸出:1->1->2->3->4->4
複製代碼
/** * Definition for singly-linked list. * function ListNode(val) { * this.val = val; * this.next = null; * } */
/** * @param {ListNode} l1 * @param {ListNode} l2 * @return {ListNode} */
const list_1 = new LinkedList()
list_1.add(1)
list_1.add(2)
list_1.add(4)
const list_2 = new LinkedList()
list_2.add(1)
list_2.add(3)
list_2.add(4)
function mergeTwoLists(l1, l2) {
if (l1 === null) {
return l2;
} else if (l2 === null) {
return l1;
}
let newHead = new LinkedListNode(0);
let temp = newHead;
while (l1 || l2) {
if (l1 === null) {
newHead.next = l2;
break;
}
if (l2 === null) {
newHead.next = l1;
break;
}
console.log('l1',l1)
console.log('l2',l2)
if (l1.data <= l2.data) {
newHead.next = l1
newHead = newHead.next;
l1 = l1.next;
} else {
newHead.next = l2;
newHead = newHead.next;
l2 = l2.next;
}
}
return temp.next;
};
const newList = mergeTwoLists(list_1[head], list_2[head])
console.log('newList',newList) // 1->1->2->3->4->4
複製代碼
題目內容又臭又長 就是閱讀理解 本身去看吧。。。leetcode-237算法
其實就是腦筋急轉彎...很是無語bash
/** * Definition for singly-linked list. * function ListNode(val) { * this.val = val; * this.next = null; * } */
/** * @param {ListNode} node * @return {void} Do not return anything, modify node in-place instead. */
var deleteNode = function(node) {
//node就是要刪除的節點 這題沒有給head 也不須要遍歷鏈表
//將後一個節點的值賦值給要刪除的node節點
node.val = node.next.val
//再將後一個節點刪除 這樣就經過賦值的方式 達到了刪除node的目的
//可憐的node.next就是個替死鬼
node.next = node.next.next
};
複製代碼
反轉一個單鏈表數據結構
示例:ui
輸入: 1->2->3->4->5->NULL
輸出: 5->4->3->2->1->NULL
複製代碼
進階: 你能夠迭代或遞歸地反轉鏈表。你可否用兩種方法解決這道題?this
/** * Definition for singly-linked list. * function ListNode(val) { * this.val = val; * this.next = null; * } */
/** * @param {ListNode} head * @return {ListNode} */
var reverseList = function(head) {
let current = head
let pre = null
while(current !== null){
let temp = current.next
current.next = pre
pre = current
current = temp
}
return pre
};
複製代碼
/** * Definition for singly-linked list. * function ListNode(val) { * this.val = val; * this.next = null; * } */
/** * @param {ListNode} head * @return {ListNode} */
//循環鏈表
var middleNode = function(head) {
let A = [head];
while (A[A.length - 1].next != null){
A.push(A[A.length - 1].next);
}
return A[Math.trunc(A.length / 2)];
};
//快慢指針
var middleNode = function(head) {
let slow = head
let fast = head
while(fast && fast.next){
slow = slow.next
fast = fast.next.next
}
return slow
};
複製代碼
/** * Definition for singly-linked list. * function ListNode(val) { * this.val = val; * this.next = null; * } */
/** * @param {ListNode} headA * @param {ListNode} headB * @return {ListNode} */
//標記
var getIntersectionNode = function(headA, headB) {
while(headA){
headA.tag = 1
headA = headA.next
}
while(headB){
if(headB.tag){
return headB
}
headB = headB.next
}
return null
};
//嵌套循環
var getIntersectionNode = function(headA, headB) {
while(headA){
let temp = headB
while(temp){
if(temp === headA){
return temp
}
temp = temp.next
}
headA = headA.next
}
return null
};
//雙指針
var getIntersectionNode = function(headA, headB) {
let la = headA
let lb = headB
while(la !== lb){
la = la ? la.next : headB
lb = lb ? lb.next : headA
}
return la
};
複製代碼
/** * Definition for singly-linked list. * function ListNode(val) { * this.val = val; * this.next = null; * } */
/** * @param {ListNode} head * @return {ListNode} */
var deleteDuplicates = function(head) {
let current = head
while(current && current.next){
if(current.val === current.next.val){
current.next = current.next.next
} else {
current = current.next
}
}
return head
};
複製代碼
/** * Definition for singly-linked list. * function ListNode(val) { * this.val = val; * this.next = null; * } */
/** * @param {ListNode} head * @return {boolean} */
//標記
var hasCycle = function(head) {
while(head){
if(head.tag){
return true
}
head.tag = 1
head = head.next
}
return false
};
// JSON.stringify
var hasCycle = function(head) {
try{
JSON.stringify(head);
return false;
}
catch(err){
return true;
}
}
//快慢指針
var hasCycle = function(head) {
let slow = head
let fast = head
while(fast && fast.next){
slow = slow.next
fast = fast.next.next
if(slow === fast){
return true
}
}
return false
};
複製代碼
/** * Definition for singly-linked list. * function ListNode(val) { * this.val = val; * this.next = null; * } */
/** * @param {ListNode} head * @param {number} val * @return {ListNode} */
var removeElements = function(head, val) {
let first = new ListNode()
first.next = head
let temp = first
while(temp && temp.next){
if(temp.next.val === val){
temp.next = temp.next.next
} else {
temp = temp.next
}
}
return first.next
};
//遞歸
var removeElements = function(head, val) {
if(!head){
return null
}
head.next = removeElements(head.next, val)
if(head.val === val){
return head.next
} else {
return head
}
};
複製代碼
啊。。。spa
又挖一個坑, 未完待續 。 。 。指針