LinkedList小练习及相关算法

  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 }

 

posted @ 2017-07-06 16:30  chump  阅读(304)  评论(0编辑  收藏  举报