如何实现自定义的数据结构?以线性表的实现为例分析

一,目标
1,采用JAVA语言实现线性表。采用链式存储结构实现。
2,抽象数据类型ADT设计(线性表需要提供什么接口?)
3,ADT实现(采用何种具体的存储结构,如顺序数组或单链表)

二,定义接口ListInterface<T>,确定线性表要提供的方法
public interface ListInterface<T> {
    public boolean add(T newEntry);
    public boolean add(int position, T newEntry);
    public T remove(int givenPositon);
    public T remove();
    public void clear();
    public boolean replace(int givenPositon, T newEntry);
    public T getEntry(int givePosition);
    public boolean contains(T anEntry);
    public boolean isEmpty();
}

三,确定数据结构
结点如何表示?
结点由数据域和指针域构成。
结点初始化:构造一个结点时,必须提供数据域的值。
结点类以内部类方式实现
private class Node{
        private T data;
        private Node next;
        private Node(T dataPortion) {
            data = dataPortion;
            next = null;
        }
    }

四,单链表的实现
1,采用的存储结构---链式存储结构
2,单链表的属性---头结点指针、尾结点指针、链表的长度(length)
3,方法实现
添加节点时,需要把各个节点链接起来;删除时,需要保证不断链;查找时需要顺序扫描.....
4,边界条件考虑
当链表为空时,增加、删除操作怎么实现?
在头结点、尾结点处增加、删除结点时,应如何操作?
5,操作的时间复杂度和究竟复杂度考虑
查找某元素时,时间复杂度为多少?
删除指定位置处的元素的时间复杂度与删除最后一个元素的时间复杂度是不是不同?
public class LList<T> implements ListInterface<T>{

    private Node firstNode;//指向线性表的第一个元素
    private Node lastNode;//指向线性表的最后一个元素
    private int length;//线性表中元素的个数

    private class Node{
        private T data;
        private Node next;

        private Node(T dataPortion) {
            data = dataPortion;
            next = null;
        }
    }

    public LList() {
        firstNode = lastNode = null;
        length = 0;
    }
//......实现接口中的方法
}

完整代码参考:
import list.ListInterface;

public class LList<T> implements ListInterface<T>{
	
	private Node firstNode;//指向线性表的第一个元素
	private Node lastNode;//指向线性表的最后一个元素
	private int length;//线性表中元素的个数
	
	private class Node{
		private T data;
		private Node next;
		
		private Node(T dataPortion) {
			data = dataPortion;
			next = null;
		}
	}
	
	public LList() {
		firstNode = lastNode = null;
		length = 0;
	}

	//insert a node in LinkedList's tail
	@Override
	public boolean add(T newEntry) {
		Node newNode = new Node(newEntry);
		if(isEmpty()){
			firstNode = newNode;
			lastNode = newNode;
		}
		else{
			lastNode.next = newNode;
			lastNode = newNode;
		}
		length++;
		return true;
	}

	@Override
	public boolean add(int position, T newEntry) {
		if(position >=1 && position <= length + 1){
			Node newNode = new Node(newEntry);
			if(isEmpty()){//链表为空时(相当于只能在头部插入)
				firstNode = lastNode = newNode;
				length++;
				return true;
			}
			
			if(position == length + 1){//在尾部插入
				lastNode.next = newNode;
				lastNode = newNode;
			}
			else if(position == 1){//在头部插入
				newNode.next = firstNode;
				firstNode = newNode;
			}
			else{
				Node nodeBefore = getNodeBefore(position);
				newNode.next = nodeBefore.next;
				nodeBefore.next = newNode;
			}
			length++;
			return true;
		}
		return false;
	}

	private Node getNodeBefore(int position){
//		assert isEmpty() == false;
		Node dest = firstNode;
			for(int i = 1; i < position - 1; i++)
				dest = dest.next;
			return dest;
	}
	
	@Override
	public T remove(int givenPositon) {
		T data = null;
		if(givenPositon <1 || givenPositon > length || isEmpty())
			return data;
		
		if(givenPositon == 1){//delete first node
			if(length == 1){
				data = firstNode.data;
				firstNode = lastNode = null;
			}
			else{
				data = firstNode.data;
				Node tmp = firstNode.next;
				firstNode.next = null;
				firstNode = tmp;
			}
		}
		else if(givenPositon == length){//delete last element
			Node nodeBefore = getNodeBefore(length);
			data = nodeBefore.next.data;
			nodeBefore.next = null;
			lastNode = nodeBefore;
		}
		else{
			Node nodeBefore = getNodeBefore(givenPositon);
			Node tmp = nodeBefore.next;
			data = tmp.data;
			nodeBefore.next = tmp.next;
			tmp.next = null;
		}
		length--;
		return data;
	}

	@Override
	public T remove() {
		return remove(length);
	}
	
	@Override
	public void clear() {
		firstNode = lastNode = null;
		length = 0;
	}

	@Override
	public boolean replace(int givenPositon, T newEntry) {
		if(givenPositon < 1 || givenPositon > length || isEmpty())
			return false;
		if(givenPositon == 1)
			firstNode.data = newEntry;
		else if(givenPositon == length)
			lastNode.data = newEntry;
		else{
			Node nodeBefore = getNodeBefore(givenPositon);
			nodeBefore.next.data = newEntry;
		}
		return true;
	}

	@Override
	public T getEntry(int givePosition) {
		if(isEmpty() || givePosition < 1 || givePosition > length)
			return null;
		Node tmp = firstNode;
		for(int i = 1; i < givePosition; i++)
			tmp = tmp.next;
		return tmp.data;
	}

	@Override
	public boolean contains(T anEntry) {
		boolean result = false;
		if(isEmpty())
			return result;
		Node tmp = firstNode;
		while(tmp != null)
		{
			if(tmp.data.equals(anEntry))
			{
				result = true;
				break;
			}
			else{
				tmp = tmp.next;
			}
		}
	return result;
	}

	@Override
	public boolean isEmpty() {
		return length == 0;
	}
	
	@Override
	public String toString()
	{
		StringBuilder sb = new StringBuilder();
		sb.append("[ ");
		Node tmp = firstNode;
		while(tmp != null){
			sb.append(tmp.data.toString() + " ");
			tmp = tmp.next;
		}
		sb.append("]");
		return sb.toString();
	}
}






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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值