java静态链表_Java数据结构——静态链表实现

本文详细介绍了Java中静态链表的概念、优点、工作原理,并提供了完整的代码示例,展示了如何进行插入、删除等操作。静态链表结合了数组和链表的特点,允许在不移动元素的情况下进行插入和删除,同时避免了动态内存分配的开销。
摘要由CSDN通过智能技术生成

Java数据结构——静态链表实现

一、定义

用数组描述的链表,即称为静态链表。

在C语言中,静态链表的表现形式即为结构体数组,结构体变量包括数据域data和游标CUR。(这里的定义来自于百度百科)

二、优点

(1)这种存储结构,仍需要预先分配一个较大的空间,但在作为线性表的插入和删除操作时不需移动元素,仅需修改指针,故仍具有链式存储结构的主要优点。

(2)假如有如上的静态链表S中存储这线性表(a,b,c,d,f,g,h,i),Maxsize=11,如图所示,要在第四个元素后插入元素e,方法是:先在当前表尾加入一个元素e,即:S[9].data = e;然后修改第四个元素的游标域,将e插入到链表中,即:S[9].cursor = S[4].cursor; S[4].cursor = 9;,接着,若要删除第7个元素h,则先顺着游标链通过计数找到第7个元素存储位置6,删除的具体做法是令S[6].cursor = S[7].cursor。

三、原理图

例如一组数据如下:

(ZHAO,QIAN,SUN,LI,ZHOU,WU,ZHENG,WANG)

a89d80b38bb55fed75e23b2b08706383.png

1 /**

2 * 静态链表的长度3 *@return

4 */

5 public intlength(){6 return size-1;7 }

因为有个空表头,所以长度为size-1;

1 /**

2 * 静态链表的初始化3 */

4 publicStaticLinkList(){5 linkList = newElement[DEFAULT_SIZE];6 for (int i = 0; i < linkList.length; i++) {7 linkList[i] = newElement();8 linkList[i].data = -1;9 linkList[i].cur = i+1;10 }11 //当前空闲节点从1开始,因为第0个节点设置成了头结点,设置为空,不12 //存储数据

13 currentFree = 1;14 }

这里是不指定链表大小的链表初始化,默认长度为DEFAULT_SIZE,第8行为链表数据初始化,第9行初始化游标cur。

1 /**

2 * 给链表添加数据,每当链表满了就给链表添加额外的空间3 *@paramdata4 */

5 public void add(intdata){6 if(size

11 addLinkSpace();12 linkList[currentFree].data =data;13 currentFree =linkList[currentFree].cur;14 size++;15 }16 }

这个函数是给静态链表添加数据,第6行判断链表是否已满,currentFree是指向当前空闲位置,第7行是将要添加的数据添加到空闲位置上,第8行currentFree指向下一个空闲位置,第9行链表实际长度加1,第11行,如果链表已满,则给链表添加空间(addLinkSpace())。

1 /**

2 * 得到索引指定的数据3 *@paramindex4 *@return

5 */

6 public int get(intindex){7 if(index>size-1&&index<0)8 throw new IndexOutOfBoundsException("数组越界,索引不合法");9 else{10 //这里index+1也是因为多了一个空的头节点

11 return linkList[index+1].data;12 }13 }

第11行index+1是因为链表的第一位为空,不取到第一位。

1 /**

2 * 删除指定位置的节点3 *@paramindex4 */

5 public void delete(intindex){6

7 index = index+1;8 if(index<1||index>=size){9 System.out.println("超出链表长度");10 }else if(index == size-1){11 size--;12 linkList =(Element[]) getTrueIndex(linkList,size);13 }else{14 int i = 0;15 while(index!=linkList[i].cur){16 i++;17 }18 int j = 0;19 while(currentFree!=linkList[j].cur){20 j++;21 }22 linkList[i].cur =linkList[index].cur;23 linkList[j].cur =index;24 linkList[index].cur =currentFree;25 currentFree =index;26 size--;27 linkList =(Element[]) getTrueIndex(linkList,size);28 }29 }

第7行也是因为链表头结点为空。第10行是指,如果删除链表的最后一位,则执行下面的操作。第12行是将链表按照逻辑顺序重新排列,是为了显示。第14-17行是为了找到指向index的游标,如果没有12行,则指向index的游标不一定是index-1,因为物理位置连续的,逻辑位置不一定连续。18-21行是为了找到指向当前空闲位置的游标,理由同上。22行是将原指向index的游标指向原index的游标指向的位置,23行是将原指向当前空闲位置的游标指向index,表明index为空闲,24行是将index的游标指向原当前空闲位置,25行是将当前空闲位置指向index。其他的都是差不多的,还有几个函数就不一一介绍了。

四、完整代码示例

4.1 StaticLinkList.java

packagecom.yds.list;/*** 因为静态链表实质上是一维数组的存储方式,所以它在物理位置上的存储

* 是顺序的,但它是用游标来指向下一个数据的,所以根据它的下标来获取数据

* 和按照游标的指向来获取数据是不同的,这里设置该链表的头结点为空

*@authorAdministrator

**/

public classStaticLinkList {private Element[] linkList = null;//private Element[] linkList1 = null;

private int DEFAULT_SIZE = 4;//默认存储大小

private int currentFree = 0;//指向当前空闲位置

private int size = 1;classElement{intdata;intcur;

}/*** 静态链表的长度

*@return

*/

public intlength(){return size-1;

}/*** 静态链表的初始化*/

publicStaticLinkList(){

linkList= newElement[DEFAULT_SIZE];for (int i = 0; i < linkList.length; i++) {

linkList[i]= newElement();

linkList[i].data= -1;

linkList[i].cur= i+1;

}//当前空闲节点从1开始,因为第0个节点设置成了头结点,设置为空,不//存储数据

currentFree = 1;

}/*** 给链表添加数据,每当链表满了就给链表添加额外的空间

*@paramdata*/

public void add(intdata){if(size

linkList[currentFree].data=data;

currentFree=linkList[currentFree].cur;

size++;

}else{//链表已满,给链表添加空间

addLinkSpace();

linkList[currentFree].data=data;

currentFree=linkList[currentFree].cur;

size++;

}

}/*** 得到索引指定的数据

*@paramindex

*@return

*/

public int get(intindex){if(index>size-1&&index<0)throw new IndexOutOfBoundsException("数组越界,索引不合法");else{//这里index+1也是因为多了一个空的头节点

return linkList[index+1].data;

}

}/*** 删除指定位置的节点

*@paramindex*/

public void delete(intindex){

index= index+1;if(index<1||index>=size){

System.out.println("超出链表长度");

}else if(index == size-1){

size--;

linkList=(Element[]) getTrueIndex(linkList,size);

}else{int i = 0;while(index!=linkList[i].cur){

i++;

}int j = 0;while(currentFree!=linkList[j].cur){

j++;

}

linkList[i].cur=linkList[index].cur;

linkList[j].cur=index;

linkList[index].cur=currentFree;

currentFree=index;

size--;

linkList=(Element[]) getTrueIndex(linkList,size);

}

}/*** 增加链表空间*/

public voidaddLinkSpace(){

DEFAULT_SIZE+=8;

Element[] link=linkList;

linkList= newElement[DEFAULT_SIZE];

System.arraycopy(link,0, linkList, 0, link.length);for (int i = link.length; i < DEFAULT_SIZE; i++) {

linkList[i]= newElement();

linkList[i].data= -1;

linkList[i].cur= i+1;

}

currentFree=link.length;

}/*** 根据指定的位置插入数据

*@paramindex

*@paramdata*/

public void insert(int index,intdata){//这里加1的原因是因为链表的第0位为空节点,这里设置的头节点为空

index = index + 1;if(sizesize&&index<0)

System.out.println("数组越界,超出数组长度");else if(index ==size){

linkList[currentFree].data=data;

currentFree=linkList[currentFree].cur;

size++;

}else{/******未按逻辑顺序排序而插入数据的写法,因为未排序,则当前索引的上个节点的索引不一定是当前索引减1****/

int i = 0;while(index!=linkList[i].cur){

i++;

}int j = 0;while(currentFree!=linkList[j].cur){

j++;

}

linkList[i].cur=currentFree;

linkList[j].cur=linkList[currentFree].cur;

linkList[currentFree].data=data;

linkList[currentFree].cur=index;

currentFree=linkList[j].cur;

size++;//每次插入后将链表按逻辑顺序重新排序,是为了方便输出查看。

linkList =(Element[]) getTrueIndex(linkList,size);

}

}else{

addLinkSpace();

insert(index, data);

}

}/*** 按照逻辑顺序重新排列

*@paramlink

*@return

*/

public Object getTrueIndex(Element[] link,intsize){

Element[] linkList1= newElement[linkList.length];int k =0;for (int i = 0; i < linkList.length; i++) {

linkList1[i]= newElement();

linkList1[i].data=link[k].data;

k=link[k].cur;

linkList1[i].cur= i+1;

}//插入时,currentFree肯定是最后一个了,但删除后,currentFree就不一定是最后一位了

currentFree =size;returnlinkList1;

}

}

4.2 JavaMain.java

packagecom.yds.list;public classJavaMain {public static voidmain(String[] args) {//TODO Auto-generated method stub

StaticLinkList listA = newStaticLinkList();int la[]={2,3,5,8,9,6,7};for (int i = 0; i < la.length; i++) {

listA.add(la[i]);

}

listA.delete(6);

listA.delete(0);

listA.insert(3, 88);

listA.insert(3, 78);for (int i = 0; i < listA.length(); i++) {

System.out.println(listA.get(i));

}

}

}

五、结果截图

5845b0bb8c72e93d5c89cbc36f97fe1f.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值