前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >数据结构链表实现

数据结构链表实现

作者头像
张凝可
发布2019-08-22 11:03:08
4400
发布2019-08-22 11:03:08
举报
文章被收录于专栏:技术圈

主要实现了链表的增加、删除、查找结点,逆置链表,求两个链表的交集、并集和差集,以及对链表排序

代码语言:javascript
复制
package SqList_Operator;

import java.text.MessageFormat;

public class LinkListTool {
	public LinkListTool(){
		
	}
	
	public int getListLength(LinkList l){
		
		int k=1;
		LNode tempNode = l.getStartNode();
		while(tempNode.getNext()!=null){
			tempNode = tempNode.getNext();
			k++;
			
		}
		return k;
		
	}
	//在链表中查找指定的元素
	public LNode getNode(LinkList l,int e){
		
		LNode resultNode = null;
		LNode tempNode = l.getStartNode();
		while(tempNode!=null){
			if(tempNode.getData()==e){
			
			    resultNode = tempNode;
			    break;
				}
			else {
				tempNode = tempNode.getNext();
			}
			
		}
		
		return resultNode;
		
	}
	public void listInsert(LinkList l,LNode p,LNode s)
	{
		//在p结点之前插入结点s
		if(p==l.getStartNode()){
			s.setNext(p);
			l.setStartNode(s);
			
			
		}
		else{
			LNode temp = l.getStartNode();
			while(temp.getNext()!=p&&temp!=null){
				temp = temp.getNext();
				
			}
			if(temp!=null){
				System.out.print("链表中不存在");
				
			}
			else{
				temp.setNext(s);
				s.setNext(p);
			}
		}
		
	}
	//逆置单链表
	public void invertLinkedList(LinkList l){
		
		System.out.print("逆置单链表之前的结点为:");
		printLinkList(l);
		
		LNode p = l.getStartNode();
		LNode r = p.getNext();
		LNode s =null;
		p.setNext(null);
		/*l.setStartNode(null);*/
		while(r!=null){
			s = r.getNext();
		    r.setNext(p);
		    p=r;
			l.setStartNode(r);
			r = s;
			/*System.out.print("test");*/
			
		}
		System.out.print("逆置单链表之后的结点为:");
		printLinkList(l);
		/*while(p!=null){
			LNode r = p.getNext();
			p.setNext(l.getStartNode());
			l.setStartNode(p);
			p = r;
			
		}*/
		
	}
	//将链表lb中所有在la链表中不存在的点插入到la链表中,并释放lb中多余的点
	public void union_L(LinkList la,LinkList lb){
		
		System.out.print(MessageFormat.format("源链表{0}为:",la ));
		printLinkList(la);
		if(la==null){
			la = lb;
			
		}else{
			//否则遍历lb中的结点
			
			LNode q = lb.getStartNode();
			LNode pre = null;
			while(q!=null){
			/*	LNode p = lb.getStartNode();*/
				LNode s = q;
				q = q.getNext();
				LNode r = la.getStartNode();
				while(r!=null&&s.getData()!=r.getData()){
					//将lb中的结点加入到la中
					 pre = r;
					r = r.getNext();
					
				}
				if(r!=null){
					//找到了相同的元素,则删除
					
					
				}
				else{
					pre.setNext(s);
					s.setNext(null);
				}
			}
			
		}
		System.out.print(MessageFormat.format("源链表{0}为:",la ));
		printLinkList(la);
	}
	
	//对带有头结点的单链表进行排序,利用直接插入对链表进行排序
	public void linkListInsertSort(LinkList l){
		//直接插入默认链表的第一个结点是有序的,直接插入则从链表的第二个结点开始
		System.out.print("排序之前源链表为:");
		printLinkList(l);
		if(l.getStartNode()!=null){
			
			LNode node = l.getStartNode().getNext();
			l.getStartNode().setNext(null);
			while(node!=null){
				LNode q = node.getNext();
				LNode p = l.getStartNode();
				LNode pre = null;
				while(p.getData()<node.getData()&&p!=null){
					pre = p;
					p = p.getNext();
					
				}
				if(pre==null){
					//说明第一个结点就比待插入的大
				   node.setNext(p);
				   l.setStartNode(node);
					
				}else{
					pre.setNext(node);
					node.setNext(p);
				}
				node = q;
				
				
				
			}
			
		}
		
		System.out.print("排序之后源链表为:");
		printLinkList(l);
		
	}
	//求解两个有序链表的交集
	public LinkList unionList(LinkList la,LinkList lb){
		LinkList lc = new LinkList();
		lc.setStartNode(null);
		LNode pa = la.getStartNode();
		LNode pb = lb.getStartNode();
		//遍历两个链表,找到两个链表中相同的元素
		while(pa!=null&&pb!=null){
			if(pa.getData()<pb.getData()) pa = pa.getNext();
			else if(pa.getData()>pb.getData()){
				
				pb = pb.getNext();
			}
			else{
				//pa.getData=pb.getData的情况,就将该结点插入到链表lc中去
				LNode tempNode = new LNode(pa.getData());
				tempNode.setNext(lc.getStartNode());
				lc.setStartNode(tempNode);
				pa = pa.getNext();
				pb = pb.getNext();
				//pa就成了lc链表中的第一个结点
				
				
				
			}
			
		}
		return lc;
		
	}
	//删除链表中的最小值结点
	public void deleteMinNode(LinkList l){
		System.out.print("删除之前源链表为:");
		printLinkList(l);
		LNode pre = l.getStartNode();
		LNode node = l.getStartNode();
		LNode min = null;
		
		//用pre来记录最小值结点的前驱
	    while(node.getNext()!=null){
	    	if(node.getData()>node.getNext().getData()){
	    		pre = node;
	    		min = node.getNext();
	    		
	    	}
	    	node = node.getNext();
	    	
	    }
	    System.out.print(pre.getData());
	    System.out.print(min.getData());
	    /*if(pre.equals(l.getStartNode())){
	    	l.setStartNode(pre.getNext());
	    	
	    }*///这种情况应该如何处理
	    pre.setNext(min.getNext());
	    min.finalize();//释放最小值结点
	    System.out.print("删除之后源链表为:");
		printLinkList(l);
		
		
	}
	//将两个有序链表合并,并且合并后的链表仍然是有序的
	public LinkList unionListTwo(LinkList la,LinkList lb){
		System.out.print("合并之前源链表为:");
		printLinkList(la);
		LNode pa = la.getStartNode();
		LNode pb = lb.getStartNode();
		LNode pre = null;
		LNode pos = null;
		//这里以链表la做为基础
		while(pa!=null&&pb!=null){
			
			if(pa.getData()<=pb.getData()){
				pre = pa;
				pa = pa.getNext();
				
			}
			else if(pa.getData()>pb.getData()){
				//其实我这里可以生成结点,不破坏lb原本的结构的
				pre.setNext(pb);
				if(pre==null)//我想用equal()方法来判断pre和pa指的是不是同一个结点
				{
					pb.setNext(pa.getNext());
					}
				else{
					
					pos = pb.getNext();//我这里还不能释放pb,如果我需要释放的话,我应该new一个结点和
					//和pb的data相同,再释放
					pb.setNext(pa);
				}
				pb = pos;
				
				
			}
			
			
		}
		//如果循环结束后,pa已经为空,单pb不为空,则要遍历pb中的结点,依次放入到pb中
		//但是如果pb为空,pa部位空,则将pa的剩下的链接过去
		if(pa!=null){
			pre.setNext(pa);
			
		}else{
			while(pb!=null){
				pre.setNext(pb);
				pre = pb;
				pb = pb.getNext();
			}
			
		}
		System.out.print("合并之后源链表为:");
		printLinkList(la);
		return la;
		
	}
	//两个链表的差集,即对链表la删除la和lb共同有的结点
	public void differenceList(LinkList la,LinkList lb){
		System.out.print("删除公共结点之前源链表为:");
		printLinkList(la);
		LNode pa = la.getStartNode();
		LNode pb = lb.getStartNode();
		LNode pre = null;
		LNode pos = null;
		while(pa!=null&&pb!=null){
			if(pa.getData()<pb.getData()){
				pre = pa;
				pa = pa.getNext();//因为涉及到删除因此需要把记录前驱
			}else if(pa.getData()>pb.getData()){
				pb = pb.getNext();
				
			}else{
				//这就说pa.getData==pb.getData();
				/*pre.setNext(pb);
				pos = pb.getNext();
				pb.setNext(pa);
				pa = pa.getNext();
				pb = pos;
				*/
				//删除
				pre.setNext(pa.getNext());
				pos = pa;
				pa = pa.getNext();
				pos.finalize();//释放该结点
				
			}
			
		}
		
		System.out.print("删除公共节点之后源链表为:");
		printLinkList(la);
		
	}
	public void addLinkNode(LinkList l,LNode node){
		//向链表l中加入结点
		//首先应该经过遍历到达链表的尾端
		LNode start = l.getStartNode();
		LNode temp = start;
		while(temp.getNext()!=null){
			temp = temp.getNext();
			
		}
		//遍历完成后temp则为待插入结点的前驱结点
		//但是如果链表中只存在这头结点,那么temp本身就是空的
		if(temp!=null){
			temp.setNext(node);
			node.setNext(null);
		}else{
			l.setStartNode(node);
			node.setNext(null);
		}
		
	}
	//还有一个功能应该是打印链表
	public void printLinkList(LinkList l){
		LNode startNode = l.getStartNode();
		LNode temp = startNode;
		if(temp==null){
			System.out.print("该链表为空链表");
			
		}
		while(temp!=null){
			System.out.print("结点数据为:"+temp.getData());
			temp = temp.getNext();
			System.out.println();
			
		}
		
	}
	
	
	
	
	

}
代码语言:javascript
复制
package SqList_Operator;

public class LinkList {
	
	private	LNode startNode;
	private int length;
	public LinkList(LNode startNode){
		this.startNode = startNode;
		startNode.setNext(null);
		
		
	}
	public LinkList(LinkList l){
		this.startNode = l.getStartNode();
		
	}
	public LinkList(){}
	public LNode getStartNode() {
		return startNode;
	}
	public void setStartNode(LNode startNode) {
		this.startNode = startNode;
	}
	public int getLength() {
		return length;
	}
	public void setLength(int length) {
		this.length = length;
	}

}

OK~

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2016年08月21日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档