分析:
先要满足以下基本的要求,遇到问题再做完善。
线性表的属性:
线性表的长度
存放线性表的数组
需要实现的方法:
判断线性表是否为空,将线性表设为空表
增(尾部增加元素,索引位置增加元素)
删(删除尾部元素,删除索引位置元素)
改(更改索引位置元素)
查(查找元素索引,查找索引位置元素)
打印线性表
注意事项:
因为线性表是在数组中实现,数组下标从0开始,而线性表的索引值从1开始
解决办法:
1.当对线性表的index位置进行操作时,对数组的操作为对下标(index - 1)进行操作(本篇采用此种方法)
2.使用数组首位存放线性表的长度,即arr[0]存储线性表长度,此时线性表的索引与数组的下标统一
属性设置:
private int length ;//线性表的长度
private int[] arr = new int[10];//线性表所在数组长度
方法实现:
1.判断线性表是否为空和将线性表设为空表:
线性表长度为0即为空;
将线性表长度设为0,即将线性表设为空表
public boolean isEmpty(){//判空
if(length == 0)
return true;
return false;
}
public void setNull(){//设空
length = 0;
}
2.增加元素(末尾增加)
末尾增加元素直接对线性表的末尾元素的后一位赋值即可
public void insert(int value){//末尾增加value
arr[length] = value;
length++;
}
3.增加元素(索引位置增加)
(1)将索引位置的元素及其之后的元素后移一位
(2)把增加元素赋值给索引位置
图解:
设有一个长度为5的线性表内容如下图:
现在要在索引3处插入10:
将索引位置的元素及其之后的元素后移一位:
把增加元素赋值给索引位置:
public void insert(int index,int value){//索引位置插入value
if (index < 1 || index > length+1){//判断位置是否合法
System.out.println("输入位置无效!");
return;
}
for(int i = length;i > index-1 ;i--){
arr[i] = arr[i-1];
}
arr[index - 1] = value;
length++;
}
4.删除元素(末尾元素):
线性表长度减一即可
public void delete(){//删除末尾元素
if(length > 0){
length--;
}else{
System.out.println("线性表为空表,无法删除元素!");
}
}
5.删除元素(删除索引位置元素):
索引位置之后的元素依次前移一位
图解:
索引位置之后的元素依次前移一位:
public void delete(int index){//删除索引位置元素
if(index < 1 || index > length){
System.out.println("索引非法!");
}else{
for(int i = index;i < length;i++){
arr[i-1] = arr[i];
}
length--;
}
}
6.更改索引位置元素:
直接对索引位置赋值即可
public void update(int index,int value){//更改指定位置元素值
if(index < 1 || index > length){
System.out.println("索引非法!");
}else{
arr[index - 1] = value;
}
}
7.查找(指定元素索引(首次出现)):
从头遍历线性表,依次判断是否与要查找的元素值相等,直到找到(return index)或者遍历完还未找到(return 0)
public int locateElement(int value){//返回指定元素位置(首次出现)
for(int i = 0 ;i < length+1;i++){
if (arr[i] == value)
return i+1;
}
return 0;
}
8.查找(指定索引位置的元素):
返回索引位置的元素值即可
public int getElement(int index){//返回指定索引的值 越界返回0
if(index > length || index < 1)
return 0;
else
return arr[index-1];
}
9.打印线性表:
遍历线性表,依次输出即可
public void show(){//打印线性表
if(isEmpty()){
System.out.println("线性表为空");
}
else{
System.out.print("[");
for(int i = 0; i < length;i++){
if (i == length - 1){
System.out.println(arr[i] + "]");
}else{
System.out.print(arr[i] + " ");
}
}
}
}
完善:
通过测试,很容易发现,因为在初始化时,用来实现线性表的数组大小固定为10,而且不再会改变,所以在经过一系列操作,当线性表的长度变为10时,再对线性表执行插入方法就会产生越界。
所以重新设置成员变量:
private int length;
private final int ADD_SIZE = 10;//增量
private int size = 10;//数组初始zize
private int[] arr = new int[size];
增加一个扩增方法,当线性表的长度length达到数组容量size时,对数组进行扩增(arr重新指向更大的数组)
public void expandArr(){//扩充数组
if(length == size){
size += ADD_SIZE;//新的数组容量
int[] tempArr = new int[size];//新建一个大数组
System.arraycopy(arr, 0, tempArr, 0,length);//原数组内容拷贝到大数组中
arr = tempArr;//arr重新指向大数组
}
}
在所有会增加线性表长度的方法的末尾调用此方法,会根据此时线性表长度判断是否对数组进行扩容:
测试是否还会越界:
package com.data_strucrue.linear;
public class Test {
//测试类
public static void main(String[] args) {
SeqLinear sl = new SeqLinear();
System.out.println("初始数组长度:" + sl.getArr().length );
for(int i = 0 ;i < 21; i++){//增加元素使线性表长度大于10,测试是否会越界
sl.insert(i+1);
System.out.println("执行" + (i + 1) + "次插入操作后,数组长度为:" + sl.getArr().length );
}
sl.show();
}
}
测试结果:
由结果可知,当元素插入十次后,此时线性表长度为10,数组size为10,此时进行扩增操作,增量为ADD_SIZE,数组size = size + ADD_SIZE,即此时数组容量变为20;插入20次后,继续扩容。所以扩容操作正常执行;
综上,线性表(顺序存储)的实现基本完善。
最终版代码为:
package com.data_strucrue.linear;
public class SeqLinear {
private int length;
private final int ADD_SIZE = 10;
private int size = 10;
private int[] arr = new int[size];
public void setNull(){//设空
length = 0;
}
public boolean isEmpty(){//判空
if(length == 0)
return true;
return false;
}
public int getLength(){//返回顺序表长度
return length;
}
public int getElement(int index){//返回指定索引的值 越界返回0
if(index > length || index < 1)
return 0;
else
return arr[index-1];
}
public int locateElement(int value){//返回指定元素位置(首次出现)
for(int i = 0 ;i < length+1;i++){
if (arr[i] == value)
return i+1;
}
return 0;
}
public void insert(int index,int value){//索引位置插入value
if (index < 1 || index > length+1){
System.out.println("输入位置无效!");
return;
}
for(int i = length;i > index-1 ;i--){
arr[i] = arr[i-1];
}
arr[index - 1] = value;
length++;
expandArr();
}
public void insert(int value){//末尾增加value
arr[length] = value;
length++;
expandArr();
}
public void delete(){//删除末尾元素
if(length > 0){
length--;
}else{
System.out.println("线性表为空表,无法删除元素!");
}
}
public void delete(int index){//删除索引位置元素
if(index < 1 || index > length){
System.out.println("索引非法!");
}else{
for(int i = index;i < length;i++){
arr[i-1] = arr[i];
}
length--;
}
}
public void update(int index,int value){//更改指定位置元素值
if(index < 1 || index > length){
System.out.println("索引非法!");
}else{
arr[index - 1] = value;
}
}
public void show(){//打印线性表
if(isEmpty()){
System.out.println("线性表为空");
}
else{
System.out.print("[");
for(int i = 0; i < length;i++){
if (i == length - 1){
System.out.println(arr[i] + "]");
}else{
System.out.print(arr[i] + " ");
}
}
}
}
public void expandArr(){//扩充数组
if(length == size){
size += ADD_SIZE;
int[] tempArr = new int[size];
System.arraycopy(arr, 0, tempArr, 0,length);
arr = tempArr;
}
}