数据结构:线性表及Java实现

数据结构:线性表及Java实现

声明:概念方面不清楚的读者,可以通过书籍或者网络搜索相关名词解释,本文重点关注在代码实现层面
一 序言
本文内容:先讲解线性表基础知识,然后使用数组和链表实现线性表。

二 线性表基本知识
1 线性表:由零个多个数据元素组成的有序序列。

2 线性表中每个节点最多只有一个前驱节点和后继节点,头节点没有前驱节点,尾节点没有后继节点。
线性表
图1 线性表结构

如图1所示,节点个数为n,节点a1是头节点,它没有前驱节点,它的后继节点是a2,an为尾节点,它没有后继节点,它的前驱节点为a(n-1),a2的前驱节点为a1,后继节点为a3(图中未画出)。从图1可以看出,线性表各节点的逻辑结构直观上可以看成各个节点相连接,形成一条链。

注意:图1中的箭头并不表示指针,笔者只是想表达它们的存储关系是链式的

3 线性表存储结构
线性表在内存中存储结构包含两种形式:
a) 顺序存储,存储单元连续,前驱节点和后继节点所存储的内存是紧靠着的,如图2所示
b) 链式存储,存储单元不一定连续,前驱节点和后继节点所存储的内存非紧靠着的,此时需要通过一个指针(Java中称为引用)指向来串接,如图3所示
线性表-数组
图2 内存连续
线性表-链式
图3 内存不连续

从图2可以看出,对于内存连续的线性表,通过前驱节点向后移动一个节点(由当前节点类型所占空间大小决定)即可找到其后继节点;
从图2可以看出,对于内存不连续的线性表,需要通过一个辅助手段找到节点的后继节点,即添加一个next指针(Java中成为对应引用,类似指针的概念),并通过该next指针找到其后继节点,灰色块表示,它们可能是内存连续的或者相隔若干个节点;

4 抽象数据类型
抽象数据类型是对同种类型数据及对该种类型数据所做操作的抽象。
数据类型包括:原子数据类型和结构数据类型。原子类型不可分割,结构类型由结构类型和原子类型组合而成,它不是最小数据单元。
数据操作包括:初始化操作,清空操作,增加数据,删除数据,修改数据,查询数据,判断线性表是否为空和判断线性表大小等操作。

三 数组实现线性表

package com.datastruct.linear;

/**
 * Description: 【数据结构-线性表】数组实现方案
 *
 * @author guodong
 * @date 2020/3/28 22:41
 */
public class ArrayLinear {

    /**
     * 定义线性表大小,不考虑扩容的情况
     */
    private static int ARRAY_LEN = 10;
    /**
     * 记录线性表当前大小
     */
    private static int CURRENT_SIZE = 0;
    /**
     * 初始化数组,申请连续的空间
     */
    private static int[] arrayList;

    public static void main(String[] args) {
        createList();
        delete(0);
        insert(0, 10);
        printValue(arrayList);
        insert(2, 12);
        printValue(arrayList);
        insert(1, 11);
        printValue(arrayList);
        int delete = delete(1);
        System.out.println("【删除】结果:" + delete);
        printValue(arrayList);
        int update = update(0, 100);
        System.out.println("【更新】结果:" + update);
        printValue(arrayList);
        int get = get(11);
        System.out.println("【查询】结果:" + get);
        get = get(8);
        System.out.println("【查询】结果:" + get);
    }

    /**
     * 初始化线性表
     */
    private static void createList() {
        arrayList = new int[ARRAY_LEN];
    }

    /**
     * 判断线性表是否为空
     */
    private static boolean isEmpty() {
        return CURRENT_SIZE == 0;
    }

    /**
     * 判断是否达到容量上限
     */
    private static boolean isFull() {
        return CURRENT_SIZE == ARRAY_LEN - 1;
    }

    /**
     * 添加数值到指定位置,从指定位置开始,
     * 将其后的数据往后移动一位,然后将数据放到指定位置
     *
     * @param local 指定位置
     * @param value 数值
     * @return void
     */
    private static void insert(int local, int value) {
    	if (isFull()) {
            System.out.println("线性表容量达到上限");
            return;
        }
        if (local > CURRENT_SIZE) {
            throw new ArrayIndexOutOfBoundsException();
        }
        if (local == CURRENT_SIZE) {
            arrayList[local] = value;
            CURRENT_SIZE++;
            return;
        }
        for (int l = CURRENT_SIZE - 1; l > local; l--) {
            arrayList[l + 1] = arrayList[l];
        }
        arrayList[local] = value;
    }

    /**
     * 删除指定位置的值,将其后面的数据往前移动一位,返回原来的值
     *
     * @param local 位置
     * @return int
     */
    private static int delete(int local) {
    	if (isEmpty()) {
            System.out.println("线性表为空");
            return -1;
        }
        if (local < 0 || local > CURRENT_SIZE) {
            throw new ArrayIndexOutOfBoundsException();
        }
        // 缓存删除前的内容
        int oldValue = arrayList[local];
        // 删除元素
        arrayList[local] = 0;
        // 将其后面数据往前移动
        for (int l = local; l < CURRENT_SIZE; l++) {
            arrayList[local] = arrayList[local + 1];
        }
        return oldValue;
    }

    /**
     * 修改指定位置的数值,并返回修改前的值
     *
     * @param local 位置
     * @param value 修改后的值
     * @return int
     */
    private static int update(int local, int value) {
    	if (isEmpty()) {
            System.out.println("线性表为空");
            return -1;
        }
        if (local < 0 || local > ARRAY_LEN) {
            throw new ArrayIndexOutOfBoundsException();
        }
        int oldValue = arrayList[local];
        arrayList[local] = value;
        return oldValue;
    }

    /**
     * 获取指定位置数值
     *
     * @param local 位置
     * @return int
     */
    private static int get(int local) {
    	if (isEmpty()) {
            System.out.println("线性表为空");
            return -1;
        }
        if (local < 0 || local > ARRAY_LEN) {
            throw new ArrayIndexOutOfBoundsException();
        }
        return arrayList[local];
    }

    /**
     * 数组打印
     *
     * @param array 线性表
     * @return void
     */
    private static void printValue(int[] array) {
        for (int index = 0; index < array.length; index++) {
            System.out.print("array[" + index + "]= " + array[index] + " ");
        }
        System.out.println("");
    }
}

四 链表实现线性表

package com.datastruct.linear;

/**
 * Description: 【数据结构-线性表】链表实现方案
 *
 * @author guodong
 * @date 2020/3/28 22:46
 */
public class LinkedLinear {

    /**
     * 头节点,不存储任何数据,标志链表起始位置
     */
    private static Node root;

    public static void main(String[] args) {
        createList();
        printValue(root);
        insert(1, new Node(11));
        printValue(root);
        insert(2, new Node(22));
        printValue(root);
        Node delete = delete(1);
        System.out.println("【删除】结果:" + (delete == null ? "null" : delete.getValue()));
        printValue(root);
        Node update = update(1, new Node(122));
        System.out.println("【更新】结果:" + (update == null ? "null" : update.getValue()));
        printValue(root);
        Node node = get(1);
        System.out.println("【查询】结果:" + (node == null ? "null" : node.getValue()));
    }

    /**
     * 初始化链表
     */
    private static void createList() {
        root = new Node(0);
    }

    /**
     * 判断线性表是否为空
     */
    private static boolean isEmpty() {
        return root == null;
    }

    /**
     * 插入节点
     *
     * @param local 位置
     * @param node  数据节点
     * @return void
     */
    private static void insert(int local, Node node) {
        if (isEmpty()) {
            createList();
        }
        Node tmp = root;
        int size = 0;
        while (tmp.getNext() != null) {
            size++;
            if (size == local) {
                tmp.setNext(node);
                return;
            }
            tmp = tmp.getNext();
        }
        tmp.setNext(node);
    }

    /**
     * 删除指定位置元素
     *
     * @param local 位置
     * @return com.datastruct.linear.Node
     */
    private static Node delete(int local) {
        if (isEmpty()) {
            System.out.println("线性表为空");
            return null;
        }
        Node tmp = root;
        int size = 0;
        while (tmp != null) {
            if (size++ == local - 1) {
                Node next = tmp.getNext();
                if (next != null) {
                    tmp.setNext(next.getNext());
                } else {
                    System.out.println("没有指定元素");
                }
                return next;
            }
            tmp = tmp.getNext();
        }
        System.out.println("没有指定元素");
        return null;
    }

    /**
     * 更新指定位置元素
     *
     * @param local 位置
     * @param node  更改后的内容
     * @return com.datastruct.linear.Node
     */
    private static Node update(int local, Node node) {
        if (isEmpty()) {
            System.out.println("线性表为空");
            return null;
        }
        Node tmp = root;
        int size = 0;
        while (tmp != null) {
            if (size++ == local) {
                Node oldValue = tmp;
                tmp.setValue(node.getValue());
                return oldValue;
            }
            tmp = tmp.getNext();
        }
        System.out.println("没有指定元素");
        return null;
    }

    /**
     * 查询节点
     *
     * @param local 指定位置
     * @return com.datastruct.linear.Node
     */
    private static Node get(int local) {
        if (isEmpty()) {
            System.out.println("线性表为空");
            return null;
        }
        Node tmp = root;
        int size = 0;
        while (tmp != null) {
            if (size++ == local) {
                return tmp;
            }
            tmp = tmp.getNext();
        }
        System.out.println("没有指定元素");
        return null;
    }

    /**
     * 数组打印
     *
     * @param root 线性表
     * @return void
     */
    private static void printValue(Node root) {
        int len = 0;
        while (root != null) {
            System.out.print("node[" + len++ + "]= " + root.getValue() + " ");
            root = root.getNext();
        }
        System.out.println("");
    }
}

class Node {
    private int value;
    private Node next;

    public Node(int value) {
        this.value = value;
    }

    public void setValue(int value) {
        this.value = value;
    }

    public int getValue() {
        return value;
    }

    public void setNext(Node next) {
        this.next = next;
    }

    public Node getNext() {
        return next;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值