数据结构Java实现01----线性表与顺序表

一、线性结构

如果一个数据元素序列满足:

(1)除第一个和最后一个数据元素外,每个数据元素只有一个前驱数据元素和一个后继数据元素;

(2)第一个数据元素没有前驱数据元素;

(3)最后一个数据元素没有后继数据元素。

则称这样的数据结构为线性结构。

二、线性表抽象数据类型:

1、线性表抽象数据类型的概念:

线性表抽象数据类型主要包括两个方面:既数据集合和该数据集合上的操作集合。

数据集合:

  可以表示为a0,a1,a2,...an-1,每个数据元素的数据类型可以是任意的类型。

操作集合包括如下:

1.插入
2.查找
3.删除 

4.判断是否为空
5.求元素个数

2、设计线性表抽象数据类型的Java接口:

代码如下:

 1 package com.myutil.list;
 2
 3 public interface List {
 4     //插入元素
 5     public void insert(int index,Object obj) throws Exception;
 6     //重载插入方法
 7     public void insert(Object obj) throws Exception;
 8     //获取指定位置的元素
 9     public Object get(int index) throws Exception;
10     //删除元素
11     public void delete(int index) throws Exception;
12     //获得线性表长度
13     public int size();
14     //判断线性表是否为空
15     public boolean isEmpty();
16 }

然后我们让子类去实现这个接口就行了。

三、顺序表:(在物理存储结构上连续,大小固定)

1、顺序表的概念:

计算机有两种基本的存储结构(物理存储结构):顺序结构、离散结构。使用顺序结构实现的线性表称为顺序表。如下图所示:

Java内存中,栈内存和堆内存占了很大一部分空间:栈内存的存储是顺序结构,堆内存的存储是离散结构。

2、设计顺序表类:

我们在上面第二段的List接口基础之上,设计一个顺序表:

(1)List.java:(线性表,和上面的第二段中代码一样)

 1 package com.myutil.list;
 2
 3 public interface List {
 4     //插入元素
 5     public void insert(int index,Object obj) throws Exception;
 6     //重载插入方法
 7     public void insert(Object obj) throws Exception;
 8     //获取指定位置的元素
 9     public Object get(int index) throws Exception;
10     //删除元素
11     public void delete(int index) throws Exception;
12     //获得线性表长度
13     public int size();
14     //判断线性表是否为空
15     public boolean isEmpty();
16 }

(2)SequentailList.java:(核心代码)

 1 package com.myutil.list;
 2
 3 //SequentialList:顺序表
 4
 5 public class SequentialList implements List {
 6
 7     //默认的顺序表的最大长度
 8     private final int defaultSize = 10;
 9     //最大长度
10     private int maxSize;
11     //当前长度
12     private int size;
13     //对象数组
14     Object[] listArray;
15
16
17     public SequentialList() {
18         init(defaultSize);
19     }
20
21     public SequentialList(int size) {
22         init(size);
23     }
24
25     //顺序表的初始化方法(建立顺序表)
26     private void init(int size) {
27         maxSize = size;
28         this.size = 0;
29         listArray = new Object[size];
30     }
31
32     @Override
33     public void insert(int index, Object obj) throws Exception {
34         //如果当前线性表已满,那就不允许插入数据
35         if (size == maxSize) {
36             throw new Exception("顺序表已满,无法插入!");
37         }
38         //插入位置编号是否合法
39         if (index < 0 || index > size) {
40             throw new Exception("参数错误!");
41         }
42         //移动元素
43         for (int j = size - 1; j >= index; j--) {
44             listArray[j + 1] = listArray[j];
45         }
46
47         listArray[index] = obj;  //不管当前线性表的size是否为零,这句话都能正常执行,即都能正常插入
48         size++;
49     }
50
51     @Override
52     public void insert(Object obj) throws Exception {
53         insert(size, obj);
54     }
55
56     @Override
57     public Object get(int index) throws Exception {
58         if (index < 0 || index >= size) {
59             throw new Exception("参数错误!");
60         }
61         return listArray[index];
62     }
63
64     @Override
65     public void delete(int index) throws Exception {
66         if (isEmpty()) {
67             throw new Exception("顺序表为空,无法删除!");
68         }
69         if (index < 0 || index > size - 1) {
70             throw new Exception("参数错误!");
71         }
72         //移动元素
73         for (int j = index; j < size - 1; j++) {
74             listArray[j] = listArray[j + 1];
75         }
76         size--;
77     }
78
79     @Override
80     public int size() {
81         return size;
82     }
83
84
85     @Override
86     public boolean isEmpty() {
87         return size == 0;
88     }
89 }

我们来看一下第54行的插入操作insert()方法:如果需要在index位置插入一个数据,那么index后面的元素就要整体往后移动一位。这里面需要特别注意的是:

插入操作:移动元素时,要从后往前操作,不能从前往后操作,不然元素会被覆盖的

删除元素:移动元素时,要从前往后操作。

(3)测试类:

 1 package com.myutil.list;
 2
 3 public class Test {
 4
 5     public static void main(String[] args) {
 6
 7         SequentialList list = new SequentialList(20);
 8
 9         try {
10             list.insert(0, 100);
11             list.insert(0, 50);
12             list.insert(1, 20);
13             list.insert(60);
14
15             for (int i = 0; i < list.size(); i++) {
16                 System.out.println("第" + i + "个数为" + list.get(i));
17             }
18
19         } catch (Exception e) {
20             e.printStackTrace();
21         }
22     }
23 }

我们要注意插入的规则是什么,不然会觉得这个顺序表打印输出的顺序很奇怪。

运行效果:

第0个数为50
第1个数为20
第2个数为100
第3个数为60

3、顺序表效率分析:

  • 顺序表插入和删除一个元素的时间复杂度为O(n)。
  • 顺序表支持随机访问,顺序表读取一个元素的时间复杂度为O(1)。因为我们是可以通过下标直接访问的,所以时间复杂度是固定的,和问题规模无关。

4、顺序表的优缺点:

  • 顺序表的优点是:支持随机访问;空间利用率高(连续分配,不存在空间浪费)。
  • 顺序表的缺点是:大小固定(一开始就要固定顺序表的最大长度)插入和删除元素需要移动大量的数据。

5、顺序表的应用:

设计一个顺序表,可以保存100个学生的资料,保存以下三个学生的资料,并打印输出。

代码实现:

(1)List.java:

  和上面的代码保持不变

(2)SequentailList.java:

  和上面的代码保持不变

(3)Students.java:学生类

 1 package com.myutil.list.use;
 2
 3 //学生类
 4 public class Students {
 5
 6   private String id;// 学号
 7   private String name;// 姓名
 8   private String gender;// 性别
 9   private int age;// 年龄
10
11   public Students() {
12
13   }
14
15   public Students(String sid, String name, String gender, int age) {
16       this.id = sid;
17       this.name = name;
18       this.gender = gender;
19       this.age = age;
20   }
21
22
23   public String getId() {
24       return id;
25   }
26
27   public void setId(String id) {
28       this.id = id;
29   }
30
31   public String getName() {
32       return name;
33   }
34
35   public void setName(String name) {
36       this.name = name;
37   }
38
39   public String getGender() {
40       return gender;
41   }
42
43   public void setGender(String gender) {
44       this.gender = gender;
45   }
46
47   public int getAge() {
48       return age;
49   }
50
51   public void setAge(int age) {
52       this.age = age;
53   }
54
55   public String toString() {
56       return "学号:" + this.getId() + " 姓名:" + this.getName() + " 性别:" + this.getGender() + " 年龄:" + this.getAge();
57   }
58
59 }

(4)Test.java:

 1 package com.myutil.list.use;
 2
 3 import com.myutil.list.SequentialList;
 4
 5 public class Test {
 6
 7     /**
 8      * @param args
 9      */
10     public static void main(String[] args) {
11         SequentialList list = new SequentialList(100);
12
13         try {
14             list.insert(list.size(), new Students("S0001", "张三", "男", 18)); //第一个参数list.size代表的是:我每次都是在顺序表的最后一个位置(当前线性表的长度的位置)进行插入操作。这一行里,size是等于0
15             list.insert(new Students("S0002", "李四", "男", 19));
16             list.insert(list.size(), new Students("S0003", "王五", "女", 21));
17             list.insert(new Students("S0004","赵六","女",20));
18
19             for (int i = 0; i < list.size(); i++) {
20                 System.out.println(list.get(i));
21             }
22
23         } catch (Exception ex) {
24             ex.printStackTrace();
25         }
26     }
27
28 }

注意第11行的注释:第一个参数list.size代表的是:我每次都是在顺序表的最后一个位置(当前线性表的长度的位置)进行插入操作;这样的话,遍历时才是按照张三、李四、王五的顺序进行输出的。

运行效果:

学号:S0001 姓名:张三 性别:男 年龄:18
学号:S0002 姓名:李四 性别:男 年龄:19
学号:S0003 姓名:王五 性别:女 年龄:21
学号:S0004 姓名:赵六 性别:女 年龄:20

本文参考博客:http://www.cnblogs.com/smyhvae/p/4758808.html,并加入自己的一点改动,后续还会有优化改动,例如加入泛型等。。。。。。

原文地址:https://www.cnblogs.com/midiyu/p/8158395.html

时间: 2024-10-12 08:03:56

数据结构Java实现01----线性表与顺序表的相关文章

数据结构Java实现02----线性表与顺序表

[正文] 本节内容: 线性结构 线性表抽象数据类型 顺序表 顺序表应用 一.线性结构: 如果一个数据元素序列满足: (1)除第一个和最后一个数据元素外,每个数据元素只有一个前驱数据元素和一个后继数据元素: (2)第一个数据元素没有前驱数据元素: (3)最后一个数据元素没有后继数据元素. 则称这样的数据结构为线性结构. 二.线性表抽象数据类型: 1.线性表抽象数据类型的概念: 线性表抽象数据类型主要包括两个方面:既数据集合和该数据集合上的操作集合. 数据集合: 可以表示为a0,a1,a2,...a

《数据结构》复习之线性表(顺序表和链表)

线性表的概念 线性表的比较 线性表的数据结构 顺序表的算法操作 双链表的补充 总结 1.线性表的概念 线性表的存储结构有顺序存储结构和链式存储结构两种.前者成为顺序表,后者称为链表. 顺序表: 顺序表就是把线性表中的所有元素按照其逻辑顺序,一次存储到从指定的存储 位置开始的一块连续的存储空间中,如下图所示. 链表 在链表的存储中,每一个节点不仅包含所存元素本身的信息,还包含元素之间的逻辑关系的信息,即前驱节点包含后继节点的地址信息,这样就可以通过前驱节点中的地址信息方便地找到后继节点的位置,如下

[C++] 数据结构(C):线性表之顺序表

1 顺序表 ADT + Status InitList(SeqList &L) 初始化顺序表 + Status GetElement(SeqList L, int i, ElementType &e) (按位)取值  + int LocateElement(SeqList L, ElementType e) (按值)查找  + Status ListInsert(SeqList &L, int i, ElementType e) (按位)插入  + Status ListDelet

数据结构-线性表_顺序表

进入大学一年了,今日终于有勇气写写随笔并展示出来了. 如有不足之处,请大家指正. 今日我想写的就是我对数据结构-线性表_顺序表的理解. 不BB了,进入正题!!!!! 数据结构中的逻辑结构分为线性结构和非线性结构,而线性表就属于线性结构. 线性结构是 n 个数据元素的有序(次序)集合,它有下列几个特征: 集合中必存在唯一的一个 "第一个元素": 集合中必存在唯一的一个 "最后的元素": 除最后元素之外,其它数据元素均有唯一的 "后继": 除第一元素

【算法和数据结构】_17_小算法_线性结构:顺序表

/* 本程序用来测试数据结构中的线性结构:顺序表 */ #include <stdio.h> #include <stdlib.h> #define LINEAR_MAX_SIZE 64 struct LinearList { int* List; //顺序表指针 unsigned short int ListLen; //顺序表最大的元素个数 unsigned short int CurrentLen; //顺序表当前元素的个数 }; typedef struct LinearL

线性链表之顺序表

顺序表中数据元素的存储地址是其序号的线性函数,只要确定了存储顺序表的起始地址(即 基地址),计算任意一个元素的存储地址的时间是相等的,具有这一特点的存储结构称为[随机存储]. 使用的基本数据结构:数组 特点:顺序存取,随机访问. /* Name: SeqList Copyright: 1.0 Author: Johnny Zen Date: 04/06/17 21:51 Description: 线性链表之顺序表 *//* Chinese:顺序(线性)表 English:SeqList*/#in

C#线性表之顺序表

线性表是最简单.最基本.最常用的数据结构.线性表是线性结构的抽象(Abstract), 线性结构的特点是结构中的数据元素之间存在一对一的线性关系. 这种一对一的关系指的是数据元素之间的位置关系,即: (1)除第一个位置的数据元素外,其它数据元素位置的前面都只有一个数据元素: (2)除最后一个位置的数据元素外,其它数据元素位置的后面都只有一个元素.也就是说,数据元素是一个接一个的排列.因此,可以把线性表想象为一种数据元素序列的数据结构. 线性表的接口如下所示. public interface I

线性表之顺序表奇偶调整和单链表就地逆置

线性表之顺序表奇偶调整,就是指将顺序表的奇数与偶数位置互换,以最优方法解决,因为方法很多,比如,开辟一个新的顺序表分别存放奇偶数,也可以从头向后寻找奇偶数放置到尾部或头部,但这些都会增大时间与空间的消耗.最优法则是前后分别寻找奇偶不同类型数,满足前奇后偶(或前偶后期),交换两数位置,实现时间复杂度O(n),空间O(1)的方案. void AdjustSqlist(SeqList *L) { int i=0,j=L->last; int temp; while(i<j) { while(L-&g

线性表之顺序表C++实现

线性表之顺序表 一.头文件:SeqList.h //顺序线性表的头文件#include<iostream> const int MaxSize = 100;//定义顺序表SeqList的模板类template<class DataType>class SeqList{public: //顺序表无参构造器(创建一个空的顺序表) SeqList(){ length = 0 } //顺序表有参构造器(创建一个长度为n的顺序表) SeqList(DataType array[], int