数据结构2 线性表的链式表示与实现(Java)

01 概念

存储空间是不连续的,由存储地址链接起来。 单链表,由头指针确定,可以用头指针的名字来命名。

每个节点由两部分组成:1.数据元素。2.指向下一个节点的指针。

还有双链表(由两个指针域,指向前后元素)和循环链表(首尾相接)

单链表中的几个概念:

image-20240410152228677

1.头指针:指向链表中第一个节点的指针(相当于是链表名) 2.首元节点:链表中存储第一个数据元素的节点 3.头节点:在链表首元节点之前附设的一个节点

所以,单链表有两种类型:带头结点和不带头节点

image-20240410152451351

如何表示空表呢? 无头节点时 head=null; 有头节点时 head.next = null

设置头节点的好处: 1.便于首元节点的处理 2.便于空表和非空表的处理

头节点数据域中装的是什么呢?可以自己定义,注意 头节点不计入链表长度

链表的特点:

1.逻辑上相邻的元素在物理位置上不一定相邻 2.访问时,只能通过头指针进入链表,需要以此向后顺序遍历其它节点

02单链表的定义

image-20240410153740070

链表类:

class SingleLinkList {
     LinkListNode head; //定义单链表的头节点
     int length;  //定义单链表的长度
}

节点类:

class LinkListNode {
     Integer data; //数据域
     LinkListNode next;//指针域
}

03单链表基本操作的实现

单链表的初始化

//初始化单链表
public SingleLinkList() {
    this.head = new LinkListNode();
}

判断链表是否为空

//判断链表是否为空
public boolean isEmpty(){
     return length==0;
}

单链表的销毁

     //销毁单链表,链表销毁后不存在
     public void destroyList(){
          head = null;
     }

单链表的清空

//清空单链表,链表仍存在,只剩头节点
public void clearList(){
     head.next=null;
}

获取单链表表长

//获取单链表的表长
public int getLength(){
      return length;
}

获取第i个元素值

//取第i个元素的值
public Integer getElem(int i){
      //先判断i是否合法
     if (i>=1 && i<=getLength()){
          LinkListNode p = head;
          while (i>0){
               p = p.next;
               i--;
          }
               return p.data;
     }
     throw new RuntimeException("输入不合法");
}

按值查找获取元素第一次出现的位置

//按值查找,获取指定元素第一次出现的位置
 public int getLocal(Integer target){
      LinkListNode p = head.next;
      while (p != null){
          if (p.data == target){
               return p.data;
          }else {
               p = p.next;
          }
      }
      throw new RuntimeException("元素不存在");
 }

在第i个节点前插入新的节点

//在第i个节点前插入新的节点
public void insertElem(int i ,Integer ele){
     LinkListNode temp ;
     LinkListNode p = head;
     if (i>=1 && i<=getLength()){
          //先找到第i-1个节点
          while (--i>0){
               p = p.next;
          }
     }else {
          throw new RuntimeException("输入不合法");
     }
     temp = p.next;
     //创建新节点,并插入
     p.next = new LinkListNode(ele,temp);
     length++;
}

删除第i个节点

//删除第i个节点
public void deleteElem(int i ){
     LinkListNode temp ;
     LinkListNode p = head;
     if (i>=1 && i<=getLength()){
          //先找到第i-1个节点
          while (--i>0){
               p = p.next;
          }
     }else {
          throw new RuntimeException("输入不合法");
     }
     //删除节点
     p.next = p.next.next;
     length--;

}

头插法和尾插法建立链表

/**
 * 单链表的建立 头插法
 * @param ele 插入的链表,以数组的形式作为输入
 */
public void createList_H(Integer[] ele){
     LinkListNode temp = head;
     for (int i = ele.length-1; i >= 0 ; i--) {
          head.next = new LinkListNode(ele[i],temp);
          temp = head.next;
          length++;
     }
}

/**
 * 单链表的建立 尾插法
 * @param ele 插入的链表,以数组的形式作为输入
 */
public void createList_R(Integer[] ele){
     LinkListNode last = head;//尾指针指向头节点
     for (int i = 0; i < ele.length ; i++) {
         last.next =  new LinkListNode(ele[i],null);
         last = last.next;
         length++;
     }

}
//遍历链表并输出
public void traverseList(){
     LinkListNode p = head.next;
     for (int i = 0; i < getLength(); i++) {
          System.out.print(p.data+"\t");
          p = p.next;
     }
}

测试

package linkedlist;

import java.sql.Array;

public class SingleLinkListTest {
    public static void main(String[] args) {
        SingleLinkList list = new SingleLinkList();
        Integer[] arr = {1,2,3,4,5,6,7,8,9};
        list.createList_R(arr);
        System.out.println(list.getLength());
        System.out.println(list.getElem(3));
        System.out.println(list.getLocal(3));
        list.insertElem(3,0);
        list.deleteElem(10);
        list.traverseList();
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值