线性表的链式存储结构

线性表的链式存储结构,双向链表实现:

package 线性表;

public class DuLinkList <T>{
	//定义一个内部类Node,Node实例代表链表的节点
	private class Node{          
		//保存节点的数据
		private T data;
		//指向上个节点的引用
		private Node prev;
		//指向下个节点的引用
		private Node next;
		public Node(){}
		public Node(T data,Node prev,Node next){
			this.data=data;
			this.prev=prev;
			this.next=next;
		}
	}
	
	//保存该链表的头节点
	private Node header;
	//保存该链表的尾节点
	private Node tail;
	//保存该链表中已包含的节点数
	private int size;
	//创建空链表
	public DuLinkList(){
		//空链表,header和tail都是null
		header=null;
		tail=null;
	}
	//以指定数据元素来创建链表,该链表只有一个元素
	public DuLinkList(T element){
		header=new Node(element,null,null);
		//只有一个节点,header和tail都指向该节点
		tail=header;
		size++;
	}
	//返回链表的长度
	public int length(){
		return size;
	}
	//获取链式线性表中索引为index处的元素
	public T get(int index){
		return getNodeByIndex(index).data;
	}
	//根据索引index获取指定位置的节点
	private Node getNodeByIndex(int index){
		if(index<0||index>size-1){
			throw new IndexOutOfBoundsException("线性表索引越界");
		}
		if(index<=size/2){
			//从header节点开始
			Node current=header;
			for(int i=0;i<=size/2&¤t!=null;i++,current=current.next){
				if(i==index){
					return current;
				}
			}
		}
		else{
			//从tail节点开始搜索
			Node current=tail;
			for(int i=size-1;i>size/2&¤t!=null;i++,current=current.prev){
				if(i==index){
					return current;
				}
			}
		}
		return null;
	}
	
	//查找链式线性表中指定元素的索引
	public int locate(T element){
		//从头节点开始搜索
		Node current=header;
		for(int i=0;i<size&¤t!=null;i++,current=current.next){
			if(current.data.equals(element)){
				return i;
			}
		}
		return -1;
	}
	//向线性链表的指定位置插入一个元素
	public void insert(T element,int index){
		if(index<0||index>size){
			throw new IndexOutOfBoundsException("线性表索引越界");
		}
		//如果还是空表
		if(header==null){
			add(element);
		}
		else{
			//当index为0时,也就是在链表头处插入
			if(index==0){
				addAtHeader(element);
			}
			else{
				//获取插入点的前一个节点
				Node prev=getNodeByIndex(index-1);
				//获取插入点的节点
				Node next=prev.next;
				//让新节点的next引用指向next节点,prev引用指向prev节点
				Node newNode=new Node(element,prev,next);
				//让prev的next指向新节点
				prev.next=newNode;
				//让prev的下一个节点的prev指向新节点
				next.prev=newNode;
				size++;
			}
		}
	}
	//采用尾插法为链表添加新节点
	public void add(T element){
		//如果该链表还是空链表
		if(header==null){
			header=new Node(element,null,null);
			//只有一个节点,header,tail都指向该节点
			tail=header;
		}
		else{
			//创建新节点,新节点的pre指向原tail节点
			Node newNode=new Node(element,tail,null);
			//让尾节点的next指向新增的节点
			tail.next=newNode;
			//以新节点作为新的尾节点
			tail=newNode;
		}
		size++;
	}
	//采用头插法为链表添加新节点
	public void addAtHeader(T element){
		//创建新节点,让新节点的next指向原来的header,并以新节点作为新的header
		header=new Node(element,null,header);
		//如果插入之前是空链表
		if(tail==null){
			tail=header;
		}
		size++;
	}
	//删除链式线性表中指定索引处的元素
	public T delete(int index){
		if(index<0||index>size-1){
			throw new IndexOutOfBoundsException("线性表索引越界");
		}
		Node del=null;
		//如果被删除的是header节点
		if(index==0){
			del=header;;
			header=header.next;
			//释放新的header节点的prev引用
			header.prev=null;
		}
		else{
			//获取删除点的前一个节点
			Node prev=getNodeByIndex(index-1);
			//获取将要被删除的节点
			del=prev.next;
			//让被删除节点的next指向被删除节点的下一个节点
			prev.next=del.next;
			//让被删除节点的下一个节点的prev指向prev节点
			if(del.next!=null){
				del.next.prev=prev;
			}
			//将被删除节点的prev,next引用赋为null
			del.prev=null;
			del.next=null;
		}
		size--;
		return del.data;
	}
	//删除链式线性表中的最后一个元素
	public T remove(){
		return delete(size-1);
	}
	//判断链式线性表是否为空链表
	public boolean empty(){
		return size==0;
	}
	//清空线性表
	public void clear(){
		//将底层数组所有元素赋为null
		header=null;
		tail=null;
		size=0;
	}
	public String toString(){
		//链表为空链表时
		if(empty()){
			return"[]";
		}
		else{
			StringBuilder sb=new StringBuilder("[");
			for(Node current=header;current!=null;current=current.next){
				sb.append(current.data.toString()+",");
			}
			int len=sb.length();
			return sb.delete(len-2, len).append("]").toString();
		}
	}
	public String reverseToString(){
		//链表为空链表时
		if(empty()){
			return"[]";		
		}
		else{
			StringBuilder sb=new StringBuilder("[");
			for(Node current=tail;current!=null;current=current.prev){
				sb.append(current.data.toString()+",");
			}
			int len=sb.length();
			return sb.delete(len-2, len).append("]").toString();
		}
	}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值