1 /** 2 * Created by chump on 2017/7/6. 3 */ 4 5 import java.lang.reflect.WildcardType; 6 import java.nio.file.NotLinkException; 7 import java.util.Stack; 8 9 /** 10 * Created with IntelliJ IDEA 11 * Created By chump 12 * Date: 2017/7/6 13 * Time: 8:33 14 */ 15 public class LinkedList { 16 //求链表长度 17 public int Length(ListNode head) { 18 int length = 0; 19 ListNode currentNode = head; 20 while (currentNode != null) { 21 currentNode = currentNode.getNext(); 22 length++; 23 } 24 return length; 25 } 26 27 //链表中插入节点 28 public ListNode InsertInLinkedList(ListNode head, ListNode nodeToInsert, int position) { 29 if (head == null) //若是链表为空,则直接插入 30 return nodeToInsert; 31 int size = Length(head); 32 if (position < 1 || position > size + 1) { 33 System.out.println("插入位置不合理,有效插入位置为:1-" + size + 1); 34 return head; 35 } 36 37 if (position == 1) { //在链表头插入 38 nodeToInsert.setNext(head); 39 return nodeToInsert; 40 } else { //在链表中间或末尾插入 41 int index = 0; 42 ListNode preNode = head; 43 while (index < position) { 44 preNode = preNode.getNext(); 45 index++; 46 } 47 ListNode currentNode = preNode.getNext(); 48 nodeToInsert.setNext(currentNode); 49 preNode.setNext(nodeToInsert); 50 } 51 return head; 52 53 } 54 55 //删除链表中的节点 56 public ListNode DeleteNode(ListNode head, int position) { 57 if (head == null) { 58 System.out.println("链表为空!"); 59 return null; 60 } 61 int size = Length(head); 62 if (position < 1 || position > size + 1) { 63 System.out.println("删除位置不合理,有效删除位置为1-" + size + 1); 64 return head; 65 } 66 if (position == 1) { //删除链表的头节点 67 ListNode currentNode = head.getNext(); 68 head = null; 69 return currentNode; 70 } else { //删除中间节点或尾节点 71 int index = 1; 72 ListNode previousNode = head; 73 while (index < position) { 74 previousNode = previousNode.getNext(); 75 index++; 76 } 77 ListNode currentNode = previousNode.getNext(); 78 previousNode.setNext(currentNode.getNext()); 79 currentNode = null; 80 } 81 return head; 82 } 83 84 //删除整个单向链表 85 public void DeleteLinkedList(ListNode head) { 86 ListNode auxilaryNode, currentNode = head; //auxiliary 辅助节点 87 while (currentNode != null) { 88 auxilaryNode = currentNode.getNext(); 89 currentNode = null; 90 currentNode = auxilaryNode; 91 } 92 } 93 //判断单向链表是否有环(Floyd算法,双指针思想) 94 public boolean IsLinkedListHasLoop(ListNode head) { 95 if (head == null) 96 return false ; 97 ListNode sloPtr = head, fasPtr = head; 98 while (sloPtr.getNext() != null && fasPtr.getNext().getNext() != null) { 99 sloPtr = sloPtr.getNext(); //初始节点相同,须要先走再断定 100 fasPtr = fasPtr.getNext().getNext(); 101 if (sloPtr == fasPtr) 102 return true; 103 } 104 return false; 105 } 106 //找到含有环的链表中的起始节点(IsLinkedListHasLoop(head))为true 107 public ListNode FindFirstLoopNode(ListNode head){ 108 ListNode sloPtr = head ,fasPtr = head ; 109 110 while (sloPtr.getNext()!=null&&fasPtr.getNext().getNext()!=null){ 111 sloPtr = sloPtr.getNext(); 112 fasPtr = fasPtr.getNext().getNext(); 113 if (sloPtr==fasPtr) 114 break; 115 } 116 fasPtr = head ; 117 //由两指针移动方式可知,慢指针位于快指针和链表表头位置的中点, 118 //分别从慢指针位置和表头开始移动,可知一旦进入环,它们就会相遇 119 while (fasPtr!=sloPtr){ 120 fasPtr = fasPtr.getNext(); 121 sloPtr = sloPtr.getNext(); 122 } 123 return fasPtr ; 124 } 125 //逆置单向链表 126 public ListNode ReverseLinkedList(ListNode head){ 127 if (head == null) 128 return head ; 129 ListNode temp = null ,nextNode = null ; 130 while (head!=null){ 131 nextNode = head.getNext() ; 132 head.setNext(temp); 133 temp = head ; 134 head = nextNode ; 135 } 136 return temp ; 137 } 138 //从表尾输出链表 (递归遍历到表尾,返回时输出元素) 139 public void PrintFromEnd(ListNode head){ 140 if (head == null) 141 return; 142 PrintFromEnd(head.getNext()); 143 System.out.println(head.getData()); 144 } 145 //求两个单向链表的合并点 146 public ListNode FindMergeNode(ListNode head1,ListNode head2){ 147 Stack stack1 = new Stack(); 148 Stack stack2 = new Stack(); 149 if ((head1 == null) && (head2 == null)) 150 return null ; 151 ListNode listNode1 = head1 ; 152 ListNode listNode2 = head2 ; 153 while (listNode1!=null){ 154 stack1.push(listNode1); 155 listNode1 = listNode1.getNext(); 156 } 157 while (listNode2!=null){ 158 stack2.push(listNode2); 159 listNode2 = listNode2.getNext(); 160 } 161 ListNode temp = null ; 162 while (stack1.peek() == stack2.peek()){ 163 temp = (ListNode) stack1.pop(); 164 stack2.pop(); 165 } 166 return temp ; 167 } 168 //逐对逆置链表 (递归) 169 public ListNode ReversePairRecursive(ListNode head){ 170 ListNode temp ; 171 if (head == null||head.getNext()==null) 172 return head ; 173 else { 174 temp = head.getNext(); 175 head.setNext(temp.getNext()); 176 temp.setNext(head); 177 head = temp ; 178 ReverseLinkedList(head.getNext().getNext()); 179 return head ; 180 } 181 } 182 //逐对逆置链表 (迭代) 183 public ListNode ReversePairIterative(ListNode head){ 184 ListNode temp1 = null ; 185 ListNode temp2 = null ; 186 while (head!=null&&head.getNext()!=null){ 187 temp1 = head ; 188 temp2 = head.getNext(); 189 temp2.setNext(temp1); 190 temp1.setNext(temp2.getNext()); 191 head = head.getNext().getNext(); 192 } 193 return head ; 194 } 195 //约瑟夫环问题 循环链表问题 196 /* 197 N我的想选出一个领头人,它们排成一个环,沿着环每数到第M我的就从环中排除该人, 198 并从下一我的开始从新数。找出最后一个留在环中的人。 199 */ 200 public void GetJosephusPosition(int n,int skip){ 201 ListNode p = new ListNode() ,q ; 202 p.setData(1); 203 q = p ; 204 //创建循环链表 205 for (int i = 2 ;i<= n ;i++){ 206 ListNode temp = new ListNode(i); 207 p.setNext(temp); 208 p = temp ; 209 } 210 p.setNext(q); //使表尾节点指向表头 211 212 //若是链表长度大于1,剔除第skip个元素 213 for (int count = n;count>1;count--){ 214 for (int i = 0 ;i<skip-1;i++){ 215 p = p.getNext() ; 216 } 217 p.setNext(p.getNext().getNext()); //删除剔除的元素 218 } 219 System.out.println("The Least one :"+p.getData()); 220 221 } 222 223 }