java与数据结构(2)---java实现静态链表
结点类
1 //结点类
2 class Node<T> {
3 private T data;
4 private int cursor;
5
6 Node(T data, int cursor) {
7 this.data = data;
8 this.cursor = cursor;
9 }
10
11 public void setData(T data) {
12 this.data = data;
13 }
14
15 public void setCursor(int cursor) {
16 this.cursor = cursor;
17 }
18
19 public T getData() {
20 return this.data;
21 }
22
23 public int getCursor() {
24 return this.cursor;
25 }
26
27 public String toString() {
28 StringBuffer sb = new StringBuffer();
29 sb.append(getData());
30 sb.append(" ");
31 sb.append(getCursor()+" ");
32 return sb.toString();
33 }
34 }
链表接口
//静态链表接口
interface StaticLinkListable<T> { int Length();//静态链表长度 int getBackupListFirstIndex();//获取当前备用链表的首结点地址 T increaseSpaceToBackupList(int k);//将空闲空间回收至备用链表 boolean insert(T element);//尾插 boolean insert(int i, T element);//在第i个位置插入元素element T remove(int i);//删除表中第i个位置的元素 void removeAll();//删除表中所有元素
}
静态链表实现类
//实现了静态链表接口的结点链表
class NodeList<T> implements StaticLinkListable<T> {
private Node[] node=null;//泛型数组
private static final int maxSize = 15; //创建一张长度为1000的备用链表
NodeList() {
this(maxSize);
} //创建一张长度为maxSize的备用链表
NodeList(int maxSize) {
node = new Node[maxSize];//泛型数组如何创建?
//0-998中的cursor依次存放1,2,3,4...999;下标0元素的cursor为1;下标999元素的cursor为0
for(int i = 0; i < maxSize-1; i++) {
node[i] = new Node<T>(null,i+1);
//System.out.println(i+" "+node[i]);
}
node[maxSize-1] = new Node<T>(null,0);
//System.out.println(maxSize-1+" "+node[maxSize-1]);
} //获取静态链表中已经被使用了的数组空间
public int Length() {
int j = node[maxSize-1].getCursor();
int length = 0;
while (j != 0) {
j = node[j].getCursor();
length++;
}
return length;
} //向备用链表申请一个数组单元,给插入操作使用;若备用链表非空,则返回备用首结点的下标,否则返回0
public int applySpaceFromBackupList() {
int i = getBackupListFirstIndex();//当前数组第一个元素的cursor存的值,就是要返回的备用首结点的下标
if(i != 0 ) {
node[0].setCursor(i+1);//由于要拿出备用链表的一个单元使用,那么将该单元的下个单元设为备用首结点
}
return i;
} //获取备用链表首结点所处的单元下标
public int getBackupListFirstIndex() {
return node[0].getCursor();
} //尾插
public boolean insert(T element) {
int i = Length();
return insert(i,element);
} //在表中第i个位置插入数据元素T e
public boolean insert(int i, T element) {
if(i >= maxSize-1) {
return false;
}
int L = Length();
if(i >= L)
i = L+1;
if(i < 1)
i = 1;
int k = maxSize-1;//999
//向备用链表申请空间,以存放要添加的数据元素结点
int m = applySpaceFromBackupList();
if(m > 0) {
//找到数组第i个元素的前一个元素的位置
for(int j = 1; j < i; j++) {
k = node[k].getCursor();
}
//创建一个新的结点,数据是element,cursor指向第i个元素
//将新生成的结点放入链表的最后一个单元,即备用链表的上一个单元
node[m] = new Node<T>(element,node[k].getCursor());
//使当前数组第i个元素前面元素的cursor指向链表尾结点
node[k].setCursor(m);
}
return true;
} //删除表中第i个位置的数据元素
public T remove(int i) {
if(i > maxSize - 1)
return null;
if(i < 1)
i = 1;
int l = Length();
if(i > l)
i = l;
int k = maxSize-1;
//找出第i个位置的前一个数据元素位置
for(int j = 1; j < i; j++)
k = node[k].getCursor();
int m = 0;
//取出前一个数据元素的cursor,也就是i
m = node[k].getCursor();
//将前一个数据元素的cursor设置为当前位置上的cursor,即让当前元素的上一个元素的cursor指向当前元素的下一个元素
node[k].setCursor(node[m].getCursor());
//将删除的元素空间回收至备用链表,并将删除位置作为添加元素的优先存储空间
return increaseSpaceToBackupList(m);
} //删除表中所有的元素
public void removeAll() {
int firIndex = node[0].getCursor();
while(node[0].getCursor() != 1) {
remove(Length());
}
} //把下标为k的空闲结点回收到备用链表,即将k作为备用链表首结点位置,数组第一个元素中的cursor指向第k个单元
public T increaseSpaceToBackupList(int k) {
T temp = (T)node[k].getData();
int m = node[0].getCursor();
node[k].setCursor(m);
node[0].setCursor(k);
return temp;
} public String toString() {
StringBuffer sb = new StringBuffer();
sb.append("[ ");
sb.append(node[0]+" ");
int k = node[maxSize-1].getCursor();
while(k != 0) {
sb.append(node[k]);
k = node[k].getCursor();
}
sb.append(node[maxSize-1]+" ");
sb.append("]");
return sb.toString();
} }
测试
package bistu; /*
*@author Nora-Xie
*@time 2013-10-02 PM 22:02
*/
/*早期的高级编程语言如:Basic、Fortran没有指针,链表结构的实现无法动态实现,于是有人想到用数组实现链表,这就是静态链表。*/
/*由数组描述的链表就是静态链表,其核心是两个数据成员、一个概念和首尾特殊元素三个部分。*/
/*两个数据成员:实际有用的数据data+存储数据的数组单元下标值cursor;*/
/*一个概念:备用链表是静态链表中,删除元素和未被使用到的数组元素;*/
/*首尾特殊元素:数组的第一个元素不存放数据信息,其cursor中存放备用链表第一个结点的下标值;最后一个元素cursor保存着第一个数据值的下标
*/ public class TestStaticLinkList {
public static void main(String[] args) {
StaticLinkListable<String> list = new NodeList<String>();
list.insert("甲");
list.insert("乙");
list.insert("丙");
list.insert("丁");
list.insert("戊");
list.insert("己");
list.insert("庚");
list.insert("辛");
list.insert("壬");
list.insert("奎");
System.out.println(list);
list.remove(12);
System.out.println(list);
list.removeAll();
System.out.println(list);
}
}
java与数据结构(2)---java实现静态链表的更多相关文章
- Java数据结构-线性表之静态链表
静态链表的定义: 节点由一个一维数组和一个指针域组成,数组用来存放数据元素,而指针域里面的指针(又称游标)用来指向下一个节点的数组下标. 这种链表称之为静态链表. 链表中的数组第一个和最后一个位置须要 ...
- c数据结构链式存储-静态链表
#include "string.h" #include "ctype.h" #include "stdio.h" #include &qu ...
- java:数据结构复习(三)链表队列
@TOC 和栈一样,队列也是表,但是使用队列的特点是先进先出. 队列模型 队列的基本操作是入队,它是在表的末端插入一个元素,和出队,它是删除在表开头的一个元素 graph LR A[<kbd&g ...
- java与数据结构(8)---java实现链队列
链队列 实际上就是单链表,只是规定了删除在队头进行,添加在队尾进行. 链队列代码结构 package list.queue; public interface Queuable<T>; p ...
- java与数据结构(4)---java实现双向循环链表
线性表之链式存储结构双向循环链表 双向循环链表:每个结点包含了数据.直接前驱地址指针和直接后驱地址指针,头结点的直接前驱指向尾结点,尾结点的直接后驱指向头结点,头尾相连构成一个可正可反的圆环.可以形象 ...
- java与数据结构(3)---java实现循环链表
循环链表:将单链表中尾结点的指针由空指针改为指向头结点,就使整个单链表形成一个环,这种首尾相接的单链表称为单链表循环表,即循环链表. 循环链表与单链表最重要的区别是:尾结点的指针,不再是p->n ...
- java与数据结构(6)---java实现链栈
栈之链式存储结构链栈 链栈 栈的链式存储结构成为链栈.链栈是没有头结点,头结点就是栈顶指针top. 代码结构 package list; public interface Stackable;公共接口 ...
- 【Java】 大话数据结构(3) 线性表之静态链表
本文根据<大话数据结构>一书,实现了Java版的静态链表. 用数组描述的链表,称为静态链表. 数组元素由两个数据域data和cur组成:data存放数据元素:cur相当于单链表中的next ...
- JAVA 基本数据结构--数组、链表、ArrayList、Linkedlist、hashmap、hashtab等
概要 线性表是一种线性结构,它是具有相同类型的n(n≥0)个数据元素组成的有限序列.本章先介绍线性表的几个基本组成部分:数组.单向链表.双向链表:随后给出双向链表的C.C++和Java三种语言的实现. ...
随机推荐
- NS2仿真:公交车移动周期模型及性能分析
NS2仿真实验报告3 实验名称:公交车移动周期模型及性能分析 实验日期:2015年3月16日~2015年3月21日 实验报告日期:2015年3月22日 一.实验环境(网络平台,操作系统,网络拓扑图) ...
- 设计模式之—简单工厂模式<Simple Factory Pattern >
简单工厂模式结构图: 简单工厂模式以简单的加减乘除运算为例: 运算符类(Operation): namespace CalcTest.Simple_Factory_patterns { class O ...
- 深入理解 CSS变形 transform(3d)
坐标轴 在了解透视之前,首先要先了解坐标轴.3D变形与2D变形最大的不同就在于其参考的坐标轴不同.2D变形的坐标轴是平面的,只存在x轴和y轴,而3D变形的坐标轴则是x.y.z三条轴组成的立体空间,x轴 ...
- 微信js-sdk,选择图片,上传,下载到本地,php服务端
//前端js代码<script> //客户端6.0.2 wx.config({ //debug:true, appId: "{pigcms:$signPackage.appId} ...
- 一些SQL语句的问题
1.getdate()函数问题 go create table table_1( id int primary key identity, name ) not null, daytime datet ...
- oracle过滤名字中含有_的行
select * from emp where ename like '%\_%' escape '\'; escape 定义转义字符串,这样转义字符串后的字符就是普通字符.
- IO流文件字符输入输出流,缓冲流
由于字节输入输出流在操纵Unicode字符时可能有乱码现象 于是就有了操作字符的输入输出流 Reader ,Writer和他们的子类FileReader,FileWrite(其实就是用来辅助构造的 W ...
- 你好,C++(26)如何与函数内部进行数据交换?5.1.3 函数参数的传递
5.1.3 函数参数的传递 我们知道,函数是用来完成某个功能的相对独立的一段代码.函数在完成这个功能的时候,往往需要外部数据的支持,这时就需要在调用这个函数时向它传递所需要的数据它才能完成这个功能获 ...
- UVA11538Chess Queen(组合数学推公式)
转载请注明出处: http://www.cnblogs.com/fraud/ ——by fraud 题目意思:在n*m的棋盘中放置两个不同的皇后,使得两者能够相互攻击,共有多少种放置 ...
- GetWindowText
用于得到窗口中的数据 {// TODO: If this is a RICHEDIT control, the control will not// send this notification un ...