数据结构Java实现----单向链表的插入和删除

一、链表结构: (物理存储结构上不连续,逻辑上连续;大小不固定)           

概念:

  链式存储结构是基于指针实现的。我们把一个数据元素和一个指针称为结点

        数据域:存数数据元素信息的域。

        指针域:存储直接后继位置的域。

  链式存储结构是用指针把相互直接关联的结点(即直接前驱结点或直接后继结点)链接起来。链式存储结构的线性表称为链表。 

链表类型:

  根据链表的构造方式的不同可以分为:

  • 单向链表
  • 单向循环链表
  • 双向循环链表

 

二、单链表:

概念:

    链表的每个结点中只包含一个指针域,叫做单链表(即构成链表的每个结点只有一个指向直接后继结点的指针)

单链表中每个结点的结构:

912d954f-de3f-4d35-bd01-3c4f87d9993b

1、头指针和头结点:

单链表有带头结点结构和不带头结点结构两种。

“链表中第一个结点的存储位置叫做头指针”,如果链表有头结点,那么头指针就是指向头结点的指针。

头指针所指的不存放数据元素的第一个结点称作头结点(头结点指向首元结点)。头结点的数据域一般不放数据(当然有些情况下也可存放链表的长度、用做监视哨等)

存放第一个数据元素的结点称作第一个数据元素结点,或称首元结点

如下图所示:

5fdb1362-fd98-4d23-9932-271f2ab9d480

不带头结点的单链表如下:

14c9aae5-c9fc-4dbe-b5c4-29c05ed84c5e

带头结点的单链表如下图:

a9afd20d-da0f-4c59-a2d6-d8eb8175933b

 

2、不带头结点的单链表的插入操作:

912a8385-5a98-48b8-a515-8dfd9347042d

上图中,是不带头结点的单链表的插入操作。如果我们在非第一个结点前进行插入操作,只需要a(i-1)的指针域指向s,然后将s的指针域指向a(i)就行了;如果我们在第一个结点前进行插入操作,头指针head就要等于新插入结点s,这和在非第一个数据元素结点前插入结点时的情况不同。另外,还有一些不同情况需要考虑。

因此,算法对这两种情况就要分别设计实现方法

3、带头结点的单链表的插入操作:(操作统一,推荐)

95b7d67d-ddaa-4b00-99f6-c1acf4f708b1

上图中,如果采用带头结点的单链表结构,算法实现时,p指向头结点,改变的是p指针的next指针的值(改变头结点的指针域),而头指针head的值不变

因此,算法实现方法比较简单,其操作与对其它结点的操作统一

 

问题1:头结点的好处:

  头结点即在链表的首元结点之前附设的一个结点,该结点的数据域中不存储线性表的数据元素,其作用是为了对链表进行操作时,可以对空表、非空表的情况以及对首元结点进行统一处理,编程更方便。

问题2:如何表示空表:

  无头结点时,当头指针的值为空时表示空表;
  有头结点时,当头结点的指针域为空时表示空表。

 

如下图所示:

问题3:头结点的数据域内装的是什么?

头结点的数据域可以为空,也可存放线性表长度等附加信息,但此结点不能计入链表长度值

 

三、单项链表的代码实现:

1、结点类:

单链表是由一个一个结点组成的,因此,要设计单链表类,必须先设计结点类。结点类的成员变量有两个:一个是数据元素,另一个是表示下一个结点的对象引用(即指针)。

步骤如下:

(1)头结点的构造(设置指针域即可)

(2)非头结点的构造

(3)获得当前结点的指针域

(4)获得当前结点数据域的值

(5)设置当前结点的指针域

(6)设置当前结点数据域的值

注:类似于get和set方法,成员变量是数据域和指针域。

代码实现:

(1)List.java:(链表本身也是线性表,只不过物理存储上不连续)

//线性表接口
public interface List {
    //获得线性表长度
    public int size();

    //判断线性表是否为空
    public boolean isEmpty();

    //插入元素
    public void insert(int index, Object obj) throws Exception;

    //删除元素
    public void delete(int index) throws Exception;

    //获取指定位置的元素
    public Object get(int index) throws Exception;
}

 

(2)Node.java:结点类

//结点类
public class Node {

    Object element; //数据域
    Node next;  //指针域

    //头结点的构造方法
    public Node(Node nextval) {
        this.next = nextval;
    }

    //非头结点的构造方法
    public Node(Object obj, Node nextval) {
        this.element = obj;
        this.next = nextval;
    }

    //获得当前结点的指针域
    public Node getNext() {
        return this.next;
    }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值