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. GitLab添加ssh-key,操作无需每次输入账号密码

    git config --global credential.helper store 然后操作pull/push 会让输入用户名密码,第一次输入进去.下次再操作pull/push时就不需要输入用户名 ...

  2. const修饰符与函数

    一.用const修饰函数的参数 函数参数类型前加const指明该参数为常量,在函数内部不可改变. void func(const int x) { //x不可以在内部进行赋值等操作. } 注:当参数为 ...

  3. msql 复杂练习

    https://blog.csdn.net/xiao__oaix/article/details/78122294 customer表branch 表account 表 depositor 表loan ...

  4. linux 下端口close_wait 过多问题

    情景描述:系统产生大量“Too many open files” 原因分析:在服务器与客户端通信过程中,因服务器发生了socket未关导致的closed_wait发生,致使监听port打开的句柄数到了 ...

  5. Java微信二次开发(三)

    各种类型消息的封装 第一步:找到com.wtz.message.response包,新建类Image.java package com.wtz.message.response; /** * @aut ...

  6. html DOM 方法和屬性

    html利用javascript對節點執行動作: 每一個節點是一個節點對象,對節點的動作是通過方法和屬性接口實現的: 方法:就是執行的動作: 屬性就是節點的屬性(包括設置和獲取): 常見方法和作用: ...

  7. Essential Phone PH1官方刷机方法

    Essential Phone官方有两种包 一种是ota包,即sideload线刷使用的包.但此刷机方法只能ota升级,不能降级. 另一种是Images包,即fastboot线刷使用的包.这种方法可以 ...

  8. 配置dataimport时候 如果css样式有问题 要修改index和admin的版本号

  9. 一本通1609【例 4】Cats Transport

    1609:[例 4]Cats Transport 时间限制: 1000 ms         内存限制: 524288 KB sol:非常偷懒的截图了事 注意:只能猫等人,不能人等猫 对于每只猫,我们 ...

  10. day30 __new__ 以及单例模式

    __new__ # __new__ # object.__new__() class A : def __init__(self): self.x = 1 print("init执行啦&qu ...