1,对于线性表而言,里面的元素是无序的,可以随意地将新元素增加到线性表中而不需要考虑该元素在线性表中的位置。但是,对于有序表而言,其中的元素是按照某种方式进行排序的,因此在有序表中插入元素时,需要按照顺序将该新元素放置到有序表的合适的位置。

但由于有序表与线性表有很多相似的地方,因此,下面通过继承线性表来实现有序表。线性表的实现参考:http://www.cnblogs.com/hapjin/p/4549492.html

2,在Node内部类的实现中,定义了获取Node类的属性的get方法和set方法,这些方法为protected类型的,意味着Node类所在的外部类的子类可以通过这些方法来访问Node类里面的数据域。同样地,在Node类所在的外部类中(LinkedChainBase)也定义了protected类型的方法addFirstNode、getFirstNode、removeFirstNode……这样使得LinkedChainBase的子类可以直接访问其数据域,提高操作的效率。

3,有序表的实现类SortedLinkList.java通过继承基类LinkedChainBase来达到直接访问线性中的数据域的目的。由于有序表终究不是线性表,因此从线性表中继承而来的某些方法(如:replace方法)会破坏有序的有序性质。因此,对于这些方法可能通过抛出异常的方式来处理。

ListInterface代码参考:http://www.cnblogs.com/hapjin/p/4549492.html

具体的实现代码如下:

基类LinkedChainBase.java

public class LinkedChainBase<T> implements java.io.Serializable {
private Node firstNode;
private int length; public LinkedChainBase(){
clear();
}
public final void clear() {//clear()在构造器中被调用了,所以此外用final修饰符
firstNode = null;
length = 0;
} /*
* 提供操作数据域firstNode的protected方法,使得子类可以直接操作表的数据域
*/
//在表的表头插入元素
protected void addFirstNode(Node newNode){
assert newNode != null:"null argument in addFirstNode";
newNode.setNextNode(firstNode);
firstNode = newNode;
length++;
} protected Node getFirstNode(){//获取表的第一个结点
return firstNode;
}
//获取表中某个位置处的结点
protected Node getNodeAt(int givenPosition){
assert (!isEmpty() && ((1 <= givenPosition) && (givenPosition <= length)));
Node currentNode = firstNode;
for(int counter = 1; counter < givenPosition; counter++){
currentNode = currentNode.next;
}
assert currentNode != null;
return currentNode;
}
//在表中某个结点后添加新结点
protected void addAfterNode(Node nodeBefore, Node newNode){
assert newNode != null:"illegal to add a null node";
newNode.setNextNode(nodeBefore.getNextNode());
nodeBefore.setNextNode(newNode);
}
//删除表中的第一个结点
protected T removeFirstNode(){
T result = null;
if(firstNode != null){
result = firstNode.data;
firstNode = firstNode.getNextNode();
}
return result;
}
//删除表中的指定结点后的其他结点
// protected T removeAfterNode(Node nodeBefore){
//
// }
public boolean isEmpty() {//判断链表是否为空
boolean result;
if(length == 0){
assert firstNode == null;
result = true;
}
else{
assert firstNode != null;
result = false;
}
return result;
} public int getLength() {//获取表的长度
return length;
} public void display() {//遍历表,显示表中的每个结点的值
Node currentNode = firstNode;
while(currentNode != null){
System.out.println(currentNode.data);
currentNode = currentNode.next;
}
} public T getEntry(int givenPosition) {//获取指定位置的结点的值
T result = null;
if((!isEmpty()) && ((givenPosition >= 1) && (givenPosition <= getLength()))){
result = getNodeAt(givenPosition).getData();
}
return result;
} public boolean contains(T anEntry) {//判断链表中的结点是否包含某个值
boolean found = false;
Node currentNode = getFirstNode();
while(!found && currentNode != null){
if(currentNode.getData().equals(anEntry)){
found = true;
break;
}
currentNode = currentNode.getNextNode();
}
return found;
} /*
* Node 是一个内部类,通用类型T与类中声明的通用类型相同,因此Node后面不需要<T>
* Node 声明为protected,这样子类就可以访问Node类中的方法,从而直接地操作线性表的数据域,提高操作效率
*/
protected class Node{
private T data;
private Node next; protected Node(T dataPortion){
data = dataPortion;
next = null;
}
private Node(T dataPortion, Node nextNode){
data = dataPortion;
next = nextNode;
}
protected T getData(){
return data;
}
protected void setData(T dataPortion){
data = dataPortion;
}
protected Node getNextNode(){
return next;
}
protected void setNextNode(Node nextNode){
next = nextNode;
}
}
}

有序表的实现类SortedLinkList.java

import linklist.ListInterface;
public class SortedLinkList<T extends Comparable<? super T>> extends LinkedChainBase<T>
implements ListInterface<T>,java.io.Serializable { //有序表中的元素之所以是有序的,主要是通过该add方法来保证的
@Override
public boolean add(T newEntry) {
Node newNode = new Node(newEntry);
Node nodeBefore = getNodeBefore(newEntry);
if(nodeBefore == null)
addFirstNode(newNode);
else
addAfterNode(nodeBefore, newNode);
return true;
} private Node getNodeBefore(T anEntry){
Node currentNode = getFirstNode();
Node nodeBefore = null;
//对待插入的元素与有序表中的元素进行比较,保证元素有序
while((currentNode != null) && (anEntry.compareTo(currentNode.getData()) > 0)){
nodeBefore = currentNode;
currentNode = currentNode.getNextNode();
}
return nodeBefore;
} @Override
public boolean add(int givenPosition, T newEntry) {
throw new UnsupportedOperationException("illegal to add element at a specified position.");
} @Override
public T remove(int givenPosition) {
throw new UnsupportedOperationException("illegal to add element at a specified position."); } @Override
public boolean replace(int givenPosition, T newEntry) {
throw new UnsupportedOperationException("illegal to add element at a specified position.");
}
}

参考《数据结构与算法分析 第二版 JAVA语言描述》Frank M. Carrano 著

JAVA通过继承线性表来实现有序表的更多相关文章

  1. 查找->静态查找表->折半查找(有序表)

    文字描述 以有序表表示静态查找表时,可用折半查找算法查找指定元素. 折半查找过程是以处于区间中间位置记录的关键字和给定值比较,若相等,则查找成功,若不等,则缩小范围,直至新的区间中间位置记录的关键字等 ...

  2. 查找(顺序表&有序表)

    [1]查找概论 查找表是由同一类型是数据元素(或记录)构成的集合. 关键字是数据元素中某个数据项的值,又称为键值. 若此关键字可以唯一标识一个记录,则称此关键字为主关键字. 查找就是根据给定的某个值, ...

  3. Java数据结构之线性表(2)

    从这里开始将要进行Java数据结构的相关讲解,Are you ready?Let's go~~ java中的数据结构模型可以分为一下几部分: 1.线性结构 2.树形结构 3.图形或者网状结构 接下来的 ...

  4. Java数据结构之线性表

    从这里开始将要进行Java数据结构的相关讲解,Are you ready?Let's go~~ java中的数据结构模型可以分为一下几部分: 1.线性结构 2.树形结构 3.图形或者网状结构 接下来的 ...

  5. 第一阶段:Java内功秘籍-线性表

    前言 为什么要学习数据结构与算法,如果你学会了做安卓,javaweb,前端等,都是你的武功秘籍,但是如果你的内功不够好,再厉害的功夫也是白费. 数据结构和算法:什么是数据结构,什么是数据,在计算机内部 ...

  6. Java数据结构与算法(1) - ch02有序表(OrderedArray)

    有序表需要掌握的插入方法,删除方法和二分法查找方法. 插入方法: 从前往后找到比要插入的值大的数组项,将该数组项及之后的项均后移一位(从最后一项起依次后移),最后将要插入的值插入当前数组项. 删除方法 ...

  7. java数据结构之有序表查找

    这篇文章是关于有序表的查找,主要包括了顺序查找的优化用法.折半查找.插值查找.斐波那契查找: 顺序优化查找:效率极为底下,但是算法简单,适用于小型数据查找: 折半查找:又称为二分查找,它是从查找表的中 ...

  8. Java的继承、封装与多态

    Java的继承.封装与多态 基本概念 面向对象OO(Object Oriented):把数据及对数据的操作方法放在一起,作为一个相互依存的整体,即对象. 对同类对象抽象出共性,即类. 比如人就是一个类 ...

  9. [ Java学习基础 ] Java的继承与多态

    看到自己写的东西(4.22的随笔[ Java学习基础 ] Java构造函数)第一次达到阅读100+的成就还是挺欣慰的,感谢大家的支持!希望以后能继续和大家共同学习,共同努力,一起进步!共勉! ---- ...

随机推荐

  1. html5 视频和音频

    视频:html5支持视屏文件或者视屏流. html5使用video元素来播放视屏,支持的类型有OGG,MEPG 4,webM,但是不同的浏览器支持类型不同. src可以放置视屏文件的路径,可以使用元素 ...

  2. 荣耀实锤Magic2或将助力AI,再次带动成长?

    临近年底,热闹了一年的手机圈纷纷偃旗息鼓,准备为明年3月的新品发力.然而今天(12月7日),恰逢节气大雪,@荣耀手机 在微博发布了一张预热海报,随后荣耀总裁赵明转发这条微博表示「关于技术,真的有很多话 ...

  3. asp.net 后台<%@ Page%> page指令属性

    aspx文件有如下一行代码: <%@ Page Language="C#" AutoEventWireup="true" CodeBehind=" ...

  4. BZOJ4785 ZJOI2017树状数组(概率+二维线段树)

    可以发现这个写挂的树状数组求的是后缀和.find(r)-find(l-1)在模2意义下实际上查询的是l-1~r-1的和,而本来要查询的是l~r的和.也就是说,若结果正确,则a[l-1]=a[r](mo ...

  5. Network POJ - 3694(lca并查集+连通图求桥)

    就是求出原先图中的桥的数量,在每一次询问时加入一条新边,求加入当前边后图中剩余的桥的数量 求出原先图中的桥的数量,然后减去新加入边的两端点之间的桥的数量,就是剩余桥的数量.. 用并查集把属于同一集合的 ...

  6. MT【224】反解系数

    (2011安徽省赛)$f(x)=ax^3+bx+c(a,b,c\in R),$当$0\le x \le 1$时,$0\le f(x)\le 1$,求$b$的可能的最大值. 提示:取三个点$f(0),f ...

  7. 自学Linux Shell11.6-退出shell

    点击返回 自学Linux命令行与Shell脚本之路 11.6-退出shell shell运行的每一个命令都是使用 退出状态码 告诉shell它已经运行完毕.退出状态码是一个0~255的整数值,在命令结 ...

  8. 自学Linux Shell12.6-嵌套循环for命令

    点击返回 自学Linux命令行与Shell脚本之路 12.6-嵌套循环for命令 嵌套循环就是在一个循环中还有一个循环. 内部循环在外部循环体中,在外部循环的每次执行过程中都会触发内部循环,直到内部循 ...

  9. tensorflow GPU版本安装及配置

    经检测速度大幅度上升,不枉费我折腾了这么久,最坑的就是网上教程.书都没有写将cuda的bin加入全局变量,还是根据报错信息推出来的. 1.cuda9.0下载安装 https://developer.n ...

  10. Java -- JDBC_DAO 设计模式

    DAO:Date Access Object 实现代码模块化,更加有利于代码的维护和升级. DAO 可以被子类继承或者直接使用. 访问数据信息的类,包含对数据的CRUD(create read upd ...