线性表分为链表和顺序表,用数组来存储的线性表就是顺序表,所以我们在构建顺序表的时候可以把他近似的看成数组来构建。
构建顺序表
public class Sequence {
private int[] list;//用数组来存储数据
private int usedSize;//顺序表的长度
private int cap;//顺序表的容量
public Sequence(int cap) {
this.usedSize = 0;//初始化
this.cap = cap;
list = new int[cap];
}
public int[] getList() {
return list;
}
public void setList(int[] list) {
this.list = list;
}
public int getUsedSize() {
return usedSize;
}
public void setUsedSize(int usedSize) {
this.usedSize = usedSize;
}
public int getCap() {
return cap;
}
public void setCap(int cap) {
this.cap = cap;
}
实现功能
在实现功能之前我们首先需要知道
- 顺序表是否为空
我们在实现顺序表的删除和头插的功能的时候会需要先判断这个顺序表里面有没有元素,可以写一个判空的函数,需要用到的时候直接调用函数就可以
public boolean isEmpty(){//判断顺序表是否为空
if(this.getUsedSize()==0){
return true;
}
return false;
}
- 顺序表是否已满
我们在实现添加数据的功能的时候需要注意这个问题,如果顺序表满了无法再继续添加元素
public boolean isFull(){//判断顺序表是否满了
if(this.getUsedSize()==this.cap){
return true;
}
return false;
}
- 输入的下标是否有错
在实现插入或者查找操作的时候会用到这个函数,如果下标输入的方式有错,也无法实现想实现的功能
public boolean isError(int index){//判断输入的下标是否有错
if(index<0 || index>this.getUsedSize()){
return true;
}
return false;
}
添加元素
头插法
每一个新添加的元素都会从数组零下标的位置插入,所以我们需要先判断顺序表的是否为空,如果是空的话直接把元素的值赋给零下标,如果不为空,就将顺序表中的数据都往后移一位,再将值赋给零下标
此时想使用头插法添加元素就需要先将1下标的数据移到2下标的位置上,再将0下标的数据移到1的位置上。
如果选择先把0下标的值给1下标,这样值就会被覆盖,无法实现添加元素的功能
public void addFirst(int data){//头插
int curSize = this.getUsedSize();
if(isFull()) {
System.out.println("顺序表已满,无法再添加元素");
return;
}
if(isEmpty()){//如果表中本来没有元素直接赋值
this.list[curSize] = data;
usedSize = curSize+1;
return;
}
for(int i = curSize-1;i>=0;i--){//将数据都向后移一位
this.list[i+1] = this.list[i];
}
this.list[0] = data;
usedSize = curSize+1;//添加完元素之后长度加1
}
尾插法
尾插法不需要移动数据,只要这个时候顺序表没有满,就可以直接把值赋到list[usedSize]
public void addLast(int data){//尾插
if(isFull()) {
System.out.println("顺序表已满,无法再添加元素");
return;
}
int curSize = this.getUsedSize();
this.list[curSize]=data;
usedSize = curSize+1;
}
下标插入
下标插入和头插法用到的方法是类似的,先判断顺序表是否满了,然后再把index以及之后的数据都向后移一位
比如要将2放到1下标的位置
把下标2~1遍历一遍,实现list[i+1]=list[i],把i下标的值赋给i+1下标
再让list[index] = data
public void insert(int index,int data){//在指定位置插入元素
int curSize = this.getUsedSize();
if(isError(index)){
System.out.println("下标输入异常");
return;
}
if(isFull()){
System.out.println("顺序表已满,无法添加元素");
return;
}
if(index==0){//插入的位置为0下标,可以使用头插法
addFirst(data);
return;
}
if(index == this.getUsedSize()){//插入的位置为usedSize的下标,可以使用尾插法
addLast(data);
return;
}
for(int i = curSize-1;i>=index;i--){//从后往前遍历
this.list[i+1] = this.list[i];
}
this.list[index] = data;
usedSize = curSize+1;
}
删除元素
删除元素就直接把要删除的这个元素的值被后面的值覆盖
要删除index下标的元素,就从index处开始遍历,直到usedSize下标,每次都让list[i] = list[i+1],把i+1的值赋给i,来实现删除的功能
public void delete(int index){
int curSize = this.getUsedSize();
if(isEmpty()){
System.out.println("该表为空,无法删除元素");
return ;
}
if(index==curSize-1){//删除的下标是末尾的数字,直接把长度减1即可
usedSize = curSize-1;
return;
}
for(int i = index; i<curSize-1;i++){
this.list[i] = this.list[i+1];
}
usedSize = curSize-1;//删除成功,顺序表长度减1
}
查找元素
如果要输入一个元素来得到下标的值,就先遍历一遍,当list[i]的值和data相同时输出i的值
public void search(int data){
for(int i = 0;i<this.getUsedSize();i++){
if(this.list[i]==data){
System.out.println(data+"的下标为:"+i);
return;
}
}
System.out.println(data+"不在这个顺序表中");//遍历完成之后发现没有相等的情况,说明顺序表中没有输入的数据
}
如果要输入下标来得到元素,需要先判断index的输入合不合理,无需遍历一遍顺序表,直接输出就行
public int search(int index){
if(isError(index)){
return -1;
}
System.out.println("该下标对应的数字为"+this.list[index]);
return this.list[index];
}
修改元素
实现将一个元素修改成为另一个元素,找到data1所在的下标后将data2的值赋给data1的下标就算修改完成了
public void change(int data1,int data2){
int flag = 0;//因为data1有不存在在顺序表中的可能
for(int i = 0; i<this.getUsedSize();i++){
if(this.list[i]!=data1){
flag++;
}
if(this.list[i]==data1) {
this.list[i] = data2;//因为担心顺序表中有重复的元素都要修改,所以这里没有加return,如果只需要修改第一个元素,可以在这里添加return
}
}
if(flag==this.getUsedSize()){//说明list[i]一直都不等于data1,也就是顺序表中没有data1这个数据
System.out.println("顺序表中没有"+data1+",无法进行修改");
}
}
完整代码
public class Sequence {
private int[] list;
private int usedSize;//顺序表内存了多少数字
private int cap;//顺序表的容量
public Sequence(int cap) {
this.usedSize = 0;
this.cap = cap;
list = new int[cap];
}
public int[] getList() {
return list;
}
public void setList(int[] list) {
this.list = list;
}
public int getUsedSize() {
return usedSize;
}
public void setUsedSize(int usedSize) {
this.usedSize = usedSize;
}
public int getCap() {
return cap;
}
public void setCap(int cap) {
this.cap = cap;
}
public boolean isEmpty(){//判断顺序表是否为空
if(this.getUsedSize()==0){
return true;
}
return false;
}
public boolean isFull(){//判断顺序表是否满了
if(this.getUsedSize()==this.cap){
return true;
}
return false;
}
public boolean isError(int index){//判断输入的下标是否有错
if(index<0 || index>this.getUsedSize()){
return true;
}
return false;
}
public void addLast(int data){//尾插
if(isFull()) {
System.out.println("顺序表已满,无法再添加元素");
return;
}
int curSize = this.getUsedSize();
this.list[curSize]=data;
usedSize = curSize+1;
}
public void addFirst(int data){//头插
int curSize = this.getUsedSize();
if(isFull()) {
System.out.println("顺序表已满,无法再添加元素");
return;
}
if(isEmpty()){
this.list[curSize] = data;
usedSize = curSize+1;
return;
}
for(int i = curSize-1;i>=0;i--){
this.list[i+1] = this.list[i];
}
this.list[0] = data;
usedSize = curSize+1;
}
public void insert(int index,int data){//在指定位置插入元素
int curSize = this.getUsedSize();
if(isError(index)){
System.out.println("下标输入异常");
return;
}
if(isFull()){
System.out.println("顺序表已满,无法添加元素");
return;
}
if(index==0){
addFirst(data);
return;
}
if(index == this.getUsedSize()){
addLast(data);
return;
}
for(int i = curSize-1;i>=index;i--){
this.list[i+1] = this.list[i];
}
this.list[index] = data;
usedSize = curSize+1;
}
public void delete(int index){
int curSize = this.getUsedSize();
if(isEmpty()){
System.out.println("该表为空,无法删除元素");
return ;
}
if(index==curSize-1){
usedSize = curSize-1;
return;
}
for(int i = index; i<curSize-1;i++){
this.list[i] = this.list[i+1];
}
usedSize = curSize-1;
}
public void search(int data){
for(int i = 0;i<this.getUsedSize();i++){
if(this.list[i]==data){
System.out.println(data+"的下标为:"+i);
return;
}
}
System.out.println(data+"不在这个顺序表中");
}
public void change(int data1,int data2){
int flag = 0;
for(int i = 0; i<this.getUsedSize();i++){
if(this.list[i]!=data1){
flag++;
}
if(this.list[i]==data1) {
this.list[i] = data2;
}
}
if(flag==this.getUsedSize()){
System.out.println("顺序表中没有"+data1+",无法进行修改");
}
}
public void show(){//打印顺序表
for(int i = 0;i<this.getUsedSize();i++){
System.out.print(this.list[i]+" ");
}
System.out.println();
System.out.println("此时顺序表的长度为:"+this.getUsedSize());
}
测试代码及运行结果
添加元素(头插)
public static void main(String[] args) {
Sequence sequence = new Sequence(5);//自定义cap的值
sequence.addFirst(4);
sequence.addFirst(3);
sequence.addFirst(2);
sequence.addFirst(1);
sequence.show();
}
尾插法
public static void main(String[] args) {
Sequence sequence = new Sequence(5);
sequence.addLast(1);
sequence.addLast(2);
sequence.addLast(3);
sequence.addLast(4);
sequence.show();
}
根据下标位置插入元素
public static void main(String[] args) {
Sequence sequence = new Sequence(5);
sequence.addLast(1);
sequence.addLast(2);
sequence.addLast(3);
sequence.addLast(4);
sequence.insert(2,5);
sequence.show();
}
删除元素
public static void main(String[] args) {
Sequence sequence = new Sequence(5);
sequence.addFirst(4);
sequence.addFirst(3);
sequence.addFirst(2);
sequence.addFirst(1);
sequence.show();
sequence.delete(2);
sequence.show();
}
查找元素
public static void main(String[] args) {
Sequence sequence = new Sequence(5);
sequence.addFirst(4);
sequence.addFirst(3);
sequence.addFirst(2);
sequence.addFirst(1);
sequence.show();
sequence.search(3);
}
修改元素
public static void main(String[] args) {
Sequence sequence = new Sequence(5);
sequence.addFirst(4);
sequence.addFirst(3);
sequence.addFirst(2);
sequence.addFirst(1);
sequence.show();
sequence.change(2,6);
sequence.show();
}