当前位置: 首页 > news >正文

线性表及其算法(java实现)

线性表

线性表是最简单和最常用的一种数据结构,它是有n个数据元素(节点)组成的有限序列。其中,数据元素的个数n为表的长度,当n为零时成为空表,非空的线性表通常记为:

(a1,a2,… ,ai-1,ai, ai+1,…,an)

一. 线性表的顺序存储及算法

线性表的顺序存储指的是将线性表的数据元素按其逻辑次序依次存入一组地址连续的存储单元里,用这种方法存储的线性表称为顺序表。

1.顺序表的结构定义

public class SeqList {
    
    /* 初始空间为10 */
    private static final int LIST_SIZE = 10;
    
    /* 数组data用来存放元素 */
    private int[] data;
    
    /* 当前表长,实际存储元素的个数 */
    private int length;
    
}

2.插入运算

顺序表的插入运算是指在线性表的第i-1个元素和第i个元素之间插入一个新元素。由于顺序表逻辑上相邻的元素在物理结构上也相邻,其物理存储关系也要发生相应的变化。除非i=n+1,否则必须将原顺序表的第i个元素开始的所有元素分别向后移动1个位置。

/**
 * 在顺序表list中第i个位置之前插入一个新元素node
 * @param list 顺序表
 * @param i 插入位置
 * @param node 新元素
 */
public void insertList(SeqList list, int i, int node) {
        
    if (i < 1 || i > list.length + 1) {
        System.out.println("position error");
        return;
    }
        
    if (list.length >= LIST_SIZE) {
        System.out.println("overflow");
        return;
    }
        
    for (int j = list.length - 1; j >= i - 1; j --) {
        /* 从最后一个元素开始逐一后移 */
        list.data[j+1] = list.data[j];
    }
    /* 插入新元素 */
    list.data[i-1] = node;
    /* 表长加1 */
    list.length ++;
        
}

3.删除运算

顺序表的删除运算指的是将表中第i个元素删除,与插入运算相反,插入是向后移动元素,删除运算则是向前移动元素。

/**
 * 在顺序表list中删除第i个元素,并返回被删除的元素
 * @param list 顺序表
 * @param i 元素位置
 * @return node
 */
public int deleteList(SeqList list, int i) {

    int node = 0;

    if (i < 0 || i > list.length) {
        System.out.println("position error");
        return node;
    }

    node = list.data[i-1];
    for (int j = i; j < list.length; j ++) {
        /* 元素前移 */
        list.data[j-1] = list.data[j];
    }

    list.length --;

    return node;

}

4.顺序表逆置

先以表长的一半为循环控制次数,将表中最后一个元素同顺序顺数第一个元素交换,将倒数第二个元素同顺数第二个元素交换,以此类推,直至交换完为止。

/**
 * 顺序表逆置
 * @param list 原始顺序表
 * @return 逆置后的顺序表
 */
public SeqList converts(SeqList list) {
        
    int node;
    int length = list.length/2;
    for (int i = 0; i < length; i ++) {
        /* 对称交换元素 */
        int j = list.length - 1 - i;
        node = list.data[i];
        list.data[i] = list.data[j];
        list.data[j] = node;
    }
    return list;
        
}

二. 线性表的链式存储及算法

链式存储结构存储线性表数据元素的存储空间可能是连续的,也可能是不连续的,因而链表的节点是不可以随机存取的,链式存粗是最常见的存储方式之一。

在使用链式存储结构表示每个数据元素时,除了存储元素本身的信息外,还需要一个存储指示后继元素存储位置的地址,利用这种存储方式表示的线性表称为链表。

5.单链表的结构定义

public class LinkList {

    /* 数据域 */
    private char data;

    /* 后继元素 */
    private LinkList next;

}

6.头插法建表算法

头插法是从一个空表开始,重复读入数据,生成新节点,将读入的数据存放到新节点的数据域中,然后将新节点插入到当前链表的表头上,直到结束为止。

/**
 * 头插法创建表
 * @param chars 字符数组
 * @return 单链表
 */
public LinkList createListF(char[] chars) {

    LinkList node;
    LinkList head = null;

    for (char ch : chars) {
        /* 申请新节点 */
        node = new LinkList();
        node.data = ch;

        /* 指向后继节点 */
        node.next = head;
        head = node;
    }

    /* 返回头节点 */
    return head;

}

7.尾插法建表算法

头插法建表中节点的次序和输入时的顺序相反,若需要和输入次序一致,则可使用尾插法。

/**
 * 尾插法建表
 * @param chars 字符数组
 * @return 单链表
 */
public LinkList createListR(char[] chars) {

    LinkList node;
    LinkList head = null;
    LinkList rear = null;

    for (char ch : chars) {
        node = new LinkList();
        node.data = ch;

        if (head == null) {
            /* 新节点为头节点 */
            head = node;
        } else {
            /* 上一个节点指向新节点 */
            rear.next = node;
        }
        /* 表尾指向新的节点 */
        rear = node;
    }

    /* 返回头节点 */
    return head;

}

相关文章:

  • 分布式商业萌芽,银行迎来发展新机遇
  • 小结
  • 信修修 | 如何一眼辨别显示器好坏?电脑选机必看!
  • thinkphp5.1 easywechat4 微信第三方开放平台
  • java 实现每次从list中取5000条数据放入新list
  • BZOJ5018[Snoi2017]英雄联盟——DP
  • configparser , subprocess , xlrd , xlwt , xml , 面向对象
  • 开发基于以太坊智能合约的DApp
  • 面向对象学习小结
  • 代码生成器技术乱弹九,代码变变变,代码生成器之度量
  • Format 函数,%f,%d,%x,%p。 浮点型小数点位取值
  • axios一些书签
  • linux就该这么学 第一天学习笔记
  • 递归函数中,return的误区
  • vagrant 本地添加box 支持带版本号
  • [数据结构]链表的实现在PHP中
  • 【Under-the-hood-ReactJS-Part0】React源码解读
  • Angular 响应式表单 基础例子
  • IIS 10 PHP CGI 设置 PHP_INI_SCAN_DIR
  • JavaScript对象详解
  • JavaScript服务器推送技术之 WebSocket
  • TCP拥塞控制
  • vue从创建到完整的饿了么(11)组件的使用(svg图标及watch的简单使用)
  • 开发基于以太坊智能合约的DApp
  • 浅析微信支付:申请退款、退款回调接口、查询退款
  • 全栈开发——Linux
  • 如何将自己的网站分享到QQ空间,微信,微博等等
  • 探索 JS 中的模块化
  • 小程序上传图片到七牛云(支持多张上传,预览,删除)
  • 400多位云计算专家和开发者,加入了同一个组织 ...
  • 从如何停掉 Promise 链说起
  • 回归生活:清理微信公众号
  • 曜石科技宣布获得千万级天使轮投资,全方面布局电竞产业链 ...
  • #etcd#安装时出错
  • #ifdef 的技巧用法
  • $con= MySQL有关填空题_2015年计算机二级考试《MySQL》提高练习题(10)
  • (2)STM32单片机上位机
  • (4)Elastix图像配准:3D图像
  • (C语言)fread与fwrite详解
  • (M)unity2D敌人的创建、人物属性设置,遇敌掉血
  • (pojstep1.1.1)poj 1298(直叙式模拟)
  • (翻译)terry crowley: 写给程序员
  • (三)elasticsearch 源码之启动流程分析
  • (学习日记)2024.01.19
  • (学习日记)2024.03.25:UCOSIII第二十二节:系统启动流程详解
  • (原創) 如何使用ISO C++讀寫BMP圖檔? (C/C++) (Image Processing)
  • (转)LINQ之路
  • (转载)Linux 多线程条件变量同步
  • (最全解法)输入一个整数,输出该数二进制表示中1的个数。
  • (最完美)小米手机6X的Usb调试模式在哪里打开的流程
  • *++p:p先自+,然后*p,最终为3 ++*p:先*p,即arr[0]=1,然后再++,最终为2 *p++:值为arr[0],即1,该语句执行完毕后,p指向arr[1]
  • .NET Core 中插件式开发实现
  • .NET 设计一套高性能的弱事件机制
  • .NET/C# 编译期能确定的字符串会在字符串暂存池中不会被 GC 垃圾回收掉
  • .NET/C# 如何获取当前进程的 CPU 和内存占用?如何获取全局 CPU 和内存占用?