阅读更多
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.HashMap;
import org.apache.commons.io.IOUtils;
//不带头结点的链表
public class LinkedList3
{
@SuppressWarnings("unchecked")
public static void main(String[] args) throws Exception
{
LinkedList3 list = new LinkedList3(1, 2, 3, 4, 5);
// System.out.println(list.isEmpty());
// System.out.println(list.size());
System.out.println(list);
// Entry entry = list.getEntry(2);
// LinkedList3 n_list = (LinkedList3) list.clone();
// System.out.println(n_list);
// LinkedList3.reverseListByIterator(n_list);
// LinkedList3.reverseListByRecursion(n_list);
// System.out.println(n_list);
// Entry entry = LinkedList3.lastIndexOf(list, 6);
// Entry entry = LinkedList3.lastIndexOfByArray(list, 2);
// Entry entry = LinkedList3.getMiddleEntry(list);
// LinkedList3.reversePrintListByStack(list);
// LinkedList3.reversePrintListByRecursion(list);
// LinkedList3 list1 = new LinkedList3();
// LinkedList3 list2 = new LinkedList3(2, 3, 4, 5);
// System.out.println(list1);
// System.out.println(list2);
// LinkedList3 list3 = LinkedList3.mergeList(list1, list2);
// System.out.println(list3);
// LinkedList3 list1 = new LinkedList3(1, 2, 3, 4);
// list1.getEntry(3).setNext(list1.getEntry(3));
// System.out.println(LinkedList3.hasLoop(list1));
// Entry entry = LinkedList3.getFirstEnterLoopEntry(list1);
// Entry entry = LinkedList3.getFirstEnterLoopEntry2(list1);
// LinkedList3 list1 = new LinkedList3(1, 2, 3, 4, 5);
// LinkedList3 list2 = new LinkedList3(11, 22, 33, 44,
// 55);
// list2.getEntry(1).setNext(list1.getEntry(0));
// list2.getEntry(3).setNext(list1.getEntry(2));
// System.out.println(list1);
// System.out.println(list2);
// System.out.println(LinkedList3.isIntersect(list1, list2));
// System.out.println(LinkedList3.isIntersect2(list1, list2));
// System.out.println(LinkedList3.isIntersect3(list1, list2));
//
// Entry entry = LinkedList3.getFirstIntersectEntry(list1,
// list2);
// System.out.println(entry == null ? "not found" : entry.element);
// LinkedList3.deleteEntry(list, list.getEntry(0));
// System.out.println(list);
}
// 头指针
private Entry head;
public LinkedList3()
{
//初始化头指针为空
head = null;
}
public LinkedList3(T... elements)
{
this();
Entry tail = head;
for (T element : elements)
{
Entry newEntry = new Entry(element);
//第一次头指针为空
if (head == null)
{
head = newEntry;
tail = head;
}
else
{
//头指针不为空,直接用尾指针来添加节点
tail.next = newEntry;
tail = newEntry;
}
}
}
public boolean isEmpty()
{
return head == null;
}
// 1. 求单链表中结点的个数
public int size()
{
if (isEmpty())
return 0;
Entry curEntry = head;
int c = 0;
while (curEntry != null)
{
c++;
curEntry = curEntry.next;
}
return c;
}
// 2. 将单链表反转: reverseList(遍历)
public static void reverseListByIterator(LinkedList3 list)
{
Entry curEntry = list.head;
Entry nextEntry = null;
Entry nextnextEntry = null;
if (curEntry == null || curEntry.next == null)
return;
while (curEntry.next != null)
{
nextEntry = curEntry.next;
nextnextEntry = nextEntry.next;
nextEntry.next = list.head;
list.head = nextEntry;
curEntry.next = nextnextEntry;
}
}
// 2. 将单链表反转: reverseListRec(递归)
public static void reverseListByRecursion(LinkedList3 list)
{
if (list.head == null || list.head.next == null)
return;
list.head = reverseList(list.head);
}
private static Entry reverseList(Entry entry)
{
if (entry.next == null)
return entry;
Entry newHead = reverseList(entry.next);
entry.next.next = entry;
entry.next = null;
return newHead;
}
// 3. 查找单链表中的倒数第K个结点(k > 0)
public static Entry lastIndexOf(LinkedList3 list, int n)
{
if (n <= 0)
throw new IllegalArgumentException("The input number should be greater than zero");
Entry first = list.getEntry(n - 1);
Entry second = list.head;
while (first.next != null)
{
first = first.next;
second = second.next;
}
return second;
}
// 3. 查找单链表中的倒数第K个结点(k > 0),数组实现
@SuppressWarnings("unchecked")
public static Entry lastIndexOfByArray(LinkedList3 list, int n)
{
if (n <= 0)
throw new IllegalArgumentException("The input number should be greater than zero");
Object[] storage = new Object[n];
int index = 0, c = 0;
Entry curEntry = list.head;
while (curEntry != null)
{
storage[index] = curEntry;
curEntry = curEntry.next;
index = (index + 1) % n;
c++;
}
if (storage[index] == null)
throw new IllegalStateException("less than " + n + " elemements, current is " + c);
return Entry.class.cast(storage[index]);
}
// 4. 查找单链表的中间结点
public static Entry getMiddleEntry(LinkedList3 list)
{
if (list.isEmpty())
return null;
Entry first = list.head;
Entry second = list.head;
while (first.next != null && first.next.next != null)
{
first = first.next.next;
second = second.next;
}
return second;
}
// 5. 从尾到头打印单链表,通过栈实现
public static void reversePrintListByStack(LinkedList3 list)
{
java.util.LinkedList> stack = new java.util.LinkedList>();
Entry curEntry = list.head;
while (curEntry != null)
{
stack.push(curEntry);
curEntry = curEntry.next;
}
String result = "[";
while (!stack.isEmpty())
result += stack.pop().element + ", ";
if (result.length() > 1)
result = result.substring(0, result.length() - 2);
result += "]";
System.out.println(result);
}
// 5. 从尾到头打印单链表(递归)
public static void reversePrintListByRecursion(LinkedList3 list)
{
String result = reversePrintList(list.head);
if (result.length() > 0)
result = result.substring(0, result.length() - 2);
result = "[" + result + "]";
System.out.println(result);
}
private static String reversePrintList(Entry entry)
{
if (entry == null)
return "";
String result = reversePrintList(entry.next);
result += entry.element;
return result + ", ";
}
// 6. 已知两个单链表list1和list2各自有序,把它们合并成一个链表依然有序
@SuppressWarnings("unchecked")
public static LinkedList3 mergeList(LinkedList3 list1, LinkedList3 list2)
{
Entry curEntry1 = list1.head;
Entry curEntry2 = list2.head;
Entry newHead = null;
Entry curEntry = newHead;
//先处理新的头指针为空的情况
if (curEntry1 != null && curEntry2 != null)
{
if (((Comparable) curEntry1.element).compareTo(curEntry2.element) < 0)
{
newHead = new Entry(curEntry1.element, null);
curEntry1 = curEntry1.next;
}
else
{
newHead = new Entry(curEntry2.element, null);
curEntry2 = curEntry2.next;
}
curEntry = newHead;
}
else if (curEntry1 != null)
{
newHead = new Entry(curEntry1.element, null);
curEntry = newHead;
curEntry1 = curEntry1.next;
}
else if (curEntry2 != null)
{
newHead = new Entry(curEntry2.element, null);
curEntry = newHead;
curEntry2 = curEntry2.next;
}
while (curEntry1 != null && curEntry2 != null)
{
if (((Comparable) curEntry1.element).compareTo(curEntry2.element) < 0)
{
curEntry.next = new Entry(curEntry1.element, null);
curEntry = curEntry.next;
curEntry1 = curEntry1.next;
}
else
{
curEntry.next = new Entry(curEntry2.element, null);
curEntry = curEntry.next;
curEntry2 = curEntry2.next;
}
}
while (curEntry1 != null)
{
curEntry.next = new Entry(curEntry1.element, null);
curEntry = curEntry.next;
curEntry1 = curEntry1.next;
}
while (curEntry2 != null)
{
curEntry.next = new Entry(curEntry2.element, null);
curEntry = curEntry.next;
curEntry2 = curEntry2.next;
}
LinkedList3 result = new LinkedList3();
result.setHead(newHead);
return result;
}
// 7. 判断一个单链表中是否有环
public static boolean hasLoop(LinkedList3 list)
{
Entry first = list.head;
Entry second = list.head;
while (first != null && first.next != null)
{
first = first.next.next;
second = second.next;
if (first == second)
return true;
}
return false;
}
// 8. 已知一个单链表中存在环,求进入环中的第一个节点
public static Entry getFirstEnterLoopEntry(LinkedList3 list)
{
Entry first = list.head;
Entry second = list.head;
while (first != null && first.next != null)
{
first = first.next.next;
second = second.next;
if (first == second)
break;
}
if (first == null || first.next == null)
return null;
second = list.head;
while (first != second)
{
first = first.next;
second = second.next;
}
return first;
}
// 8. 已知一个单链表中存在环,求进入环中的第一个节点 HashMap实现
public static Entry getFirstEnterLoopEntry2(LinkedList3 list)
{
HashMap, Boolean> storage = new HashMap, Boolean>();
Entry curEntry = list.head;
while (curEntry != null)
{
if (storage.get(curEntry) == Boolean.TRUE)
return curEntry;
else
{
storage.put(curEntry, Boolean.TRUE);
curEntry = curEntry.next;
}
}
return null;
}
// 9. 判断两个单链表是否相交 HashMap实现
public static boolean isIntersect(LinkedList3 list1, LinkedList3 list2)
{
if (list1.isEmpty() || list2.isEmpty())
return false;
HashMap, Boolean> storage = new HashMap, Boolean>();
Entry curEntry1 = list1.head;
while (curEntry1 != null)
{
storage.put(curEntry1, Boolean.TRUE);
curEntry1 = curEntry1.next;
}
Entry curEntry2 = list2.head;
while (curEntry2 != null)
{
if (storage.get(curEntry2) == Boolean.TRUE)
return true;
curEntry2 = curEntry2.next;
}
return false;
}
// 9. 判断两个单链表是否相交 如果相交 让第一个链表的next指向第二个链表的头指针,可以构成一个环
public static boolean isIntersect2(LinkedList3 list1, LinkedList3 list2)
{
if (list1.isEmpty() || list2.isEmpty())
return false;
Entry curEntry1 = list1.head;
Entry curEntry2 = list2.head;
while (curEntry1.next != null)
curEntry1 = curEntry1.next;
curEntry1.next = list2.head;
boolean exist = false;
while (curEntry2.next != null)
{
if (curEntry2.next == list2.head)
{
exist = true;
break;
}
curEntry2 = curEntry2.next;
}
curEntry1.next = null;
return exist;
}
// 9. 判断两个单链表是否相交 如果相交 最后一个节点一定相等
public static boolean isIntersect3(LinkedList3 list1, LinkedList3 list2)
{
if (list1.isEmpty() || list2.isEmpty())
return false;
Entry curEntry1 = list1.head;
Entry curEntry2 = list2.head;
while (curEntry1.next != null)
curEntry1 = curEntry1.next;
while (curEntry2.next != null)
curEntry2 = curEntry2.next;
if (curEntry1 == curEntry2)
return true;
return false;
}
// 10. 求两个单链表相交的第一个节点
public static Entry getFirstIntersectEntry(LinkedList3 list1, LinkedList3 list2)
{
int m = list1.size();
int n = list2.size();
Entry curEntry1 = list1.head;
Entry curEntry2 = list2.head;
int c;
if (m > n)
{
c = m - n;
while (c != 0)
{
curEntry1 = curEntry1.next;
c--;
}
}
else
{
c = n - m;
while (c != 0)
{
curEntry2 = curEntry2.next;
c--;
}
}
while (curEntry1 != null)
{
if (curEntry1 == curEntry2)
return curEntry1;
curEntry1 = curEntry1.next;
curEntry2 = curEntry2.next;
}
return null;
}
// 11. 给出一单链表头指针pHead和一节点指针pToBeDeleted,O(1)时间复杂度删除节点pToBeDeleted: delete
public static void deleteEntry(LinkedList3 list, Entry entry)
{
if (entry == null)
return;
if (entry.next != null)
{
entry.element = entry.next.element;
entry.next = entry.next.next;
}
else
{
if (entry == list.head)
list.head = entry.next;
else
{
Entry preEntry = list.head;
while (preEntry != null)
{
if (preEntry.next == entry)
break;
preEntry = preEntry.next;
}
preEntry.next = preEntry.next.next;
}
}
}
public void setHead(Entry head)
{
this.head = head;
}
public Entry createEntry(T element)
{
return new Entry(element);
}
public Entry getEntry(int index)
{
if (index < 0)
throw new IllegalArgumentException("index should be a positive number or zero");
int c = 0;
Entry curEntry = head;
while (curEntry != null && c < index)
{
c++;
curEntry = curEntry.next;
}
if (curEntry == null)
throw new IllegalStateException("less than " + (index + 1) + " elements, current is " + c);
return curEntry;
}
@SuppressWarnings("unchecked")
@Override
public Object clone() throws CloneNotSupportedException
{
try
{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
try
{
oos.writeObject(head);
oos.flush();
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray()));
try
{
LinkedList3 result = new LinkedList3();
result.setHead(Entry.class.cast(ois.readObject()));
return result;
}
finally
{
IOUtils.closeQuietly(ois);
}
}
finally
{
IOUtils.closeQuietly(oos);
}
}
catch (Exception e)
{
e.printStackTrace();
return super.clone();
}
}
@Override
public String toString()
{
String result = "[";
Entry curEntry = head;
while (curEntry != null)
{
result += curEntry.element;
curEntry = curEntry.next;
if (curEntry != null)
result += ", ";
}
return result + "]";
}
public static class Entry implements Serializable
{
private static final long serialVersionUID = 1L;
T element;
Entry next;
Entry(T element)
{
this(element, null);
}
Entry(T element, Entry next)
{
this.element = element;
this.next = next;
}
public void setElement(T element)
{
this.element = element;
}
public T getElement()
{
return element;
}
public void setNext(Entry next)
{
this.next = next;
}
public Entry getNext()
{
return next;
}
@Override
public String toString()
{
return String.valueOf(element);
}
}
}