链表相关算法
链表算法
链表反转
输入一个链表,反转链表后,输出新链表的表头。
Java的链表定义
class LinkNode{
int data;
LinkNode next;
LinkNode(int data)
{
this.data=data;
}
/*****为链表增加节点*****/
public void addLinkNode(int data)
{
LinkNode newnode=new LinkNode(data);//要写在外面而不是if里面!
if(this.next==null)//这里的this每次指向的都是该链表的第一个节点
this.next=newnode;
else
this.next.addLinkNode(data);
}
/****打印节点值*****/
public void print()
{
System.out.print(this.data);
if(this.next!=null)
{
System.out.print("->");
this.next.print();
}
}
}
反转链表
在不产生额外的开销情况下,只是依靠指针的next指向来进行反转,反转过程如下:
代码如下:
public ListNode ReverseList(ListNode head) {
if(head==null)
return null;
ListNode pre=null;
ListNode next=null;
while(head!=null)
{
next=head.next;
head.next=pre;
pre=head;
head=next;
}
return pre;
}
合并递增链表
输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。
public ListNode Merge(ListNode list1,ListNode list2) {
ListNode r = list1;
ListNode p = list2;
ListNode mem1 = null;
ListNode mem2 = null;
while (r != null && p != null) {
while (r != null && p != null) {
if (r.val <= p.val) {
mem1 = r;
r = r.next;
}
else break;
}
if(p!=null)
mem1.next = p;
while (r != null && p != null) {
if (r.val >= p.val) {
mem2 = p;
p = p.next;
}
else break;
}
if(r!=null)
mem2.next = r;
}
return list1;
}
hhhh高兴到起飞,这个是完完全全自己手撕的算法,一边就过而且时间空间效率都超级高嘻嘻嘻
大概捋一下思路:
合并的时候要以其中的某一个链表为标准,这样返回的时候也是返回这个链表的头指针;因为是已经排好序的合并,所以交替找到比另一个小的一部分,这里一部分是重点,而不是自己之前想的一个一个的连接;交替就是两个while循环进行处理,这里 (r != null && p != null)用&而不是||,因为只要有一个链表完成了从头到尾的遍历,这个过程就结束了;
还有一个比较重要的点,这是每次画代码执行流程的时候总结出来的,当遍历到p=null时,说明操作已经完成,如果再次连接.next的话,就会导致已经连接后面的数字被null替换了。