链表是由节点构成的,这个节点我们可以通过建立一个类来实现它。这个类我们通常选用内部类。
class TestLink{
class Entry{
int data;
Entry next;
public Entry() {
next = null;
}
public Entry(int data) {
this.data = data;
next = null;
}
}
}
链表分为有头结点的链表和无头节点的链表,头结点不储存数据。本篇博客用的是头结点的链表。
注意链表要创建一个构造方法初始化头节点,否则会产生空指针异常
Entry head;//成员变量
public TestLink() {//构造函数
head = new Entry();
}
public void insertHead(int val) {
Entry cur = new Entry(val);//插入的点
cur.next = head.next;//把插入的点next指向head的下一个节点
head.next=cur;//head的next指向插入的点
}
遍历链表的时候要注意while(cur.next!=null)和while(cur!=null)的区别。
前者遍历完cur是链表尾元素,后者遍历完cur是null.
public void insertTail(int val) {
Entry goal = new Entry(val);//要插入的点
Entry cur = head;//用来遍历链表
while(cur.next!=null) {//当cur.next为null即cur已经在链表尾部,退出循环
cur = cur.next;
}
cur.next=goal;//尾插
}
public int getLength() {
Entry cur = head;//用来遍历链表
int count = 0;//计数器
while(cur.next != null) {
cur =cur.next;
count++;
}
return count;
}
public void insert(int val,int post) {
Entry cur = head;//用来遍历链表
if(post >= 0 && post <= this.getLength()) {//找到插入的位置前的的那一个节点
for(int i=0;i
public int valueOf(int val) {
Entry cur = head.next;
int count = 0;
while(cur != null) {
if(cur.val == val) {
count++;
return count;
}
count++;
cur = cur.next;
}
return -1;
}
public void remove(int val) {
int j = valueOf(val);
if(j < 1) {
return;
}
Entry cur = head.next;
Entry pr = head;
for (int i = 1; i < j; i++) {
cur = cur.next;
pr =pr.next;
}
pr.next = cur.next;
}
public Entry reverse(){
Entry pre = null;//
Entry newHead = null;//用来存放逆置后链表的头结点
Entry cur = head;//用来遍历链表
while(cur != null) {//当cur.next==null时即cur到尾部时再循环一次把cur变成头指针。
Entry curNext = cur.next;
if(curNext == null){
newHead = cur;
}
cur.next = pre;
pre = cur;
cur = curNext;
}
return newHead;
}
public Entry getPost(int k) {
if(head == null) {
return -1;
}
Entry cur = head;//用来遍历链表
if(k < 0 || k > this.getLength()) {//如果插入的位置小于零或大于链表长度返回null
return null;
}
for(int i=0;i
public boolean isCut(TestLink t1,TestLink t2) {
TestLink.Entry head1 = t1.head;
TestLink.Entry head2 = t2.head;
int len1 = t1.getLength();
int len2 = t2.getLength();
int myLen = len1-len2;//两条链表的长度差
if(myLen < 0) {//head1指向长链表表头
head1 = t2.head;
head2 = t1.head;
}
for(int i=0;i< myLen;i++) {//head1到在长链表上移动至和端链表对齐
head1 = head1.next;
}
while(head1 != null && head2 !=null && head1 != head2) {//两个遍历节点同时向后移,如果到尾部结束循环或两个节点相交结束循环
head1 = head1.next;
head2 = head2.next;
}
if(head1 == head2) {//相交返回true
return true;
}
return false;
}
public boolean judgeLoop() {
Entry fast = head;//快节点
Entry slow = head;//慢节点
while(fast.next != null && fast.next.next != null) {//当快节点到尾部的时候循环结束,因为快节点每次要后移两格所以要加上fast.next.next不等于空的条件,否则会产生空指针异常
fast = fast.next.next;
slow = slow.next;
if(fast == slow) {//相交返回true
return true;
}
}
return false;
}
public int intoLoop(){
Entry fast = head;
Entry slow = head;
while(fast.next != null && fast.next.next != null){
fast = fast.next.next;
slow = slow.next;
if(fast == slow) {
break;
}
}
slow = head;
while(fast != slow){
fast = fast.next;
slow = slow.next;
}
return slow.data;
}
当快慢节点第二次相遇时,慢节点从第一次到第二次相遇走的距离即环长。
public int getLoopLength() {
Entry fast = head;
Entry slow = head;
boolean tag = false;
int length = 0;
while(fast.next != null && fast.next.next != null) {
fast = fast.next.next;
slow = slow.next;
if(fast == slow && tag == true) {
break;
}
if(fast == slow && tag == false) {
tag =true;
}
if(tag == true ) {
length++;
}
}
return length;
}
将两个递增链表合并成一个递增链表
public static Entry mergeLink(Link l1,Link l2) {
Link.Entry p1 = l1.head.next;
Link.Entry p2 = l2.head.next;
Link.Entry newHead = null;
if(p1.data