-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
XiaTianliang
committed
Oct 22, 2016
1 parent
848e1e7
commit a36dc1b
Showing
3 changed files
with
363 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package linkList; | ||
|
||
import binarytree.TreeNode; | ||
|
||
/** | ||
* Created by tianliangxia on 16-10-22. | ||
*/ | ||
public class ListNode { | ||
public int val; | ||
public ListNode next=null; | ||
public ListNode(int val){ | ||
this.val = val; | ||
} | ||
|
||
@Override | ||
public String toString(){ | ||
StringBuilder stringBuilder = new StringBuilder(); | ||
ListNode node = this; | ||
while (node!=null){ | ||
stringBuilder.append(node.val+"->"); | ||
node=node.next; | ||
} | ||
stringBuilder.delete(stringBuilder.length()-2,stringBuilder.length()); | ||
return stringBuilder.toString(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,211 @@ | ||
package linkList; | ||
|
||
import utils.StringUtils; | ||
|
||
/** | ||
* Created by tianliangxia on 16-10-22. | ||
*/ | ||
public class ListNodes { | ||
|
||
public static ListNode construct(int[] vals){ | ||
if(vals == null || vals.length == 0) | ||
return null; | ||
ListNode root = new ListNode(0); | ||
ListNode head = root; | ||
for(int val: vals){ | ||
head.next = new ListNode(val); | ||
head = head.next; | ||
} | ||
return root.next; | ||
} | ||
|
||
public static ListNode construct(String str){ | ||
if(StringUtils.isEmpty(str)) | ||
return null; | ||
String[] vals; | ||
if(str.charAt(0) == '[' && str.charAt(str.length()-1)==']'){ | ||
str = str.substring(1, str.length()-1); | ||
} | ||
if(str.contains("->")){ | ||
vals = str.split("->"); | ||
}else if(str.contains(",")){ | ||
vals = str.split(","); | ||
}else{ | ||
vals = new String[1]; | ||
vals[0]=str; | ||
} | ||
|
||
int[] ints = new int[vals.length]; | ||
for(int i=0;i<ints.length;i++){ | ||
ints[i] = Integer.valueOf(vals[i]); | ||
} | ||
|
||
return construct(ints); | ||
} | ||
|
||
public static ListNode sort(ListNode root){ | ||
if(root == null || root.next == null) | ||
return root; | ||
ListNode mid = partition(root); | ||
root = sort(root); | ||
mid = sort(mid); | ||
return merge(root, mid); | ||
} | ||
|
||
private static ListNode partition(ListNode head){ | ||
int count = 0; | ||
ListNode p = head; | ||
while (p!=null){ | ||
count++; | ||
p=p.next; | ||
} | ||
count/=2; | ||
p=head; | ||
for(int i=0;i<count-1;i++){ | ||
p=p.next; | ||
} | ||
ListNode tmp = p.next; | ||
p.next = null; | ||
return tmp; | ||
} | ||
public static ListNode merge(ListNode left, ListNode right){ | ||
ListNode root = new ListNode(0); | ||
ListNode head = root; | ||
while (left!=null && right!=null){ | ||
if(left.val <= right.val){ | ||
head.next=left; | ||
head=head.next; | ||
left=left.next; | ||
}else { | ||
head.next=right; | ||
head=head.next; | ||
right=right.next; | ||
} | ||
} | ||
if(left!=null){ | ||
head.next=left; | ||
} | ||
if(right!=null){ | ||
head.next=right; | ||
} | ||
return root.next; | ||
} | ||
|
||
/*** | ||
* 1->2->2->3 => 1->2->3 | ||
* @param head | ||
* @return | ||
*/ | ||
public static void removeDuplication(ListNode head){ | ||
if(head == null || head.next == null) | ||
return ; | ||
|
||
ListNode p = head; | ||
while (p != null && p.next != null){ | ||
if(p.val == p.next.val){ | ||
p.next = p.next.next; | ||
}else { | ||
p=p.next; | ||
} | ||
} | ||
} | ||
|
||
/*** | ||
* 1->2->2->3 => 1->3 | ||
* @param head | ||
* @return | ||
*/ | ||
|
||
public static ListNode removeDuplication2(ListNode head){ | ||
if(head == null || head.next == null) | ||
return head; | ||
|
||
ListNode root = new ListNode(0); | ||
root.next = head; | ||
ListNode pre = root; | ||
while (head != null && head.next != null){ | ||
ListNode p = head.next; | ||
while (p != null && p.val == head.val){ | ||
p=p.next; | ||
} | ||
if(p == null){ | ||
pre.next = p; | ||
} | ||
if(p == head.next){ | ||
head = head.next; | ||
pre = pre.next; | ||
}else { | ||
pre.next = p; | ||
head = p.next; | ||
} | ||
} | ||
|
||
return root.next; | ||
} | ||
|
||
/*** | ||
* 判断是否有环 | ||
* @param root | ||
* @return | ||
*/ | ||
public static boolean checkRing(ListNode root){ | ||
if(root == null || root.next == null) | ||
return false; | ||
ListNode fast = root, slow = root; | ||
while (fast.next != null && fast.next.next != null){ | ||
fast = fast.next.next; | ||
slow = slow.next; | ||
if(fast == slow) | ||
return true; | ||
} | ||
return false; | ||
} | ||
|
||
/*** | ||
* 修改链表指向 | ||
* @param head | ||
* @return | ||
*/ | ||
public static boolean checkRing2(ListNode head){ | ||
if(head == null) | ||
return false; | ||
ListNode root = new ListNode(0); | ||
ListNode pre = root, post; | ||
while (head != null){ | ||
post = head.next; | ||
head.next = pre; | ||
pre = head; | ||
head = post; | ||
if(head == root) | ||
return true; | ||
} | ||
return false; | ||
} | ||
|
||
/*** | ||
* 找到环的入口 | ||
* @param head | ||
* @return | ||
*/ | ||
public static ListNode findRingEntry(ListNode head){ | ||
if(head == null || head.next == null) | ||
return null; | ||
ListNode fast = head, slow = head; | ||
while (fast != null && fast.next != null){ | ||
fast = fast.next.next; | ||
slow = slow.next; | ||
if(fast == slow) | ||
break; | ||
} | ||
if(fast == null || fast.next == null) | ||
return null; | ||
|
||
fast = head; | ||
while (fast != slow){ | ||
fast = fast.next; | ||
slow = slow.next; | ||
} | ||
return fast; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
package linkList; | ||
|
||
import org.junit.Test; | ||
|
||
import static org.junit.Assert.*; | ||
|
||
/** | ||
* Created by tianliangxia on 16-10-22. | ||
*/ | ||
public class ListNodesTest { | ||
|
||
@Test | ||
public void constructTest(){ | ||
int[] vals = new int[]{1,2,3,4,5}; | ||
ListNode node = ListNodes.construct(vals); | ||
assertEquals(node.toString(), "1->2->3->4->5"); | ||
} | ||
|
||
@Test | ||
public void constructTest2(){ | ||
ListNode node = ListNodes.construct("1->2->3->4->5"); | ||
assertEquals(node.toString(), "1->2->3->4->5"); | ||
|
||
node = ListNodes.construct("1,2,3,4,5"); | ||
assertEquals(node.toString(), "1->2->3->4->5"); | ||
|
||
node = ListNodes.construct("[1,2,3,4,5]"); | ||
assertEquals(node.toString(), "1->2->3->4->5"); | ||
|
||
node = ListNodes.construct("[1->2->3->4->5]"); | ||
assertEquals(node.toString(), "1->2->3->4->5"); | ||
|
||
node = ListNodes.construct("1"); | ||
assertEquals(node.toString(), "1"); | ||
|
||
node = ListNodes.construct("[1]"); | ||
assertEquals(node.toString(), "1"); | ||
|
||
} | ||
|
||
|
||
@Test | ||
public void testSort(){ | ||
ListNode root = ListNodes.construct("5,4,3,2,1"); | ||
ListNode res = ListNodes.sort(root); | ||
assertEquals("1->2->3->4->5",res.toString()); | ||
} | ||
|
||
@Test | ||
public void mergeTest(){ | ||
ListNode l1 = ListNodes.construct("1,3"); | ||
ListNode l2 = ListNodes.construct("2,4,6"); | ||
ListNode merge = ListNodes.merge(l1, l2); | ||
assertEquals("1->2->3->4->6", merge.toString()); | ||
|
||
l2 = ListNodes.construct("2,4,6"); | ||
merge = ListNodes.merge(null, l2); | ||
assertEquals("2->4->6", merge.toString()); | ||
} | ||
|
||
@Test | ||
public void removeDuplicationTest(){ | ||
ListNode root = ListNodes.construct("1,2,2,3,3,3,4"); | ||
ListNodes.removeDuplication(root); | ||
assertEquals("1->2->3->4", root.toString()); | ||
|
||
root = ListNodes.construct("1,1"); | ||
ListNodes.removeDuplication(root); | ||
assertEquals("1", root.toString()); | ||
} | ||
|
||
@Test | ||
public void removeDuplication2Test(){ | ||
ListNode root = ListNodes.construct("1,2,2,3,3,3,4"); | ||
ListNodes.removeDuplication2(root); | ||
assertEquals("1->4", root.toString()); | ||
} | ||
|
||
@Test | ||
public void checkRing1Test(){ | ||
//ListNode line = ListNodes.construct("1,2,3"); | ||
ListNode ring = ListNodes.construct("4,5,6,7,8"); | ||
ListNode p = ring; | ||
while (p.next != null) | ||
p = p.next; | ||
p.next = ring; | ||
|
||
assertEquals(true, ListNodes.checkRing(ring)); | ||
assertEquals(true, ListNodes.checkRing2(ring)); | ||
} | ||
|
||
@Test | ||
public void checkRing1Test2(){ | ||
ListNode line = ListNodes.construct("1,2,3"); | ||
ListNode ring = ListNodes.construct("4,5,6,7,8"); | ||
ListNode p = ring; | ||
while (p.next != null) | ||
p = p.next; | ||
p.next = ring; | ||
p=line; | ||
while (p.next != null) | ||
p=p.next; | ||
p.next = ring; | ||
|
||
assertEquals(true, ListNodes.checkRing(line)); | ||
assertEquals(true, ListNodes.checkRing2(line)); | ||
} | ||
|
||
@Test | ||
public void findRingEntryTest(){ | ||
ListNode line = ListNodes.construct("1,2,3"); | ||
ListNode ring = ListNodes.construct("4,5,6,7,8"); | ||
ListNode p = ring; | ||
while (p.next != null) | ||
p = p.next; | ||
p.next = ring; | ||
p=line; | ||
while (p.next != null) | ||
p=p.next; | ||
p.next = ring; | ||
assertEquals(ring, ListNodes.findRingEntry(line)); | ||
} | ||
|
||
|
||
|
||
} |