链表操作是算法基本功之一,最近看算法,做了几个链表比较基础的题目。大家看这些题目,拿着纸笔画一画,思路瞬间清晰。之后希望持续更新~~。
//定义链表
function Node (value) {
this.value = value;
this.next = null;
}
//把数组转化成链表
function arrToList (arr) {
var head = new Node(arr[0]);
var node = head
for(var i=1; i < arr.length; i++) {
var onode = new Node(arr[i]);
node.next = onode;
node = node.next;
}
return head;
}
//获取链表长度
function getLength (list) {
var length = 0;
while (list != null) {
list = list.next;
length = length + 1;
}
return length;
}
//算法1:翻转链表
function reverseList (head) {
var p = null;
while (head!=null) {
var q = head.next;
head.next = p;
p = head;
head = q;
console.log(q);
}
return p;
}
//算法2: 判断链表是否有环
function hasCircle (head) {
if(head == null || head.next == null) {
return false;
}
var fast = head.next;
var slow = head;
while (fast != slow) {
if (fast == null || fast.next == null) {
return false;
}
fast = fast.next.next;
slow =slow.next;
}
return true;
}
/*var list1 = arrToList([1,2,3,4,5,6,7]);
var list2 = arrToList([8,9,10]);
var list3 =list.next;
list.next.next = list2;
list2.next.next.next = list3;*/
//算法3: 链表相加求和
function addList (list1,list2) {
var carry = 0;
var head = new Node(0);
var point = head;
while (list1!=null && list2!=null) {
//num,carry的取值是重点
var num = (list1.value + list2.value + carry);
point.next = new Node(num % 10);
carry = parseInt(num/10);
list1 = list1.next;
list2 = list2.next;
point = point.next;
}
while (list1!=null) {
var num = (list1.value + carry);
point.next = new Node(num % 10);
carry = parseInt(num/10);
list1 = list1.next;
point = point.next;
}
while (list2!=null) {
var num = (list2.value + carry);
point.next = new Node(num % 10);
carry = parseInt(num/10);
list2 = list2.next;
point = point.next;
}
while (carry !=0) {
var num = carry;
point.next = new Node(num % 10);
carry = parseInt(num/10);
}
return head;
}
//算法4: 删除链表倒数第n个节点
function deleteKpoint (list,k) {
var p = list;
var q = list;
while (k > 0) {
if (list == null) {
return null;
}
list = list.next;
k = k-1;
}
//注意这里的临界值判断
while (list.next != null) {
p = p.next;
list = list.next;
}
p.next = p.next.next;
return q;
}
//算法5: 得到链表的倒数第n个结点
function getKpoint (list,k) {
var p = list;
while (k > 0) {
if (list == null) {
return null;
}
list = list.next;
k = k-1;
}
//注意这里的临界值判断
while (list != null) {
p = p.next;
list = list.next;
}
return p;
}
//算法6: 删除链表中重复的元素
function deleteRepeat (list) {
var p = list;
while (list.next != null) {
if (list.value == list.next.value) {
list.next = list.next.next;
} else {
list = list.next;
}
}
return p;
}
//算法7: 删除链表中重复元素,并删除该结点
function deleteRepeat2 (list) {
var oNode = new Node();
oNode.next = list;
list = oNode;
//下面的if判断谁的value,上面的限制条件临界值就是这个
while (list.next!=null && list.next.next!= null) {
if (list.next.value == list.next.next.value) {
var number = list.next.value;
while (list.next != null && list.next.value == number) {
list.next = list.next.next;
}
} else {
list = list.next;
}
}
return oNode.next;
}
//算法8: 旋转链表
function rotateList(list,k) {
var length = getLength(list);
k = k % length;
var p = list;
var q = list;
while (list.next != null && k > 0) {
list = list.next;
k = k - 1;
}
while (list.next != null) {
list = list.next;
p = p.next;
}
var r = p.next;
list.next = q;
p.next = null;
return r;
}