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 }