java线性数据结构_Java数据结构学习-线性结构

线性结构

线性表是一种线性结构,它是具有相同类型的n(n≥0)个数据元素组成的有限序列;

线性表的基本组成为:数组,单项链表,双向链表;

数组

数组有上界和下界,数组的元素在上下界内是连续的;

比如存储一个整数的数组定义为:

int[] arr = {10,20,30,40,50};

数组的特点是:数据是连续的;随机访问速度快;

数组中稍微复杂一点的是多维数组和动态数组.对于C语言而言,多维数组本质上也是通过一位数组实现的;

至于动态数组,是指数组的容量能动态增长的数组;

对于C语言而言,若要提供动态数组,需要手动实现;

而对于C++而言,STL提供了Vector;

对于Java而言,Collection集合中提供了ArrayList和Vector;

单向链表

单向链表(单链表)是链表的一种,它由节点组成,每个节点都包含下一个节点的指针;

单链表的示意图如下:

f79bc1ceeeb56b341422ace7d12c2673.png

表头为空,表头的后继节点是"节点10"(数据为10的节点),"节点10"的后继节点是"节点20"(数据为20的节点),...

单链表删除节点

d081cf7f6b0edf8e79d0af6a45a280e5.png

删除"节点30"

删除之前:"节点20"的后继节点为"节点30",而"节点30"的后继节点为"节点40";

删除之后:"节点20"的后继节点为"节点40";

单链表添加节点

91296f3af75f071d6a5abd36a337eea5.png

在"节点10"与"节点20"之间添加"节点15";

添加之前:"节点10"的后继节点为"节点20";

添加之后:"节点10"的后继节点为"节点15",而"节点15"的后继节点为"及诶单20";

双向链表

双向链表(双链表)时候链表的一种;和单链表一样,双链表也是由节点组成的,它的每个数据节点中都有俩个指针,分别指向直接后继和直接前驱;所以,从双向链表中的任意一个节点开始,都可以很方便的访问它的前驱节点和后继节点;一般我们都够着双向循环链表;

双链表的示意图如下:

6ab2eb2392128dc4bd9fb02c8df137be.png

表头为空,表头的后继节点为"节点10"(数据为10的节点);

"节点10"的后继节点是"节点20"(数据为10的节点),"节点20"的前驱节点是"节点10";

"节点20"的后继节点是"节点30","节点30"的前驱节点是"节点20";...;

末尾节点的后继节点是表头;

双链表删除节点

946a9e1ebb867c127a060bdf392ee2ab.png

删除"节点30"

删除之前:"节点20"的后继节点为"节点30","节点30"的前驱节点为"节点20";

"节点30"的后继节点为"节点40","节点40"的前驱节点为"节点30";

删除之后:"节点20"的后继节点为"节点40","节点40"的前驱节点为"节点20";

双链表添加节点

2673c70c327da78d5e74eba0813f7eff.png

在"节点10"与"及诶单20"之间添加"节点15";

添加之前:"节点10"的后继节点为"节点20","节点20"的前驱节点为"节点10";

添加之后:"节点10"的后继节点为"节点15","节点15"的前驱节点为"节点10";

"节点15"的后继节点为"节点20","节点20"的前驱节点为"节点15";

下面演示一下双链表的实现,只介绍Java语言的三种实现

双链表类(DoubleLink.java)

/*** Java 实现的双向链表。

* 注:java自带的集合包中有实现双向链表,路径是:java.util.LinkedList

**/

public class DoubleLink{//表头

private DNodemHead;//节点个数

private intmCount;//双向链表“节点”对应的结构体

private class DNode{publicDNode prev;publicDNode next;publicT value;publicDNode(T value, DNode prev, DNode next) {this.value =value;this.prev =prev;this.next =next;

}

}//构造函数

publicDoubleLink() {//创建“表头”。注意:表头没有存储数据!

mHead = new DNode(null, null, null);

mHead.prev= mHead.next =mHead;//初始化“节点个数”为0

mCount = 0;

}//返回节点数目

public intsize() {returnmCount;

}//返回链表是否为空

public booleanisEmpty() {return mCount==0;

}//获取第index位置的节点

private DNode getNode(intindex) {if (index<0 || index>=mCount)throw newIndexOutOfBoundsException();//正向查找

if (index <= mCount/2) {

DNode node =mHead.next;for (int i=0; i

node=node.next;returnnode;

}//反向查找

DNode rnode =mHead.prev;int rindex = mCount - index -1;for (int j=0; j

rnode=rnode.prev;returnrnode;

}//获取第index位置的节点的值

public T get(intindex) {returngetNode(index).value;

}//获取第1个节点的值

publicT getFirst() {return getNode(0).value;

}//获取最后一个节点的值

publicT getLast() {return getNode(mCount-1).value;

}//将节点插入到第index位置之前

public void insert(intindex, T t) {if (index==0) {

DNode node = new DNode(t, mHead, mHead.next);

mHead.next.prev=node;

mHead.next=node;

mCount++;return;

}

DNode inode =getNode(index);

DNode tnode = new DNode(t, inode.prev, inode);

inode.prev.next=tnode;

inode.next=tnode;

mCount++;return;

}//将节点插入第一个节点处。

public voidinsertFirst(T t) {

insert(0, t);

}//将节点追加到链表的末尾

public voidappendLast(T t) {

DNode node = new DNode(t, mHead.prev, mHead);

mHead.prev.next=node;

mHead.prev=node;

mCount++;

}//删除index位置的节点

public void del(intindex) {

DNode inode =getNode(index);

inode.prev.next=inode.next;

inode.next.prev=inode.prev;

inode= null;

mCount--;

}//删除第一个节点

public voiddeleteFirst() {

del(0);

}//删除最后一个节点

public voiddeleteLast() {

del(mCount-1);

}

}

测试程序(DlinkTest.java)

/*** Java 实现的双向链表。

* 注:java自带的集合包中有实现双向链表,路径是:java.util.LinkedList

**/

public classDlinkTest {//双向链表操作int数据

private static voidint_test() {int[] iarr = {10, 20, 30, 40};

System.out.println("\n----int_test----");//创建双向链表

DoubleLink dlink = new DoubleLink();

dlink.insert(0, 20); //将 20 插入到第一个位置

dlink.appendLast(10); //将 10 追加到链表末尾

dlink.insertFirst(30); //将 30 插入到第一个位置//双向链表是否为空

System.out.printf("isEmpty()=%b\n", dlink.isEmpty());//双向链表的大小

System.out.printf("size()=%d\n", dlink.size());//打印出全部的节点

for (int i=0; i

System.out.println("dlink("+i+")="+dlink.get(i));

}private static voidstring_test() {

String[] sarr= {"ten", "twenty", "thirty", "forty"};

System.out.println("\n----string_test----");//创建双向链表

DoubleLink dlink = new DoubleLink();

dlink.insert(0, sarr[1]); //将 sarr中第2个元素 插入到第一个位置

dlink.appendLast(sarr[0]); //将 sarr中第1个元素 追加到链表末尾

dlink.insertFirst(sarr[2]); //将 sarr中第3个元素 插入到第一个位置//双向链表是否为空

System.out.printf("isEmpty()=%b\n", dlink.isEmpty());//双向链表的大小

System.out.printf("size()=%d\n", dlink.size());//打印出全部的节点

for (int i=0; i

System.out.println("dlink("+i+")="+dlink.get(i));

}//内部类

private static classStudent {private intid;privateString name;public Student(intid, String name) {this.id =id;this.name =name;

}

@OverridepublicString toString() {return "["+id+", "+name+"]";

}

}private static Student[] students = newStudent[]{new Student(10, "sky"),new Student(20, "jody"),new Student(30, "vic"),new Student(40, "dan"),

};private static voidobject_test() {

System.out.println("\n----object_test----");//创建双向链表

DoubleLink dlink = new DoubleLink();

dlink.insert(0, students[1]); //将 students中第2个元素 插入到第一个位置

dlink.appendLast(students[0]); //将 students中第1个元素 追加到链表末尾

dlink.insertFirst(students[2]); //将 students中第3个元素 插入到第一个位置//双向链表是否为空

System.out.printf("isEmpty()=%b\n", dlink.isEmpty());//双向链表的大小

System.out.printf("size()=%d\n", dlink.size());//打印出全部的节点

for (int i=0; i

System.out.println("dlink("+i+")="+dlink.get(i));

}

}public static voidmain(String[] args) {

int_test();//演示向双向链表操作“int数据”。

string_test(); //演示向双向链表操作“字符串数据”。

object_test(); //演示向双向链表操作“对象”。

}

}

运行结果

1 ----int_test----

2 isEmpty()=false

3 size()=3

4 dlink(0)=30

5 dlink(1)=20

6 dlink(2)=10

7

8 ----string_test----

9 isEmpty()=false

10 size()=3

11 dlink(0)=thirty12 dlink(1)=twenty13 dlink(2)=ten14

15 ----object_test----

16 isEmpty()=false

17 size()=3

18 dlink(0)=[30, vic]19 dlink(1)=[20, jody]20 dlink(2)=[10, sky]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值