写给初学者的数据结构——初识链表(带头结点)(Java实现)

理解篇(C++):https://blog.csdn.net/weixin_43796828/article/details/94901321

标准C实现:https://blog.csdn.net/weixin_43796828/article/details/95616496


1、结点类

public class Node 
{
	Object data;
	Node next;
	
	public Node(Object data) 
	{
		this.data = data;
	}
	
	public Node(Object data,Node next)
	{
		this.data = data;
		this.next = next;
	}

	public Object getData() {
		return data;
	}

	public void setData(Object data) {
		this.data = data;
	}

	public Node getNext() {
		return next;
	}

	public void setNext(Node next) {
		this.next = next;
	}
	
	public String toString()
	{
		return data.toString();
	}
	
}

2、链表类

public class List
{
	Node current;
	Node head;
	int size;

	List()//操作结果:自动生成头结点,头结点,a0,a1,a2,a3,。。。an。
	{
		head = current = new Node(null);
		size = 0;
	}
	
	public void index(int i)throws Exception//操作结果:定位,移动到ai身上
	{		
		if(i<-1 || i>size-1)
		{
			throw new Exception("参数错误");
		}
		
		if(i==-1)
		{
			return;
		}
		
		current = head.next;
		int j = 0;
		while((current!=null) && j<i)
		{
			current = current.next;
			j++;
		}
		
	}
	
	public void ListInsert(int i,Object obj)throws Exception//操作结果:插入,在下标为i的结点前插入一个Object对象
	{
		if(i<0 || i>size)
		{
			throw new Exception("参数错误");
		}
		index(i-1);
		current.setNext(new Node(obj,current.next));
		size++;
	}
	
	public Object ListDelete(int i)throws Exception//操作结果:删除下标为i的结点,函数返回被删除的对象
	{
		if(size==0)
		{
			throw new Exception("链表已空无元素可删!");
		}
		
		if(i<0 || i>size-1)
		{
			throw new Exception("参数错误!");
		}
		
		index(i-1);
		Object obj = current.next.getData();
		current.setNext(current.next.next);
		size--;
		return obj;
	}	

	public Object DeleteElem(Object obj) throws Exception//操作结果:删除表中值为obj的元素,并返回TRUE,如无此元素,则返回FALSE
	{	
		Node p = head,q;
		while(p!=null)
		{
			q = p.next;
			if(q!=null && q.data.equals(obj))
			{
				p.next = q.next;
				size--;
				return q.data;
			}
			p = q;
		}
		throw new Exception("不存在此元素!");	
	}
	
	public int LocateElem(Object obj)
	{
		//初始条件:线性表L已存在
		//操作结果:返回L中第1个与e相等的数据元素的位序。
		//		      若这样的元素不存在,则返回值为0.
		int i = 0;
		Node p = head.next;
		while(p!=null)
		{
			i++;
			if(p.data.equals(obj))
			{
				return i;
			}
			p = p.next;
		}
		return 0;
	}	

	public int ReplaceElem(int i,Object obj)
	{
		Node p = head;
		int j = 0;
		while(p.next!=null && j<i)
		{
			j++;
			p = p.next;
		}
		
		if(j==i)
		{
			p.data = obj;
			return 1;
		}
		else
		{
			return 0;
		}
	}

	public void DestroyList()
	{
		//初始条件:线性表L已存在
		//操作结果:销毁线性表
		head.next = null;
		size = 0;
		current = null;
	}
	
	public void ClearList()
	{
		//初始条件:线性表L已存在
		//操作结果:将L重置为空表
		head.next = null;
		size = 0;
		current = head;
				
	}
	
	public boolean ListEmpty()//操作结果:返回true或者false,判断元素是否为空
	{
		return size==0;
	}
	
	public int ListLength()//操作结果:函数返回链表中的元素个数
	{
		return size;
	}

	public Object GetElem(int i)throws Exception//操作结果:函数返回下标为i的对象
	{
		if(i<-1 || i>size-1)
		{
			throw new Exception("参数错误!");
		}
		index(i);
		return current.getData();
	}
	
	public Object GetFirstElem()throws Exception
	{
		if(!ListEmpty())
		{
			index(0);
			return current.data; 
		}
		return null;
	}
	
	public Object PriorElem(Object obj)
	{
		//初始条件:线性表L已存在
		//操作结果:若obj是L的数据元素,且不是第一个,则函数返回它的前驱.否则操作失败,函数返回null
		Node q,p = head.next;
		while(p.next!=null)//这个循环的本质是从第二个搜索检索到最后一个
		{
			q = p.next;
			if(q.data.equals(obj))
			{
				obj = p.data;
				return p;
			}
			p = q;
		}
		return null;
	}
	
	public Object NextElem(Object obj)
	{
		//初始条件:线性表L已存在
		//操作结果:若obj是L的数据元素,且不是最后一个,则函数返回它的后继.否则操作失败,函数返回null
		Node p = head.next;
		while(p.next!=null)
		{
			if(p.data.equals(obj))
			{
				return p.next.data;
			}
			p = p.next;
		}
		return null;
	}
	
	//从上面这两个函数来看,if语句放在“指针”后移之前和之后,确乎玄妙。

	public void ListTraverse()
	{
		Node p = head.next;
		while(p!=null)
		{
			System.out.print(p.data + " " );//这一句还可以是其它一些操作(java中函数),C中可以用函数指针.
			p = p.next;
		}
		System.out.println();
	}

	public boolean HeadInsert(Object obj)
	{
		//初始条件:线性表L已存在。
		//操作结果:在L的头部插入新的数据元素obj,作为链表的第一个元素
		head.setNext(new Node(obj,head.next));
		size++;
		return true;
	}
	
	public boolean EndInsert(Object obj)
	{
		Node p = head;
		while(p.next!=null)
		{
			p = p.next;
		}
		p.setNext(new Node(obj,null));
		size++;
		return true;
	}
	
	public Object DeleteFirst()throws Exception
	{
		Node p = head.next;
		if(head.next!=null)
		{
			head.setNext(p.next);
			size--;
			return p.data;
		}
		else
		{
			throw new Exception("表空!");
		}
	}

	public Object DeleteTail()throws Exception
	{
		Node p = head,q = null;
		
		if(p.next==null)
		{
			throw new Exception("表空");
		}

		while(p.next!=null)
		{
			q = p;
			p = p.next;
		}
		q.setNext(null);
		size--;
		return p.data;
	}

	//InsertAscend,InsertDescend,CraetDescend,CreatDescend;需要先知道数据类型
}

3、Main函数

	public static void main(String[] args) {
		List str = new List();
		int n = 5;
		
		try
		{
			for(int i = 0; i < n; i++)
			{
				str.ListInsert(i,new Integer(i));
			}
			System.out.println("表空? " + str.ListEmpty());
			System.out.println("表长?" + str.ListLength());
			System.out.print("表遍历:");
			str.ListTraverse();	
			System.out.println("表中首元素:" + str.GetFirstElem());
			System.out.println("表中第二个元素:" + str.GetElem(1));
			System.out.println("删除元素1:" + str.DeleteTail());
			System.out.println("删除元素2:" + str.DeleteFirst());
			System.out.println("删除元素3:" + str.DeleteElem(1));
			System.out.println("增添元素1:" + str.EndInsert(6));
			System.out.println("增添元素2:" + str.HeadInsert(48));
			str.ReplaceElem(str.LocateElem(new Integer(3)),36);
			System.out.println("删除尾元素,第二个元素,首元素:");
			str.ListTraverse();	
			System.out.println("36的位序:" + str.LocateElem(new Integer(36)));
			System.out.println("36的前驱:" + str.PriorElem(new Integer(36)));
			System.out.println("36的后继:" + str.NextElem(new Integer(36)));
			str.ClearList();
			str.ListTraverse();	
			for(int i = 0; i < n; i++)
			{
				str.ListInsert(i,new Integer(i*2));
			}
			str.ListTraverse();	
			str.DestroyList();
			str.ListTraverse();	
			
		}
		catch(Exception e)
		{
			System.out.println(e.getMessage());
		}
	}

4、运行结果

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值