如何实现自定义的数据结构?以线性表的实现为例分析
2016-03-02 13:55
567 查看
一,目标
1,采用JAVA语言实现线性表。采用链式存储结构实现。
2,抽象数据类型ADT设计(线性表需要提供什么接口?)
3,ADT实现(采用何种具体的存储结构,如顺序数组或单链表)
二,定义接口ListInterface<T>,确定线性表要提供的方法
三,确定数据结构
结点如何表示?
结点由数据域和指针域构成。
结点初始化:构造一个结点时,必须提供数据域的值。
结点类以内部类方式实现
四,单链表的实现
1,采用的存储结构---链式存储结构
2,单链表的属性---头结点指针、尾结点指针、链表的长度(length)
3,方法实现
添加节点时,需要把各个节点链接起来;删除时,需要保证不断链;查找时需要顺序扫描.....
4,边界条件考虑
当链表为空时,增加、删除操作怎么实现?
在头结点、尾结点处增加、删除结点时,应如何操作?
5,操作的时间复杂度和究竟复杂度考虑
查找某元素时,时间复杂度为多少?
删除指定位置处的元素的时间复杂度与删除最后一个元素的时间复杂度是不是不同?
完整代码参考:
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(); } }
相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- Android IPC进程间通讯机制
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- 介绍一款信息管理系统的开源框架---jeecg
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- PropertyChangeListener简单理解
- c++11 + SDL2 + ffmpeg +OpenAL + java = Android播放器
- 插入排序
- 冒泡排序
- 堆排序
- 快速排序
- 二叉查找树