package 链表;
/** * 定义一个结点 * @author LiZhe * */ class Node{ Node next = null; int data; public Node(int data){ this.data = data; } } /** * 链表 * @author LiZhe * */ public class MyLinkedList { Node head = null;//链表的头结点 /** * 添加结点 * @param data */ public void addNode(int data){
//将数据封装到结点中,即创建新结点
Node newNode = new Node(data);
//如果链表是空链表,将新结点添加给头结点
if(head == null){
head = newNode;
return;
}
//如果链表是非空链表,将新节点添加到链表末尾处
Node tmp = head;
while(tmp.next != null){
tmp = tmp.next;
}
tmp.next = newNode;
}
/**
* 删除第index个结点
* @param index
* @return
*/
public boolean deleteNodeByIndex(int index){
//角标不合理
if(index<1 || index>length()){
return false;
}
//index==1的情况
if(index == 1){
head = head.next;
return true;
}
//index大于等于2的情况
int i = 2;
Node preNode = head;
Node curNode = preNode.next;
while(curNode != null){
if(index == i){
preNode.next = curNode.next;
return true;
}
preNode = curNode;
curNode = curNode.next;
i++;
}
return true;
}
/**
* 对链表进行排序,并返回排序后的头结点
*
* 思路:用选择排序的思想对链表排序。第一个结点和第二个结点相比较,小的往前放,第一个结点和第三个结点相比较,
*小的往前放...,第一次排序后,最小值放在第一个结点处。将第一个结点的下一个结点重新设为第一个结点,重复上述过程。
* @return
*/
public Node orderList(){
Node curNode = head;
while(curNode.next != null){
Node nextNode = curNode.next;
while(nextNode !=null){
if(curNode.data>nextNode.data){
int temp = curNode.data;
curNode.data = nextNode.data;
nextNode.data = temp;
}
nextNode = nextNode.next;
}
curNode = curNode.next;
}
return head;
}
/**
* 从链表中删除重复数据
*
* 思路:对链表进行双重遍历,外循环正常遍历链表,假设外循环当前遍历的结点为cur,内循环从cur.next开始遍历,若碰到与cur
* 结点里存的数据值相同,则删除这个重复结点。
*/
public void deleteDuplecate(){
Node curNode = head;
while(curNode != null){
Node preNode = curNode;
Node nextNode = curNode.next;
while(nextNode != null){
if(curNode.data == nextNode.data){
preNode.next = nextNode.next;
nextNode=nextNode.next;
}else{
preNode = nextNode;
nextNode=nextNode.next;
}
}
curNode = curNode.next;
}
}
/**
* 如何从尾到头打印链表
*
* 思路:要实现反过来打印链表,每访问到一个结点,先递归输出它后面的结点,再输出该结点自身
*/
public void printListReversely(Node head){
Node tmp = head;
if(tmp != null){
printListReversely(tmp.next);
System.out.println(tmp.data);
}
}
/**
* 反转链表
*
* 思路:从头到尾遍历原链表,在断开当前结点与下一个结点的联系之前,先保存当前节点的下一个结点,然后,让当前结点指向上一个结点,将当前结点定义为新的上一个结点,将当前结点的下一个结点定义为新的当前结点。直到当前节点的下一个结点为null时,将当前结点定义反转后链表的头结点。
*
* @param head
*/
public void reverseList(){
if(head == null || head.next == null){
return;
}
Node current = head;//定义当前结点,初始值为头结点head
Node preCurrent = null;//定义当前节点的上一个结点,初始值为null
Node reverseHead = head;//定义反转后链表的头结点,初始值为未反转前链表的头结点
while(current != null){
Node next = current.next;//在断开当前结点与下一个结点联系之前,保存当前节点的下一个结点
//如果当前结点的下一个结点为null,那么当前结点就是反转后的链表的头结点
if(next == null)
reverseHead = current;
current.next = preCurrent;//断开当前结点与下一个结点的联系,让当前结点指向上一个结点
preCurrent = current;//将当前结点定义为新的上一个结点
current = next;//将当前结点的下一个结点定义为新的当前结点
}
this.head = reverseHead;
}
/**
* 如何寻找单链表的中间结点
*
* 思路:第一步:定义快、慢两个指针,两个指针均从头开始遍历;
* 第二步:快指针一次走两步,慢指针一次走一步;
* 第三步:当快指针走到链表尾部时,慢指针恰好到达链表中部
*
* @param head
* @return
*/
public Node searchMidNode(Node head){
Node p = head;
Node q = head;
while(p!=null && p.next!=null && p.next.next!=null){
p = p.next.next;
q = q.next;
}
return q;
}
/**
* 如何检测一个单链表是否有环
*
* 思路:定义两个指针fast和slow,快指针一次走两步,慢指针一次走一步,快指针每移动一次都要跟慢指针比较,直到当快指针等于慢指针时,说明这个链表是
* 带环的单向链表,否则,说明这个链表不是带环的单向链表。
*
* @param head
* @return
*/
public boolean hasCycle(Node head){
if(head == null){
return false;
}
Node fast = head;
Node slow = head;
while(fast!=null && fast.next!=null){
slow = slow.next;
fast = fast.next.next;
if(slow == fast){
return true;
}
}
return false;
}
/**
* 如何判断两个链表是否相交
*
* 思路:如果两个链表相交,那么它们一定有着相同的尾结点,因此实现思路为:分别遍历两个链表,记录它们的尾结点,如果
* 它们的尾结点相同,那么说明这两个链表相交,否则不想交。
*
* @param head1
* @param head2
* @return
*/
public boolean isIntersect(Node head1,Node head2){
if(head1==null || head2==null){
return false;
}
//找出第一个链表的尾结点
Node tail1 = head1;
while(tail1.next != null){
tail1 = tail1.next;
}
//找出第二个链表的尾结点
Node tail2 = head2;
while(tail2.next != null){
tail2 = tail2.next;
}
return tail1 == tail2;
}
/**
* 打印链表
*/
public void printList(){
Node tmp = head;
while(tmp!=null){
System.out.println(tmp.data);
tmp = tmp.next;
}
}
/**
* 计算链表长度
* @return
*/
public int length(){
int length = 0;
Node tmp = head;
while(tmp != null){
length++;
tmp = tmp.next;
}
return length;
}
/**
* 主函数
* @param args
*/
public static void main(String[] args) {
MyLinkedList myLinkedList = new MyLinkedList();
myLinkedList.addNode(1);
myLinkedList.addNode(9);
myLinkedList.addNode(3);
myLinkedList.addNode(6);
myLinkedList.addNode(7);
System.out.println("打印链表:");
myLinkedList.printList();
}
} |