文章目录
线性表
什么是线性表呢?线性表是一种在实际中广泛运用的数据结构,例如:顺序表、链表、栈和队列。线性表在逻辑结构上是线性结构,就是一条线连续的,但是在物理结构上并不一定连续,今天我们要学习的顺序表就是线性结构的一种。
顺序表
顺序表名字听起来挺高大上的,但其实底层的逻辑就是一个数组,是用一段物理地址连续的存储单元依次存储数据结构元素的线性结构。
顺序表的模拟实现
首先我们先来创建一个顺序表:
public class SeqList {
private int[] array;//数组
private int usedsize;//当前数组有多少个元素,初始为0
private static int DEFAULT_SIZE = 5;
// 默认构造方法
public SeqList(){
array = new int[DEFAULT_SIZE];//创建顺序表对象时创建一个5个元素的数组
}
}
便于我们检测我们写的方法的正确性,我们可以写一个打印顺序表的方法。
// 打印顺序表,注意:该方法并不是顺序表中的方法,为了方便看测试结果给出的
public void display() {
for(int i = 0;i < usedsize;i++) {
System.out.print(array[i] + " ");
}
System.out.println();
}
这样就可以遍历打印数组中的元素了,也就是遍历打印顺序表。
1、新增元素,默认在数组最后新增
//判断顺序表是否满
private boolean isFullAdd(int[] array) {
return usedsize == array.length;
}
// 新增元素,默认在数组最后新增
public void add(int data) {
//如果超过顺序表的最大容量需要先进行扩容
if(isFullAdd(array)) {
array = Arrays.copyOf(array,array.length * 2);
}
//如果没有超过直接在usedsize下标下添加元素
array[usedsize] = data;
usedsize++;
}
我们需要向顺序表中添加元素,也就是向数组末尾添加元素,在添加之前我们首先要判断一下顺序表是否满了,如果满了我们需要进行扩容,之后将我们添加的数据添加到usedsize
下标处就可以了。
我们在测试类里面测试一下我们的这个方法,成功将元素添加到了顺序表末尾并且打印出来,超出初始顺序表初始大小后会自动扩容。
2、判定是否包含某个元素
public boolean contains(int toFind) {
for(int i = 0;i < usedsize;i++) {
if(array[i] == toFind) {
return true;
}
}
return false;
}
遍历数组如果找到相同的元素就返回true,如果没有找到就返回false。
3、查找某个元素对应的位置
这个的思路跟判定是否包含某个元素是一样的,只不过这个方法返回的是对应元素的下标。
public int indexOf(int toFind) {
for(int i = 0;i < usedsize;i++) {
if(array[i] == toFind) {
return i;
}
}
return -1;
}
如果找到该元素就返回该元素的下标,没有找到就返回-1。
4、获取顺序表长度
这个方法我们直接返回usedsize
就可以了:
public int size() {
return usedsize;
}
5、在 pos 位置新增元素
在pos
位置新增元素时我们需要判断一下pos
参数是否合法,数组的小标不可以小于0,并且顺序表中的元素必须挨在一起,所以pos
也不可以大于usedsize
,判断完pos
参数还需要跟add
方法一样判断顺序表是否已满,已满需要扩容。
// 在 pos 位置新增元素
public void add(int pos, int data) {
//判断pos下标是否合法
try {
checkIndex(pos);
}catch (IndexException ex) {
ex.printStackTrace();
}
//如果超过顺序表的最大容量需要先进行扩容
if(isFullAdd(array)) {
array = Arrays.copyOf(array,array.length * 2);
}
for(int i = usedsize - 1;i >= pos;i--) {
array[i + 1] = array[i];
}
array[pos] = data;
usedsize++;
}
//判断add方法时的pos参数是否合法
private void checkIndex (int pos ) throws IndexException{
if(pos < 0 || pos > usedsize) {
throw new IndexException("pos下标不合法");
}
}
//判断顺序表是否满
private boolean isFullAdd(int[] array) {
return usedsize == array.length;
}
当我们对于pos
的合法性和顺序表是否已满进行判断完成后,我们需要的做的操作是,从数组的最后开始向后一次挪动数组元素,让数组元素向后挪动一位,直到找到pos
位置,将pos
位置上的元素向后移动一位后,将新增元素data
放入pos
位置。
6、获取 pos 位置的元素
同样我们需要对pos
的合法性进行一下判断,跟在pos位置新增元素的区别是pos
不可以等于usedsize
,因为usedsize
位置上并没有元素,会造成数组的越界访问。
// 获取 pos 位置的元素
public int get(int pos) {
try{
checkIndexGet(pos);
}catch (IndexException ex) {
ex.printStackTrace();
}
return array[pos];
}
//判断get时pos是否合法
private void checkIndexGet(int pos) throws IndexException{
if(pos < 0 || pos >= usedsize) {
throw new IndexException("调用get方法时,pos不合法");
}
}
7、给 pos 位置的元素设为 value
同样我们还需要对参数pos
进行合理性检查,之后将pos
位置的元素替换为data
。
// 给 pos 位置的元素设为 value
public void set(int pos, int value) {
try {
checkIndex(pos);
}catch (IndexException ex) {
ex.printStackTrace();
}
array[pos] = value;
}
8、删除第一次出现的关键字key
首先我们需要找到第一次出现关键字key的位置,可以通过之前写的indexOf
方法找到,找到之后我们只需要将后面的数据向前挪动移动一个位置,就可以覆盖掉key
元素。
//删除第一次出现的关键字key
public boolean remove(int toRemove) {
int index = indexOf(toRemove);
if(index == -1) {
System.out.println("没有该元素");
return false;
}
for(int i = index;i < usedsize -1;i++) {
array[i] = array[i + 1];
}
usedsize--;
array[usedsize] = 0;
return true;
}
9、清除顺序表
清空顺序表只需要将usedsize
置为0就可以了。
// 清空顺序表
public void clear() {
usedsize = 0;
}
以上我们就使用Java语言模拟实现了顺序表,模拟实现之后会帮助我们更好的理解顺序表,之后与大家分享顺序表的运用时大家会更容易理解。