参考资料:《大话数据结构》
线性表(List)的定义
书中给出的定义为:零个或多个数据元素的有限序列。可想象成一串糖葫芦(用一根线可以把所有元素串起来)。
特点:
- 元素之间是有序的
- 元素的个数是有限个
当线性表元素的个数n定义为线性表的长度 ,当n=0时,为空表。
线性表的顺序存储结构
1. 定义
用一段地址连续的存储单元(数组)依次存储线性表的数据元素。定义一个线性表需要两个元素,即数组的长度和当前线性表中元素的个数(线性表中的n)。数组的长度分配后一般不可变,而线性表中的个数n可以改变,并且n<=数组长度。
int len; //数组长度
int n; //有效元素的个数
int[] arr;
int remove_value; //记录删除的元素的值
2. 获取线性表元素的操作
线性表与数组下标的对应关系为:线性表的第一个元素存储在数组下标为0的位置,第二个元素在下标为1的位置…
所以,如果我们想要获取线性表第m个元素,等价于获取数组下标为m-1位置上的元素。
3.插入操作
首先,在进行插入操作之前,我们应该判断当前线性表有效元素个数n是否小于数组长度。若小于则可以进行插入操作,否则不可进行插入操作(此时,数组已满,假设数组不能扩容)。
假设现在还可以插入,则判断要插入的位置和数组下标的关系,若想要插入的位置大于数组长度减一,则不能进行插入。
然后进行插入操作。可以想象成排队买票,最后来的人当然排到原来最后一个人的后面,此时为最简单的情况。但现在假设有一个人情况紧急,需要插队(假设和排在第三名位置的人说好了),则从第三名开始之后的人需要依次往后挪一个位置,而且必须是最后一个人先开始挪(想象下,如果你后面的人不动,你怎么往后挪一个位置)。如下图,则是7先动,然后6,一直到3。当3挪动之后(3现在跑到了数组下标为3的位置,即线性表的第四个元素的位置),将要插入的元素的值放到原来3所在的位置(数组下标为2的位置)。
最后将线性表有效元素个数加一。
if(n == len || pos > len || pos <1) { //如果线性表已满或者要插入的位置pos大于len或插入位置小于1,则不能插入
return false;
}else{
for(int i = n;i > pos - 1; i--){
arr[i] = arr[i-1]; //从后往前依次移
}
arr[pos-1] = value;
n++; //线性表有效元素个数加一
}
4. 删除操作
同插入操作一样,在进行删除操作之前,我们应对要删除位置进行判断。如果要删除的位置大于线性表的有效个数n,则不能删除。
若满足上面要求,则首先获取要删除位置的元素,然后从要删除的位置到线性表的最后一个元素,依次往前挪一位。
最后,将线性表有效元素个数减一。
if(n == 0 || pos < 1 || pos > len){ //线性表为空或者要删除位置小于1或者位置大于数组长度
return false;
}else{
remove_value = arr[pos - 1];
for(int i = pos;i < n;i++){
arr[pos-1] = arr[pos]; //从前往后依次移
}
n--;
}
5.线性表顺序存储的优缺点
优点 | 缺点 |
---|---|
根据线性表与数组下标的对应关系,可以快速找到要取的元素,因此其查询较快 | 由上面的增删可以看到,对一个位置的增删,需要移动大量的元素,因此增删较慢。此外,由于数组长度固定,当线性表长度变化大时,很难确定数组长度。 |
Java代码实现
public class Array {
int len; //数组长度
int cnt; //有效元素的个数
int[] arr;
int remove_value; //记录删除的元素的值
public Array(int len) {
cnt = 0; //有效元素个数刚开始为0,以cnt为下标的位置无值
this.len = len;
arr = new int[len]; //初始化数组,长度为len,值都为0
}
/*判断数组是否为空*/
public boolean is_empty() {
if (cnt == 0)
return true;
else
return false;
}
/*输出数组*/
public void show_Array() throws EmptyException{
if(is_empty()){
throw new EmptyException("数组为空,无法输出");
}else{
for(int i = 0;i < cnt;i++){
System.out.println(arr[i]);
}
}
}
/*判断数组是否满*/
public boolean is_full(){
if (cnt == len)
return true;
else
return false;
}
/*数组追加元素*/
public boolean append_Array (int value) throws FullException {
if (is_full()) {
throw new FullException("数组已满,无法追加");
}else{
arr[cnt] = value;
cnt++;
return true;
}
}
/*在某个特定位置添加元素*/
public boolean insert_Array(int pos,int value) throws FullException {
if (is_full()) {
throw new FullException("数组已满,无法添加");
}else{
/*例如要在第三个位置添加,实际上是在下标为2的地方添加,
从最后一个位置的元素到下标为2的元素,依次向后移一位,
先移后添加
*/
for(int i = cnt;i > pos - 1; i--){
arr[i] = arr[i-1];
}
arr[pos - 1] = value;
cnt++; //添加后数组元素多一个,故++
return true;
}
}
/*删除某个位置元素*/
public boolean delect_Array(int pos)throws EmptyException{
if(is_empty()) {
throw new EmptyException("数组为空,无法删除");
}else if(pos < 1 || cnt < pos){ //若要删除的位置小于1或者大于线性表有效元素的个数,则报错
return false;
} else{
/*同在某个位置添加元素,不同的先将元素删除,再把后面位置的元素依次向前移一位*/
remove_value = arr[pos - 1];
for(int i = pos;i < cnt;i++) {
arr[i - 1] = arr[i];
}
}
return true;
}
/*数组元素倒置,此方法适用于有效元素个数为奇数或偶数*/
public void inversion_Array(){
int i = 0;
int j = cnt - 1; //最后一个元素的下标为cnt-1
int t;
while(i < j){
t = arr[i];
arr[i] = arr[j];
arr[j] = t;
i++;
j--;
}
}
/*使用冒泡排序对数组进行排序(从小到大)*/
public void sort_Array(){
int t;
for(int i = cnt - 1;i > 0;i--){
for(int j = 0;j < i;j++){
if(arr[j] > arr[j+1]){
t = arr[j];
arr[j] = arr[j+1];
arr[j+1] = t;
}
}
}
}
}
-----------------------------------------------------------------------------------
public class EmptyException extends Exception {
public EmptyException(String message) {
super(message);
}
}
-----------------------------------------------------------------------------------
public class FullException extends Exception{
public FullException(){
super();
}
public FullException(String message){
super(message);
}
}
-----------------------------------------------------------------------------------
public class test {
public static void main(String[] args) {
Array a = new Array(5); //数组长度为10,有效元素为0
try{
a.append_Array(100);
a.append_Array(66);
a.append_Array(88);
a.insert_Array(2,40);
a.insert_Array(5,2312);
a.delect_Array(a.cnt);
a.show_Array();
} catch(Exception e){
e.printStackTrace();
}
}
}