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. [日常工作]Oracle12cr2在日常工作中遇到的不兼容的问题

    Oracle12c 数据库GS实例时需要使用新驱动,避免制单出现获取不到正确凭证编号内码的问题. Oracle12c 会产生大量的隐藏表,部分ddl语句会报错. Oracle12c 删除了VM_con ...

  2. Pyhton语句

    一.if条件语句 1.python 并不支持 switch 语句 num = 5 if num == 3: # 判断num的值 print 'boss' elif num == 2: print 'u ...

  3. Node require

    var user = require("./module_user");//使用模块 module_userconsole.log(user.userCount);user.use ...

  4. ThreadLocal的使用场景及实现原理

    1. 什么是ThreadLocal? 线程局部变量(通常,ThreadLocal变量是private static修饰的,此时ThreadLocal变量相当于成为了线程内部的全局变量) 2. 使用场景 ...

  5. C# 8小特性

    对于C# 8,有吸引了大多数注意力的重大特性,如默认接口方法和可空引用,也有许多小特性被考虑在内.本文将介绍几例可能加入C#未来版本的小特性. 新的赋值运算符:&&=和||= 从第一个 ...

  6. redis map存储的注意点

  7. checkStyle 错误普及

    1Type is missing a javadoc commentClass  缺少类型说明 2“{” should be on the previous line“{” 应该位于前一行.解决方法: ...

  8. Mvc 前台 匿名对象

    View无法使用 dynamic 报错: object 未包含....的属性 这里需要区别一下:如果dynamic只是简单模型,那么还是可以使用的.例如 dynamic v = new Expando ...

  9. 利用Python攻破12306的最后一道防线

    各位同学大家好,我是强子,好久没跟大家带来最新的技术文章了,最近有好几个同学问我12306自动抢票能否实现,我就趁这两天有时间用Python做了个12306自动抢票的项目,在这里我来带着大家一起来看看 ...

  10. 自学Linux Shell11.1-shell概述

    点击返回 自学Linux命令行与Shell脚本之路 11.1-shell概述 Shell 是一个用 C 语言编写的程序,它是用户使用 Linux 的桥梁.Shell 既是一种命令语言,又是一种程序设计 ...