关闭

链表基本操作java实现

159人阅读 评论(0) 收藏 举报
分类:
package 链表操作;

//常见的链表8大操作,比较常考的

import java.util.*;
class Node{
	int e;
	Node next;
	public Node(int e){
		this.e=e;
	}
}


public class NodeOperation {


	public static void main(String[] args) {

	Node head=new Node(0);
	Node N=head;
	
	for(int i=1;i<10;i++){
		N=N.next=new Node(i);//链表的赋值和移动一步到位
		System.out.print(N.e+" ");
	}
	
	
	System.out.println();
	//add the second line
	Node head1=new Node(10);
	Node M=head1;
	for(int i=11;i<20;i++){
		M=M.next=new Node(i);
		
		//System.out.println(N.e);
	}
	
	
	//以下是几种情况的测试节点的情况,都是常见的笔试面试的题目,务必熟练操作,手写代码
	
	/*
	//3.输出反向单链表的值
	printReverse(head);
	System.out.println();
	*/
	
	
	/*
	//2.两个链表的合并
	M=merge(head,head1);
	while(M!=null){
		System.out.print(M.e+" ");
		M=M.next;
	}
	System.out.println();
	*/
	
	
	/*1.链表的反转
	//System.out.println(head.e);
	N=head;
	//遍历单链表
	//System.out.println(N.e);
	//System.out.println(N.next);
	while(N!=null){
		System.out.println(N.e);
		N=N.next;
	}

	N=head;
	System.out.println(head);
	reverse(head);
	System.out.println(head);

	*/
	
	/*
	//4.寻找单链表中的中间节点
	System.out.println(searchMid(head).e);
	
	*/
	
	
	/*
	//5.寻找单链表倒数第k个节点
	//System.out.println(head);
	System.out.println((searchKnode(head,2)).e);
	*/
	
	
	/*
	//6.检测一个链表有没有环
	N.next=head;//创造一个环,去掉本部分就是false
	System.out.println(isLoop(head));
	*/
	
	//7.判断两个链表是否相交,及找出相交的第一个节点(有一定的难度),此程序只需要了解思路即可,暂不验证,不便于测试
	
	//8.删除链表中重复的数据
	Node H=head;
	//System.out.print(H.e+" hh");
	for(int i=1;i<10;i++){
		H=H.next=new Node(3);
		
		//System.out.print(H.e+" ");
	}
	H=head;
	deleteDuplecate(H);
	
	}

	
	
	
	
	//1.链表的反转操作
	public static void reverse(Node head){
		Node reverse = head;
		Node current=head;
		Node prev=null;
		while(current!=null){
			Node pnext=current.next;
			//System.out.println("22"+pnext);
			if(pnext==null){
				reverse=current;
				System.out.println(reverse);
			}
			current.next=prev;//断开链表
			prev=current;
			current=pnext;
			//System.out.println("11"+current);
		}
		head=reverse;
		System.out.println(head);
		while(head!=null){
			System.out.println(head.e);
			head=head.next;
		}

	}
	
	//2.利用递归的方式进行两个有序链表的合并,合并为一个有序链表
	public static Node merge(Node head,Node head1){
		Node head0;
		if(head==null){
			return head1;
		}
		
		if(head1==null){
			return head;
		}
		
		//核心算法在后面
		if(head.e>head1.e){
			head0=head1;
			head0.next=merge(head1.next,head);
		}else{
			head0=head;
			head0.next=merge(head.next,head1);
		}
		return head0;
	}
	
	//3.利用递归从尾到头输出单链表,递归的实质是一个栈,里面存放一个一个的栈帧
	public static void printReverse(Node p){
		if(p!=null){
			printReverse(p.next);
			System.out.print(p.e+" ");
		}
	}
	
	//4.寻找单链表的中间节点,定义一个快指针 一个慢指针,拒绝了两次遍历链表
	public static Node searchMid(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;
	}
	
	//5.寻找单链表的倒数第k个节点,利用两个指针,双指针法在链表查找操作中比较常用
	
	public static Node searchKnode(Node head,int k){
		
		/*这个必须要考虑的边界条件,由于我们这里没有确定单链表总结点个数的方法,因此只是注释一下,正常程序中务必要进行考虑
		if(k<1||k>size){
			return null;
		}
		*/
		
		Node p=head;
		Node q=head;
		//System.out.println(q);
		//其中的一个指针向前k-1个节点
		//System.out.println(k);
		for(int i=0;i<k-1;i++){
			q=q.next;
			//System.out.println(q);
		}
		
		while(q.next!=null){
			p=p.next;
			q=q.next;
		}
		
		return p;
	}

	//6.如何检测一个链表是否有环,比较常考的知识点
	public static boolean isLoop(Node head){
		Node p=head;
		Node q=head;
		if(q==null){
			return false;
		}
		
		while(q!=null&&q.next!=null){
			p=p.next;
			q=q.next.next;
			if(p==q){
				return true;
			}
		}
		return false;
	}
	
	
	//7.判断两个链表是否相交,及找出相交的第一个节点(有一定的难度),此程序只需要了解思路即可,暂不验证
	
	public static Node getFirstmeetNode(Node h1,Node h2){
		//判断两个链表相交吗---看尾节点是否相同
		if(h1==null||h2==null){//均为空表
			return null;
		}
		
		Node tail1=h1;
		int len1=1;
		while(tail1.next!=null){
			tail1=tail1.next;
			len1++;
		}
		
		Node tail2=h2;
		int len2=1;
		while(tail2.next!=null){
			tail2=tail2.next;
			len2++;
		}
		
		
		if(tail1==tail2){
			System.out.println(true);
		}else{
			return null;
		}
		Node t1=h1;
		Node t2=h2;
		//找到两个链表中里尾戒点等长的点
		if(len1>len2){
			int d=len1-len2;
			while(d!=0){
				t1=t1.next;
				d--;
			}
		}else{
			int d=len1-len2;
			while(d!=0){
				t2=t2.next;
				d--;
			}
		}
		
		
		//同步向后遍历,一定会找到呢个第一个相交的点
		while(t1!=t2){
			t1=t1.next;
			t2=t2.next;
		}
		
		return t1;
		
	}
	
	
	//从链表中删除重复数据
	public static void deleteDuplecate(Node head){
		Set<Integer> s=new HashSet<Integer>();
		Node temp=head;
		Node pre=null;//用于存储删除后新的链表的数据,该变量的引入经典
		int t=0;
		while(temp!=null){
			t=s.size();
			s.add(temp.e);
			if(t<s.size()){
				pre=temp;
			}else{//出现重复的情况,不是很理解
				pre.next=temp.next;
			}
			temp=temp.next;
		}
		
		pre=head;
		//System.out.println(head.e+" ");
		System.out.println();
		while(pre!=null){
			System.out.print(pre.e+" ");
			pre=pre.next;
		}
	}	
}

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:6091次
    • 积分:281
    • 等级:
    • 排名:千里之外
    • 原创:23篇
    • 转载:0篇
    • 译文:0篇
    • 评论:1条
    最新评论