线性表
线性表(linear list)是n个具有相同特性的数据元素的有限序列
常见的线性表:顺序表、链表、栈、队列…
线性表在逻辑上是线性结构,也就说是连续的一条直线,但是在物理结构上并不一定是连续的,线性表在物
理上存储时,通常以数组和链式结构的形式存储
顺序表
顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储
在数组的基础上完成增删查改
例如:
写一个顺序表,里面完成增删查改功能
打印顺序表
首先要有一个数组
来存放数据,还要有一个变量
来记录当前数组元素的个数
DEFAULT_SIZE
这个变量是设置数组元素的大小,也可以不用变量来定义,直接写元素的个数
打印数组就是循环遍历数组打印,很简单
public class MyArrayList {
private int[] elem; // 数组
private int used; //记录数组的有效个数
// 这个变量是设置 数组元素的大小
private static final int DEFAULT_SIZE = 10;
// 构造方法 初始化
public MyArrayList(){
// 把数组初始化为 10 个元素
this.elem = new int[DEFAULT_SIZE];
}
// 1.打印顺序表 这只是有来测试的 这不是里顺序表的方法
public void display() {
for (int i = 0; i < used - 1; i++) {
System.out.print(elem[i] + " ");
}
//换行
System.out.println();
}
新增元素
新增元素是在原本的数组后面添加一个新的元素
新增元素要先检查当前数组空间是否满了,如果数组满了要进行扩容
,Arrays.copyOf
是扩容
最后才是添加新的元素
判断数组空间是否满 写了一个方法,之后可能会用到
// 2.新增元素,默认在数组最后新增
public void add(int data) {
// 检查当前数组是否为满
if(isFull()){
// 空间满 扩容
this.elem = Arrays.copyOf(this.elem,2*elem.length);
}
// 添加新元素,最后是used+1
this.elem[used] = data;
this.used++;
}
// 判断数组空间是否满
public boolean isFull(){
// 如果数组空间满了返回 true
if(size() >= elem.length){
return true;
}
return false;
}
// 返回当前数组的元素个数
public int size(){
return this.used;
}
在写了以上三个方法后,就可以创建一个新的类进行测试
在某个位置新增元素
在某个位置新增元素必须要满足下面的条件:
不能是负数的下标
不能越界
不能间隔放元素,存储的位置前面必须是有元素的
重新创建一个异常类
,用来判断pos
位置的合法性
// 判断 pos 位置的异常
public class PosWrongfulException extends RuntimeException{
public PosWrongfulException(){
}
public PosWrongfulException(String n){
super();
}
}
---------------------------------------------------------------------------
/**
* 3.在 pos 位置新增元素
* 如果 pos 下标不合法,就会抛出一个 PosWrongfulException 异常
*/
public void add(int pos, int data) throws PosWrongfulException {
// 判断数组空间元素是否放满
if(isFull()){
System.out.println("数组空间以放满,扩容!");
this.elem = Arrays.copyOf(this.elem,2*elem.length);
}
// 判断合法性 是否有越界
if(pos < 0 || pos > this.used){
System.out.println("add 新增的pos 位置不合法!");
throw new PosWrongfulException("add 新增的pos 位置不合法!");
}
// 挪动数据
for (int i = this.used-1; i >= pos; i--) {
this.elem[i+1] = this.elem[i];
}
// 从 pos 下标插入 data 数据
this.elem[pos] = data;
// 元素个数+1
this.used++;
}
判定是否包含某个元素
历遍数组找,但是不能超过 used(数组的元素个数)
// 4.判定是否包含某个元素
public boolean contains(int toFind) {
for (int i = 0;i<used;i++){
if(this.elem[i] == toFind){
return true;
}
}
return false;
}
查找某个元素对应的位置
历遍数组找,找到返回下标,找不到返回 -1
public int indexOf(int toFind) {
for (int i = 0;i<used;i++){
if(this.elem[i] == toFind){
return i;
}
}
return -1;
}
获取 某个 位置的元素
传过来的数据可能为空,创建一个异常类
,用来判断pos
位置是否为空
public class EmptyException extends RuntimeException{
public EmptyException() {
}
public EmptyException(String message) {
super(message);
}
}
----------------------------------------------------------
public int get(int pos) {
if(isEnpty()){
throw new EmptyException("当前顺序表为空!");
}
if(pos < 0 || pos >= this.used){
throw new PosWrongExceotion("get 获取的 pos 的位置不合法!");
}
// 返回元素
return this.elem[pos];
}
public boolean isEnpty(){
return size() == 0;
}
给 某个 位置的元素设为 value
// 7.给 pos 位置的元素设为 value
public void set(int pos, int value) {
// 判断
if(isEnpty()){
throw new EmptyException("顺序表为空!");
}
if(pos < 0 || pos >= this.used){
throw new PosWrongExceotion("set 获取元素时,pos不合法!");
}
// 修改
this.elem[pos] = value;
}
删除第一次出现的关键字key
1.首先要判断数组是否是空的顺序表,如果为直接返回
2. 先找到 key(你要删除的数字)
,才能知道下标
3. 挪动数据
4. used++
public void remove(int Key) {
if(isEnpty()){
throw new EmptyException("顺序表为空!");
}
int n = 0;
for (int i = 0;i<used;i++){
if(this.elem[i] == Key){
n = i;
}
}
for (int i = n; i < this.used-1; i++) {
this.elem[i] = this.elem[i+1];
}
this.used--;
}
-------------------------------------------------------------------------
代码简化
public void remove(int Key) {
if(isEnpty()){
throw new EmptyException("顺序表为空!");
}
// indexOf 是上面写的方法
int n = this.indexOf(Key);
if(n == -1){
System.out.println("没有这个数字!");
return;
}
for (int i = n; i < this.used-1; i++) {
this.elem[i] = this.elem[i+1];
}
this.used--;
}
清空顺序表
// 10.清空顺序表
public void clear() {
this.used = 0;
// 如果是引用类型,要把每个空间都制成 null
// for (int i = 0;i<used;i++){
// this.elem[i] = null;
// }
// this.used = 0;
}
源代码
import java.util.Arrays;
public class MyArrayList {
private int[] elem; // 数组
private int used; //记录数组的有效个数
// 这个变量是设置 数组元素的大小
private static final int DEFAULT_SIZE = 10;
// 构造方法 初始化
public MyArrayList(){
// 把数组初始化为 10 个元素
this.elem = new int[DEFAULT_SIZE];
}
// 1.打印顺序表 这只是有来测试的 这不是里顺序表的方法
public void display() {
for (int i = 0; i < this.used; i++) {
System.out.print(this.elem[i] + " ");
}
// 换行
System.out.println();
}
// 2.新增元素,默认在数组最后新增
public void add(int data) {
// 检查当前数组是否为满
if(isFull()) {
this.elem = Arrays.copyOf(this.elem,2*this.elem.length);
}
this.elem[used] = data;
used++;
}
public boolean isFull(){
if(size() >= elem.length) {
return true;
}
return false;
}
// 3.在 pos 位置新增元素
public void add (int pos, int data) throws PosWrongExceotion{
// 判断数组是否满了
if(isFull()){
//扩容
System.out.println("空间已满,扩容!");
this.elem = Arrays.copyOf(this.elem,2*this.elem.length);
}
// 判断是否有越界
if(pos < 0 || pos > this.used){
System.out.println("pos 的位置不合法!");
throw new PosWrongExceotion("pos 的位置不合法!");
}
// 挪动数据
for (int i = used-1; i >= pos; i--) {
this.elem[i+1] = this.elem[i];
}
// 从 pos 下标插入 data 数据
this.elem[pos] = data;
// 元素个数+1
used++;
}
// 4.判定是否包含某个元素
public boolean contains(int toFind) {
for (int i = 0;i<used;i++){
if(this.elem[i] == toFind){
return true;
}
}
return false;
}
// 5.查找某个元素对应的位置
public int indexOf(int toFind) {
for (int i = 0;i<used;i++){
if(this.elem[i] == toFind){
return i;
}
}
return -1;
}
// 6.获取 pos 位置的元素
public int get(int pos) {
if(isEnpty()){
throw new EmptyException("当前顺序表为空!");
}
if(pos < 0 || pos >= this.used){
throw new PosWrongExceotion("get 获取的 pos 的位置不合法!");
}
return this.elem[pos];
}
public boolean isEnpty(){
return size() == 0;
}
// 7.给 pos 位置的元素设为 value
public void set(int pos, int value) {
// 判断
if(isEnpty()){
throw new EmptyException("顺序表为空!");
}
if(pos < 0 || pos >= this.used){
throw new PosWrongExceotion("set 获取元素时,pos不合法!");
}
// 修改
this.elem[pos] = value;
}
//8.删除第一次出现的关键字key
public void remove(int Key) {
if(isEnpty()){
throw new EmptyException("顺序表为空!");
}
// indexOf 是上面写的方法
int n = this.indexOf(Key);
if(n == -1){
System.out.println("没有这个数字!");
return;
}
for (int i = n; i < this.used-1; i++) {
this.elem[i] = this.elem[i+1];
}
this.used--;
}
// 9.获取顺序表长度
public int size() {
return this.used;
}
// 10.清空顺序表
public void clear() {
this.used = 0;
// 如果是引用类型,要把每个空间都制成 null
// for (int i = 0;i<used;i++){
// this.elem[i] = null;
// }
// this.used = 0;
}
}
主函数测试
public class Test {
public static void main(String[] args) {
MyArrayList n = new MyArrayList();
// 2.测试 add 添加方法
n.add(1);
n.add(2);
n.add(3);
n.display();
// 3.测试 add添加新元素
try {
n.add(0,10);
}catch (PosWrongExceotion e){
e.printStackTrace();
}
n.display();
// 4. 测试 数组是否包含某个元素
System.out.println(n.contains(10));
System.out.println(n.contains(100));
// 5. 测试查找某个元素对应的位置
System.out.println(n.indexOf(10));
System.out.println(n.indexOf(88));
System.out.println("========================");
// 6. 测试获取 pos 位置的元素
try {
System.out.println( n.get(1));
}catch (PosWrongExceotion e){
e.printStackTrace();
}
System.out.println("==========================");
// 7.测试给 pos 位置的元素设为 value
n.set(0,88);
n.display();
System.out.println("==========================");
// 8.删除第一次出现的关键字key
n.remove(3);
n.display();
}
}