Java实现顺序表结构

来源:互联网 发布:小米手机怎么转移数据 编辑:程序博客网 时间:2024/04/30 02:04

什么是顺序表

顺序表(Sequential List)就是按照顺序存储方式存储的线性表,该线性表的节点按照逻辑次序存放在计算机的一组连续的存储单元中。

顺序表数据结构代码:

/** * 节点 */public class Data {    // 节点的关键字    private String key;    private String name;    private int age;    public String getKey() {        return key;    }    public void setKey(String key) {        this.key = key;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public int getAge() {        return age;    }    public void setAge(int age) {        this.age = age;    }}/** * 顺序表结构 */public class Type {    // 定义顺序表的最大长度    public static final int MAX_LEN = 100;    // 保存顺序表的结构数组,用于存放各个数据节点    private Data[] listData = new Data[MAX_LEN + 1];    // 顺序表已存节点的数量    private int listLen;}

由于Java语言中数组都是从下标0开始的。在这里,为了讲述和理解方便,从下标1开始记录数据节点,下标0的位置不使用。

初始化顺序表

在使用顺序表之前,首先要创建一个空得顺序表,即初始化顺序表。这里,在程序中只需要设置顺序表的节点数量listLen为0即可。这样,后面需要添加的数据元素将从顺序表中的第一个位置存储。代码示例如下:

    /**     * 初始化顺序表     */    public void init() {        // 初始化为空表        this.listLen = 0;    }

需要注意的是,这里并没有清空一个顺序表。只需要将节点数量listLen设置为0即可,这样如果顺序表中原来已有数据,也会被覆盖,并不影响操作,反而提高了处理的速度。

计算顺序表长度

计算顺序表长度即计算线性表L中结点的个数。由于在Type中使用listLen来表示顺序表的结点数量,因此程序只需要返回该值就可以了。代码如下:

    /**     * 获取顺序表的长度     */    public int length() {        return this.listLen;    }

插入结点

插入结点就是在线性表L的第i个位置插入一个新的节点,使得其后的节点编号依次加1.这时,插入一个新结点之后,线性表L的长度将变为n+1。插入节点操作的难点在与随后的每个结点数据都要进行移动,计算量比较大。代码如下:

/**     * 插入节点     * @param n 插入结点位置     * @param data 插入数据元素     */    public int insert(int n, Data data) {        int i;        if (listLen >= MAX_LEN) { // 顺序表结点数量超过最大数量            System.out.println("顺序表已满,不能插入节点!");            return 0; // 返回0表示插入不成功        }        if (n < 1 || n > listLen - 1) {            System.out.println("插入元素序号越界,不能插入元素!");            return 0;        }        for (i = listLen; i >= n; i--) { // 将顺序表中的数据向后移动            listData[i+1] = listData[i];        }        listData[n] = data; // 插入结点        listLen++;  // 顺序表结点数量增加1        return 1; // 成功插入,返回1    }

注意for循环的条件为i >= n;即只移动插入点之后的数据,这样插入点就会空出来,之后将data插入到此结点之上即可。

追加节点

追加节点并不是一个基本的数据结构运算,其可以看做插入结点的一种特殊形式,相当于在顺序表的末尾增加一个数据节点。代码如下:

/** * 增加元素到顺序表尾部  */public int add(Data data) {    if(listLen >= MAX_LEN) { // 顺序表已满        System.out.println("顺序表已满,不能再添加节点了!");        return 0;    }    listData[++listLen] = data;    return 1;}

删除节点

删除结点即删除线性表L中的第i个结点,使得其后的所有结点编号依次减1.删除一个结点之后,线性表L的长度将变为n-1.代码如下:

/** * 删除n结点的元素 */public int delete(int n) {    int i;    if (n < 1 || n > listLen + 1) { // 删除结点序号不正确        System.out.println("删除结点序号错误,不能删除结点!");        return 0; // 删除不成功,返回0    }    for (i = n; i < listLen; i++) { // 将顺序表中的数据向前移动        listData[i] = listData[i + 1];      }    listLen--;  // 顺序表元素数量减1    return 1;   // 成功删除,返回1}

查找结点

查找结点即在线性表L中查找值为x的结点,并返回该结点在线性表L中的位置。如果在线性表中没有找到值为x的结点,则返回一个错误标志。根据值x类型的不同,查找结点可以分为按照序号查找结点和按照关键字查找结点两种方法。

1.按照序号查找结点

对于一个顺序表,序号就是数据元素在数组中的位置,也就是数组的下标标号。按照序号查找结点是顺序表查找结点最常用的方法,这是因为顺序表的存储本身就是一个数组。代码如下:

/** * 按照序号查找结点 */public Data findByNum(int n) { // 根据序号返回数据元素    if (n < 1 || n > listLen + 1) { // 元素序号不正确        System.out.println("结点序号错误,不能返回结点!");        return null; // 不成功,则返回0    }    return listData[n];}

2.按照关键字查找结点

另一个比较常用的方法是按照关键字查找结点。这里,关键字可以是数据元素结构中的任意一项。以key关键字为例介绍,代码如下:

/** * 按照关键字查找结点 */public int findByCont(String key) {     int i;    for (i = 1; i < listLen; i++) {         if (listData[i].getKey().equals(key)) { // 如果找到所需结点            return i;   // 返回结点序号        }    }    return 0; // 搜索整个表后仍没有找到,则返回0}

显示所有结点

显示所有结点数据并不是一个数据结构基本的运算,因为其可以简单地逐个引用结点来实现。代码如下:

    /**     * 显示所有结点     */    public int all() {        int i;        for(i =1;i<=listLen;i++) {            String format = String.format("(%s,%s,%d)\n",listData[i].getKey(),listData[i].getName(),listData[i].getAge());            System.out.println(format);        }        return 0;    }

顺序表操作实例

学习了前面的顺序表的基础运算之后,便可以轻松地完成对顺序表的各种操作。下面给出一个完整的例子,来演示顺序表的创建、插入结点、查找结点等操作、代码如下:

import java.text.Format;/** * 顺序表结构 */public class Type {    // 定义顺序表的最大长度    public static final int MAX_LEN = 100;    // 保存顺序表的结构数组,用于存放各个数据节点    private Data[] listData = new Data[MAX_LEN + 1];    // 顺序表已存节点的数量    private int listLen;    /**     * 初始化顺序表     */    public void init() {        // 初始化为空表        this.listLen = 0;    }    /**     * 获取顺序表的长度     */    public int length() {        return this.listLen;    }    /**     * 插入节点     *      * @param n     *            插入结点位置     * @param data     *            插入数据元素     */    public int insert(int n, Data data) {        int i;        if (listLen >= MAX_LEN) { // 顺序表结点数量超过最大数量            System.out.println("顺序表已满,不能插入节点!");            return 0; // 返回0表示插入不成功        }        if (n < 1 || n > listLen - 1) {            System.out.println("插入元素序号越界,不能插入元素!");            return 0;        }        for (i = listLen; i >= n; i--) { // 将顺序表中的数据向后移动            listData[i + 1] = listData[i];        }        listData[n] = data; // 插入结点        listLen++; // 顺序表结点数量增加1        return 1; // 成功插入,返回1    }    /**     * 增加元素到顺序表尾部     */    public int add(Data data) {        if (listLen >= MAX_LEN) { // 顺序表已满            System.out.println("顺序表已满,不能再添加节点了!");            return 0;        }        listData[++listLen] = data; // 追加结点操作,并更新结点数量listLen。        return 1;    }    /**     * 删除n结点的元素     */    public int delete(int n) {        int i;        if (n < 1 || n > listLen + 1) { // 删除结点序号不正确            System.out.println("删除结点序号错误,不能删除结点!");            return 0; // 删除不成功,返回0        }        for (i = n; i < listLen; i++) { // 将顺序表中的数据向前移动            listData[i] = listData[i + 1];        }        listLen--; // 更新结点数量,顺序表元素数量减1        return 1; // 成功删除,返回1    }    /**     * 按照序号查找结点     */    public Data findByNum(int n) { // 根据序号返回数据元素        if (n < 1 || n > listLen + 1) { // 元素序号不正确            System.out.println("结点序号错误,不能返回结点!");            return null; // 不成功,则返回0        }        return listData[n];    }    /**     * 按照关键字查找结点     */    public int findByCont(String key) {         int i;        for (i = 1; i < listLen; i++) {             if (listData[i].getKey().equals(key)) { // 如果找到所需结点                return i;   // 返回结点序号            }        }        return 0; // 搜索整个表后仍没有找到,则返回0    }    /**     * 显示所有结点     */    public int all() {        int i;        for(i =1;i<=listLen;i++) {            String format = String.format("(%s,%s,%d)",listData[i].getKey(),listData[i].getName(),listData[i].getAge());            System.out.println(format);        }        return 0;    }}

测试方法代码如下:

public static void main(String[] args) {        int i;        Type type = new Type(); // 定义顺表变量        Data pdata; // 定义结点保存引用变量        String key; // 保存关键字        System.out.println("顺序表操作演示!");        type.init(); // 初始化顺序表        System.out.println("初始化顺序表完成");        Scanner input = new Scanner(System.in);        do { // 循环增加结点数据            System.out.print("输入添加的结点(学号  姓名  年龄):");            Data data = new Data();            data.setKey(input.next());            data.setName(input.next());            data.setAge(input.nextInt());            if (data.getAge() != 0) { // 若年龄不为0                if (type.add(data) == 0) { // 若添加结点失败                    break; // 退出死循环                }            } else { // 若年龄为0                break; // 退出死循环            }        } while (true);        System.out.println("顺序表中的结点顺序为:");        type.all(); // 显示所有结点数据        System.out.print("要取出结点的序号:");        i = input.nextInt(); // 输入结点占点序号        pdata = type.findByNum(i); // 按序号查找结点        if (pdata != null) { // 若返回的结点引用不为null            String format = String.format("第%d个结点为:(%s,%s,%d)\n", i,                    pdata.getKey(), pdata.getName(), pdata.getAge());            System.out.println(format);        }        System.out.print("要查找结点的关键字:");        key = input.next(); // 输入关键字        i = type.findByCont(key); // 按关键字查找,返回结点序号        pdata = type.findByNum(i); // 按序号查询,返回结点引用        if (pdata != null) { // 若返回的结点引用不为null            String format = String.format("第%d个结点为:(%s,%s,%d)\n", i,                    pdata.getKey(), pdata.getName(), pdata.getAge());            System.out.println(format);        }    }

执行结果如下:

顺序表操作演示!初始化顺序表完成输入添加的结点(学号  姓名  年龄):001 aa 21输入添加的结点(学号  姓名  年龄):002 bb 22输入添加的结点(学号  姓名  年龄):003 cc 23输入添加的结点(学号  姓名  年龄):004 dd 24输入添加的结点(学号  姓名  年龄):0 0 0顺序表中的结点顺序为:(001,aa,21)(002,bb,22)(003,cc,23)(004,dd,24)要取出结点的序号:2第2个结点为:(002,bb,22)要查找结点的关键字:003第3个结点为:(003,cc,23)

顺序表结构的缺点

1.在插入或者删除结点时,往往需要移动大量的数据。
2.如果表比较大,有事比较难分配足够的连续内存空间,往往导致内存分配失败,而无法存储。

0 0
原创粉丝点击