Java 链表操作

/**
 * 
 * @author whc
 *	
 */
public class LinkedList
{
	private static class Node
	{
		private int data;
		private Node next;
		public Node()
		{
			
		}
		public Node(int data,Node next)
		{
			this.data = data;
			this.next = next;
		}
	}

	//向单链表中插入结点
	public static void insert(Node header,int data,int index)
	{
		Node pre = getNodeByIndex(header,index-1);//获取index前向节点
		Node newNode = new Node(data, pre.next);//创建新结点,并令其next指向index节点
		pre.next = newNode; //index-1节点next指向newNode
	}
	
	//删除节点
	public static int delete(Node header,int index)
	{
		Node cur = null;
		if(index == 0)  //若为头结点
		{
			cur = header;
			header = header.next;
		}
		else
		{
			Node pre = getNodeByIndex(header,index-1);
			cur = pre.next;
			pre.next = cur.next;
			cur.next = null;
		}
		return cur.data;
	}
	
	//O(1)时间复杂度删除节点
	public static void quickQelete(Node header,int index)
	{
		Node delete = getNodeByIndex(header, index);
		if(delete.next == null)   //若删除的是尾结点,需遍历找到前结点
		{
			if(header == delete)
				header = null;
			else
			{
				Node temp = header;
				while(temp.next != delete)
					temp = temp.next;
				temp.next = null;
			}
		}
		else    //狸猫换太子
		{
			delete.data = delete.next.data;
			delete.next = delete.next.next;
		}
	}
	
	//寻找倒数第k个元素
	public static Node getBackward(Node header,int k)
	{
		Node pre = header;
		Node rear = getNodeByIndex(header,k-1);//求倒数第k个结点,两结点其实相差(k-1)
		while(rear.next != null)
		{
			pre = pre.next;
			rear = rear.next;
		}
		return pre;
	}
	
	//单链表反转(非递归)
	public static Node reverse(Node header)
	{
		Node pre = header;
		Node cur = header.next;
		Node rear = null;
		while(cur != null)
		{
			rear = cur.next;
			cur.next = pre;
			pre = cur;
			cur = rear;
		}
		header.next = null;
		header = pre;
		return header;
	}
	
	//单链表反转(递归)
	public static Node reverse2(Node header)
	{
		if(header==null||header.next==null)return header;  
        Node reHeader=reverse2(header.next);  
        header.next.next=header;  
        header.next=null;  
        return reHeader; 
	}
	
	//从尾到头打印单链表(递归)
	public static void printByReverse(Node header)
	{
		if(header == null)
			return;
		else
		{
			printByReverse(header.next);
			System.out.print(header.data + ",");
		}
	}
	
	//合并两个有序链表(非递归)
	public static Node mergeSorted(Node header1,Node header2)
	{
		Node header = null;
		Node cur = header;
		while(header1 != null && header2 != null)
		{
			if(header1.data <= header2.data)
			{
				cur.next = header1;
				cur = cur.next;
				header1 = header1.next;
			}
			else
			{
				cur.next = header2;
				cur = cur.next;
				header2 = header2.next;
			}
		}
		if(header1 != null)
			cur.next = header1;
		if(header2 != null)
			cur.next = header2;
		return header;
	}
	
	//合并两个有序的单链表(递归)
	public static Node mergeSortedList(Node header1,Node header2)
	{
		if(header1 == null)
			return header2;
		if(header2 == null)
			return header1;
		Node header = null;
		if(header1.data > header2.data)
		{
			header = header2;
			header.next = mergeSortedList(header1, header2.next);
		}
		else
		{
			header = header1;
			header.next = mergeSortedList(header1.next, header2);
		}
		return header;
	}
	
	//对单链表进行归并排序
	public static Node mergeSort(Node header)
	{
		Node rear = null;
		if(header == null || header.next == null)
			return header;
		else if(header.next.next == null)
		{
			rear = header.next;
			header.next = null;
		}
		else
		{
			Node mid = getMidNode(header);
			rear = mid.next;
			mid.next = null;
		}
		return mergeSortedList(mergeSort(header),mergeSort(rear));//合并两个有序链表
	}
	
	//交换链表中任意两个节点
	public static void swap(Node header,Node p,Node q)
	{
		if(p == header || q == header || p == null || q == null || p == q)
			return;
		else if(p.next == q)
		{
			Node pre_p = findPre(header, p);
			pre_p.next = q;
			p.next = q.next;
			q.next = p;
		}
		else if(q.next == p)
		{
			Node pre_q = findPre(header, q);
			pre_q.next = p;
			q.next = p.next;
			p.next = q;
		}
		else
		{
			 Node after_p = p.next;
			 Node pre_p = findPre(header, p);
			 Node pre_q = findPre(header, q);
			 p.next = q.next;
			 pre_q.next = p;
			 pre_p.next = q;
			 q.next = after_p;
		}
	}
	
	//判断链表中是否有环
	public static boolean isCycle(Node header)
	{
		boolean flag = false;
		Node fast = header;
		Node slow = fast;
		if(fast == null)
			return false;
		while(fast != null && fast.next != null)
		{
			slow = slow.next;
			fast = fast.next.next;
			if(fast == slow)
			{
				flag = true;
				break;
			}
		}
		return flag;
	}
	
	//判断两个链表是否相交(无环情况),并返回相交的第一个结点。
	public static Node isIntersect(Node header1,Node header2)
	{
		Node target = null;
		int len1 = length(header1);
		int len2 = length(header2);
		if(len1 == 0 || len2 == 0)
			return target;
		if(len1 > len2)//长链表先出发前进二者之差步
		{
			for(int i = 0;i < len1-len2;i++)
				header1 = header1.next;
		}
		else
		{
			for(int i = 0;i < len2-len1;i++)
			header2 = header2.next;
		}
		while(header1 != null && header2 != null)
		{
			if(header1 == header2)  //相遇的第一步即为两链表相交的第一个点
			{
				target = header1;
				break;
			}
			else                      //二者共同前进
			{
				header1 = header1.next;
				header2 = header2.next;
			}
		}
		return target;
	}
	
	//删除链表中的重复结点(递归)
	public static Node deleteSame(Node header)
	{
		Node temp = header,pointer;
		if(header.next == null)
			return header;
		header.next = deleteSame(header.next);
		pointer = header.next;
		while(pointer != null)
		{
			if(header.data == pointer.data)
			{
				temp.next = pointer.next;
				pointer.next = null;
				pointer = temp.next;
			}
			else
			{
				temp = temp.next;
				pointer = pointer.next;
			}
		}
		return header;
	}
	
	//获取链表中间结点
	public static Node getMidNode(Node header)
	{
		Node slow = header;
		Node fast = slow;
		while(fast != null && fast.next != null)
		{
			slow = slow.next;
			fast = fast.next.next;
		}
		return slow;
	}
	
	//获取结点前驱结点
	public static Node findPre(Node header,Node p)
	{
		Node q = header;
		while(q != null)
		{
			if(q.next == p)
				return q;
			else
				q = q.next;
		}
		return null;
	}
	
	//根据索引获取结点
	public static Node getNodeByIndex(Node header,int index)
	{
		Node cur = header;
		int i;
		if(index >= length(header)-1)
			return null;
		for(i = 0; i < index; i++)
			cur = cur.next;
		return cur;
	}
	
	//遍历链表
	public static void view(Node header)
	{
		Node temp = header;
		while(temp != null)
		{
			System.out.print(temp.data + ",");
			temp = temp.next;
		}
		System.out.println();
	}
	
	//获取链表长度
	public static int length(Node header)
	{
		int num = 0;
		Node cur = header;
		while(cur != null)
		{
			num++;
			cur = cur.next;
		}
		return num;
	}
	
	public static void main(String[] args)
	{
		Node header = null;//头结点
		Node tail = null;//尾结点
		int n = 9;
		Node cur = null;
		while((n--) != 0)	//新建一单链表
		{
			int random = (int)(Math.random()*100%20);
			if(header == null)
			{
				header = new Node(random,null);
				cur = header;
			}
			else
			{
				cur.next = new Node(random, null);
				cur = cur.next;
			}
		}
		tail = cur;
		System.out.println("新建的单链表:");
		view(header);//遍历单链表
		System.out.println("插入[99]结点后:");
		insert(header, 99, 5);
		view(header);
		System.out.println("删除[99]结点后:");
		delete(header, 5);
		view(header);
		System.out.println("倒数第五个结点:" + getBackward(header, 5).data);
//		System.out.println("反转后的单链表:");
//		view(reverse(header));
		System.out.println("从尾到头打印单链表:");
		printByReverse(header);
		System.out.println("获取的中间结点为:");
		System.out.println(getMidNode(header).data);
//		System.out.println("排序之后的单链表:");
//		Node header2 = mergeSort(header);
//		view(header2);
		Node Node1 = getNodeByIndex(header, 3);
		Node Node2 = getNodeByIndex(header, 4);
		swap(header, Node1, Node2);
		System.out.println("Node1与Node2交换之后:");
		view(header);
		System.out.println("判断单链表是否有环:" + isCycle(header));
		System.out.println("删除链表中重复节点后:");
		view(deleteSame(header));	
	}
}



</pre><pre name="code" class="java">

参考自:http://blog.csdn.net/kerryfish/article/details/24043099


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值