标签:保存 nbsp 时间复杂度 倒数第k个节点 while循环 reverse 单链表 function console
function LinkedList() {
//需要插入链表的元素
var Node = function(element) {
this.element = element;//元素的值
this.next = null;//指向下一个节点项的指针
};
var length = 0;//链表的长度
var head = null;//链表中第一个节点(的引用)
//向链表尾部追加元素
this.append = function(element) {
var node = new Node(element), current;
if(head === null) {
//当链表为空时
head = node;
} else {
//要从第一个元素找起
current = head;
//循环链表,直到找到最后一项
while(current.next) {
current = current.next;
}
//把元素插入到链表的末尾
current.next = node;
}
length++;
};
//从链表中根据位置移除元素并返回该元素
this.removeAt = function(position) {
if (position > -1 && position < length) {
var current = head,
previous,
index = 0;
//移除第一项
if(position == 0) {
head = current.next;
return current.element;
}else{
while(index++ < position){
previous = current;//删除指定位置前的一个元素
current = current.next;
}
previous.next = current.next;
length--;
}
return current.element;
}else{
return null;
};
}
//从链表中根据值移除元素
this.remove = function(element){
var index = this.indexOf(element);
return this.removeAt(index);
};
//在任意位置插入一个元素
this.insert = function(position, element) {
if(position > -1 && position <= length) {
var node = new Node(element),
current = head,
previous,
index = 0;
if(position === 0){ //在第一个位置添加
node.next = current;
head = node;
}else{
while(index++ < position) {
previous = current;
current = current.next;
}
node.next = current;
previous.next = node;
}
length++;
return true;
}else{
return false;
}
};
//找到并返回一个元素的位置,如果元素不存在,返回-1
this.indexOf = function(element) {
var current = head,
index = 0;
while(current) {
if(element === current.element) {
return index;
}
index++;
current = current.next;
}
return -1;
};
//判断链表是否为空
this.isEmpty = function() {
return length === 0;
};
//返回链表的长度
this.size = function() {
return length;
};
//查看链表中元素的值(转换为字符串)
this.toString = function() {
var current = head,
string = ‘‘;
while(current) {
string += "," + current.element;
current = current.next;
}
return string.slice(1);
};
//返回链表中第一个元素
this.getHead = function() {
return head;
};
//查看链表(中的元素和指针,以数组形式输出)
this.print = function() {
var current = head,
list = [];
while(current) {
list.push(current);
current = current.next;
}
return list;
};
}
var list = new LinkedList();
list.append(5);
console.log(list.toString());
console.log(list.print());
console.log(list.indexOf(115));
console.log(list.isEmpty());
console.log(list.size());
console.log(list.getHead());
console.log(list.removeAt(0));
console.log(list.toString());
console.log(list.removeAt(1));
console.log(list.toString());
list.insert(0, 500);
console.log(list.toString());
//思路 特殊情况:单链表,空链表 新建一个节点newHead,放在头节点前面,当头节点需要被删除时,方便返回结果 pre指针指向前一个节点(初始为newHead)cur指向当前节点(初始为头节点),next指向下一个节点(初始为null) cur不空,cur.next不空时,进入循环,依次比较节点,next保存cur.next 如果cur和next值相等,就进入循环,依次向后查找所有重复元素,然后删除中间所有重复元素(pre.next = next;),cur指向next的当前位置 如果cur和next值不相等,pre和cur依次向后移动,继续比较 最后遍历结束,退出循环,返回头节点:newHead.next function deleteDuplication(pHead) { if (!pHead || !pHead.next) return pHead; let newHead = new ListNode("head"); //新建一个节点 newHead.next = pHead; //充当新的头节点,当head节点被删除时可以返回正确的头节点 let pre = newHead; //pre指向前一个节点 let cur = pHead; //cur指向当前节点 let next = null; //next指向下一个节点 while (cur && cur.next) { //当前节点不空且下一个节点不空时,进入比较循环 next = cur.next; //next存放下个节点的位置 if (next.val === cur.val) { //cur和next值相等 //进入循环向后查找所有重复元素 while (next && next.val === cur.val) { next = next.next; //next后移一位 } //next空或者next和cur值不相等,退出循环 pre.next = next; //删除中间重复的节点 cur = next; //cur指针指向next的位置 } else { //cur和next值不相等 pre = cur; //pre和cur都后移 cur = next; } } return newHead.next; }
var isPalindrome = function(head, queue = []) { if (!head) { return true; } queue.push(head.val); let flag = isPalindrome(head.next, queue); return queue.shift() === head.val && flag; }
<!--查找单链表的中间结点:
定义两个节点k1、k2,k1一次走两步,k2一次走一步,
当k2走到尽头时此时k1所在的位置中间节点。-->
<!--输入:[1,2,3,4,5,6]
输出:此列表中的结点 4 (序列化形式:[4,5,6])
由于该列表有两个中间结点,值分别为 3 和 4,我们返回第二个结点。
-->
/**
* Definition for singly-linked list.
* function ListNode(val) {
* this.val = val;
* this.next = null;
* }
*/
var middleNode = function(head) {
var length = 1,
node = head;
//测量链表长度
while(node.next !== null){
length++;
node = node.next;
}
//设置中间长度
if(length % 2 === 0){
length = length / 2 + 1;
}else{
length = Math.ceil(length / 2);
}
//重新查找中间长度的节点
node = head;
while(length !== 1){
node = node.next;
length--;
}
return node;
};
//思路
简单思路: 循环到链表末尾找到 length 在找到length-k节点 需要循环两次。
//优化:
设定两个节点,间距相差k个节点,当前面的节点到达终点,取后面的节点。
前面的节点到达k后,后面的节点才出发。
//代码鲁棒性: 需要考虑head为null,k为0,k大于链表长度的情况。
function FindKthToTail(head, k) {
if (!head || !k) return null;
let front = head;
let behind = head;
let index = 1;
while (front.next) {
index++;
front = front.next;
if (index > k) {
behind = behind.next;
}
}
return (k <= index) && behind;
}
//以链表的头部节点为基准节点
//将基准节点的下一个节点挪到头部作为头节点
//当基准节点的next为null,则其已经成为最后一个节点,链表已经反转完成
var reverseList = function (head) {
let currentNode = null;
let headNode = head;
while (head && head.next) {
currentNode = head.next;
head.next = currentNode.next;
currentNode.next = headNode;
headNode = currentNode;
}
return headNode;
};
function array2list(ary) {
if(!ary.length) {
return null
}
var node
var head = {value: ary[0], next: null}
var pnode = head //pnode变量用来保存前一个节点
for(var i = 1; i < ary.length; i++) {
node = {value: ary[i], next:null}
pnode.next = node //将前一个节点的next指向当前节点
pnode = node //将node赋值给pnode
}
return head
}
function list2array(head) {
if(!head) {
return []
}
var result = [head.value]
var restValues = list2array(head.next)
return result.concat(restValues)
}
//题目:给定单链表,将所有奇数节点组合在一起,然后是偶数节点。 //思路 特殊情况,空/单/双链表不需要修改顺序 odd指向奇数节点,even指向偶数节点,evenHead保存第一个偶节点 while循环控制后移,条件:even && odd && even.next,因为even.next需要even存在,所以要先判断even,
因为odd.next夹在了中间,所以只需要判断最后的额 even.next存在 odd在even前,所以先移动odd——先改变.next指针,再将odd/even指向.next的位置。 最后连接奇偶链表,返回头节点head var oddEvenList = function(head) { if (!head || !head.next || !head.next.next) { return head; } let odd = head, //odd指向奇数节点 evenHead= head.next, even = head.next; //even指向偶数节点,evenHead保存第一个偶节点 while (even && odd && even.next) { odd.next = even.next; //奇节点指向奇节点 odd = odd.next; //odd指针移向下一个奇节点 even.next = odd.next; //偶节点指向偶节点 even = even.next; //even指针移向下一个奇节点 } odd.next = evenHead; //连接奇偶链表 return head; };
//思路:
对两个链表,各自设置一个游标节点指向头节点,对游标节点上的数值进行比较,
小节点的next等于小节点的next和大节点的较小值。数值小的那个拿出来放入到合并链表中,
如此递归。
返回小节点。
//考虑代码的鲁棒性,也是递归的终止条件,两个head为null的情况,取对方节点返回。
function Merge(pHead1, pHead2) {
if (!pHead1) {
return pHead2;
}
if (!pHead2) {
return pHead1;
}
let head;
if (pHead1.val < pHead2.val) {
head = pHead1;
head.next = Merge(pHead1.next, pHead2);
} else {
head = pHead2;
head.next = Merge(pHead1, pHead2.next);
}
return head;
}
//思路
1.先找到两个链表的长度length1、length2
2.让长一点的链表先走length2-length1步,让长链表和短链表起点相同
3.两个链表一起前进,比较获得第一个相等的节点
时间复杂度O(length1+length2) 空间复杂度O(0)
function FindFirstCommonNode(pHead1, pHead2) {
if (!pHead1 || !pHead2) { return null; }
// 获取链表长度
let length1 = getLength(pHead1);
let length2 = getLength(pHead2);
// 长链表先行
let lang, short, interval;
if (length1 > length2) {
lang = pHead1;
short = pHead2;
interval = length1 - length2;
} else {
lang = pHead2;
short = pHead1;
interval = length2 - length1;
}
while (interval--) {
lang = lang.next;
}
// 找相同节点
while (lang) {
if (lang === short) {
return lang;
}
lang = lang.next;
short = short.next;
}
return null;
}
function getLength(head) {
let current = head;
let result = 0;
while (current) {
result++;
current = current.next;
}
return result;
}
// 链表节点
class Node {
constructor(element) {
this.element = element
this.prev = null
this.next = null
}
}
// 双向链表
class DoublyLinkedList {
constructor() {
this.head = null
this.tail = null
this.length = 0
}
// 任意位置插入元素
insert(position, element) {
if (position >= 0 && position <= this.length){
const node = new Node(element)
let current = this.head
let previous = null
let index = 0
// 首位
if (position === 0) {
if (!head){
this.head = node
this.tail = node
} else {
node.next = current
this.head = node
current.prev = node
}
// 末位
} else if (position === this.length) {
current = this.tail
current.next = node
node.prev = current
this.tail = node
// 中位
} else {
while (index++ < position) {
previous = current
current = current.next
}
node.next = current
previous.next = node
current.prev = node
node.prev = previous
}
this.length++
return true
}
return false
}
// 移除指定位置元素
removeAt(position) {
if (position > -1 && position < this.length) {
let current = this.head
let previous = null
let index = 0
// 首位
if (position === 0) {
this.head = this.head.next
this.head.prev = null
if (this.length === 1) {
this.tail = null
}
// 末位
} else if (position === this.length - 1) {
this.tail = this.tail.prev
this.tail.next = null
// 中位
} else {
while (index++ < position) {
previous = current
current = current.next
}
previous.next = current.next
current.next.prev = previous
}
this.length--
return current.element
} else {
return null
}
}
// 其他方法...
}
标签:保存 nbsp 时间复杂度 倒数第k个节点 while循环 reverse 单链表 function console
原文地址:https://www.cnblogs.com/huahongcui/p/11520845.html