单链表的节点数,合并,相交,反转
Posted 等风来
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了单链表的节点数,合并,相交,反转相关的知识,希望对你有一定的参考价值。
1.求节点数
function getNodeNum(head){ if(head == null){ return 0; } var len = 0, cur = head; while(cur != null){ len++; cur = cur.next; } return len; }
2. 查找倒数第K个节点
//可以统计节点个数,再找到第n-(k-1)个节点,最后一个节点的倒数第1个,倒数第K个节点是n-(k-1) //这里使用双指针法,两个指针,第一个指针先走到第k个节点,前后两个指针相差k-1, //这样两个指针一起走,首个指针走到最后一个节点,第二个节点指向倒数第k个节点 function getLastKthNode(head,k){ if(k == 0 || head == null){ return null; } var ahead = head, behind = head; while(k > 1 && ahead != null){ ahead = ahead.next; k--; } //说明链表长度不足k if(k > 1 || ahead == null){ return null; } while(ahead.next != null){ behind = behind.next; ahead = ahead.next; } return behind; }
3.查找中间节点
//用双指针法,快慢指针,慢指针每次一步,快指针每次两步,当快指针走到尾部,慢指针走到中间节点 function getMiddleNode(head){ if(head == null || head.next == null){ return head; } var ahead = null, behind = null; while(ahead.next != null){ ahead = ahead.next; behind = behind.next; if(ahead.next != null){ ahead = ahead.next; } } return behind; }
4. 合并两个有序链表为一个新的有序链表
function mergeSortedList(head1,head2){ if(head1 == null){ return head2; } if(head2 == null){ return head1; } var mhead = new Node(); var h1 = head1.next, h2 = head2.next; if(h1.val < h2.val){ mhead.next = h1; mhead.next.next = null; h1 = h1.next; } else{ mhead.next = h2; mhead.next.next = null; h2 = h2.next; } var temp = mhead; while(h1 != null && h2 != null){ if(h1.key < h2.key){ temp.next = h1; h1 = h1.next; temp = temp.next; temp.next = null; } else{ temp.next = h2; h2 = h2.next; temp = temp.next; temp.next = null; } } if(h1 != null){ temp.next = h1; } else{ temp.next = h2; } return mhead; }
5.判断两个单链表是否相交
//判断依据,两个单链表相交之后,其后面的链表是共有的,形成一个三条线共用一个顶点的形状 //因此判断两个链表的最后一个点是否相同,即可判定是否有交点 function IsIntersected(head1,head2){ if(head1 == null || head2 == null){ return false; } var tail1 = head1, tail2 = head2; while(tail1.next != null){ tail1 = tail1.next; } while(tail2.next != null){ tail2 = tail2.next; } return tail1 == tail2; }
6.求两个链表的第一个交点
//求两个链表的第一个交点,先判断是否相交,如果不相交,返回null,否则,将长度大的链表的指针 //向前移动两个链表的长度差距离,这样两个链表指针距离交点的长度相等,两个指针同时向前移动, //当指针相同时候,即为第一个交点 function getFirstCommonNode(head1,head2){ if(head1 == null || head2 == null){ return false; } var tail1 = head1, len1 = 0, tail2 = head2, len2 = 0; while(tail1.next != null){ tail1 = tail1.next; len1++; } while(tail2.next != null){ tail2 = tail2.next; len2++; } if(tail1 != tail2){ return null; } var count = len1 - len2; count = Math.abs(count); tail1 = head1; tail2 = head2; if(count > 0){ while(count--){ tail1 = tail1.next; } } else{ while(count--){ tail2 = tail2.next; } } while(tail1 != tail2){ tail1 = tail1.next; tail2 = tail2.next; } return tail1; }
7.反转链表
//从尾到头打印链表,对于颠倒顺序的问题,首先想到栈,先进后出,要么使用自定义栈, //要么使用系统栈,即递归 function reverseTraverse(head){ var stack = []; var cur = head; while(cur != null){ stack.push(cur); } while(stack.length > 0){ var node = stack.pop(); console.log(‘val ‘ + node.val) } } //使用递归(系统栈,递归栈的思想) function reverseTraverse(head){ //递归出口,出栈条件 if(head == null){ return; } else{ reverseTraverse(head.next); //递归出口,即出栈时候,才会执行此句打印,所以是倒着打印 console.log(‘val ‘ + head.val); } } //反转链表,利用头插法,将后面的节点不断插入到head节点后面 function reverse(head){ if(head == null || head.next == null){ return; } var cur = head.next, next = cur.next; //第二个节点与第三个节点断开,否则会形成环 cur.next = null; while(next != null){ cur = next; next = cur.next; cur.next = head.next; head.next = cur; } }
参考:http://blog.csdn.net/luckyxiaoqiang/article/details/7393134
以上是关于单链表的节点数,合并,相交,反转的主要内容,如果未能解决你的问题,请参考以下文章