[java]顺序表的头插,尾插,头删,尾删,中间插入,删除元素

import java.util.Arrays;
public class SeqList {
 // 属性
  private int[] array; // 用来保存数据
  private int size;  // 保存 array 已经有的数据个数
  // 构造方法
  public SeqList() {
   // 初始化部分
   // 1. 初始化 array,给定一个默认大小
   // 2. 初始化 size,没有数据,所以 size = 0
   array = new int[11]; // 11 可以调节
   size = 0;
  }  
  // 支持的方法
  // 头插 O(n)
  public void pushFront(int element) {
   ensureCapacity();   
   // i 是数据下标,遍历范围是 [size - 1, 0]
   for (int i = size - 1; i >= 0; i--) {
    array[i+1] = array[i];
   }   
   // [0] 空出来了
   array[0] = element;
   size++;
  }  
  // 尾插 O(1)
  public void pushBack(int element) {
   ensureCapacity();   
   array[size++] = element;
  } 
  // 中间插入,根据下标做插入 O(n)
  public void insert(int index, int element) {
   // index 的合法性 [0, size]
   if (index < 0 || index > size) {
    System.out.println("index 非法");
    return;
   }   
   ensureCapacity();  
   // i 代表的是空间的下标
   for (int i = size; i > index; i--) {
    array[i] = array[i - 1];
   }   
   array[index] = element;
   size++;
  }  
  // 头删
  public void popFront() {
   if (size == 0) {
    System.out.println("空顺序表,无法删除");
    return;
   }
   for (int i = 0; i < size - 1; i++) {
    array[i] = array[i + 1];
   }
   array[--size] = 0;
  } 
  public void popBack() {
   if (size == 0) {
    System.out.println("空顺序表,无法删除");
    return;
   }
   array[--size] = 0;
  }  
  public void erase(int index) {
   if (size == 0) {
    System.out.println("空顺序表,无法删除");
    return;
   }
  }  
  // 查找
  public int indexOf(int element) {
   for (int i = 0; i < size; i++) {
    if (array[i] == element) {
     return i;
    }
   }   
   return -1;
  }  
  // 根据下标,获取元素
  public int get(int index) {
   if (index < 0 || index >= size) {
    System.out.println("下标错误");
    return -1;
   }
   return array[index];
  } //[java]顺序表的头插,尾插,头删,尾删,中间插入,删除元素
  // 给定下标,修改下标所在元素的值
  public void set(int index, int element) {
   array[index] = element;
  } 
  public int size() {
   return size;
  }  
  public boolean isEmpty() {
   return size == 0;
  }  
  public int capacity() {
   return array.length;
  }  
  // 便于打印,显示顺序表中已有元素
  public String toString() {
   return Arrays.toString(
    Arrays.copyOf(array, size)
   );
 }  
 // O(n)
  public void remove(int element) {
   int index = indexOf(element);
   if (index != -1) {
    erase(index);
   }
  }  
  public void removeAll(int element) {
   // 时间:O(n^2) 空间:O(1)
   /*
   int index;
   while ((index = indexOf(element)) != -1) {
    erase(index);
   }
   */   
   /* 时间:O(n) 空间:O(n)
   int[] newArray = new int[size];
   int j = 0;
   for (int i = 0; i < size; i++) {
    if (array[i] != element) {
     newArray[j++] = array[i];
    }
   }  
   // 最后剩下的数一共有 j 个
   // 1. 把数据搬回去 2. 更新 size
   for (int i = 0; i < j; i++) {
    array[i] = newArray[i];
   }
   size = j;
   */ 
   /* 时间:O(n) 空间:O(1)
   */
   int j = 0;
   for (int i = 0; i < size; i++) {
    if (array[i] != element) {
     array[j++] = array[i];
    }
   }
   size = j;
  } 
  // 内部使用的方法
  // 无论是否需要扩容,调用完这个方法,保证容量一定够用
  private void ensureCapacity() {
   if (size < array.length) {
    // 不需要扩容
    return;
   }  
   int newCapacity = array.length + array.length / 2;
   int[] newArray = new int[newCapacity];
   for (int i = 0; i < array.length; i++) {
    newArray[i] = array[i];
   }
   this.array = newArray;  
   } 
    public static void test1(String[] args) {
   SeqList seqList = new SeqList();  
   // []
   System.out.println(seqList.toString());
   // 尾插 1 2 3
   seqList.pushBack(1);
   seqList.pushBack(2);
   seqList.pushBack(3);
   // [ 1, 2, 3 ]
   System.out.println(seqList.toString());  
   // 头插 10 20 30
   seqList.pushFront(10);
   seqList.pushFront(20);
   seqList.pushFront(30);
   // [ 30, 20, 10, 1, 2, 3 ]
   System.out.println(seqList.toString());  
   seqList.insert(2, 100);
   seqList.insert(4, 200);
   // [ 30, 20, 100, 10, 200, 1, 2, 3 ]
   System.out.println(seqList.toString());
   System.out.printf("当前容量: %d%n", seqList.capacity());  
   seqList.pushBack(1000);
   seqList.pushBack(2000);
   seqList.pushBack(3000);
   seqList.pushBack(4000);
   seqList.pushBack(5000);
   seqList.pushBack(6000);
   System.out.printf("当前容量: %d%n", seqList.capacity());
   seqList.popFront();
   seqList.popFront();
   seqList.popFront();
   seqList.popFront();
   // [ 200, 1, 2, 3 ]
   System.out.println(seqList.toString());  
   seqList.popBack();
   seqList.popBack();
   seqList.popBack();
   // [ 200 ]
   System.out.println(seqList.toString());
  } 
  public static void test2(String[] args) {
   SeqList s = new SeqList();
   s.pushBack(1);
   s.pushBack(2);
   s.pushBack(3);
   s.pushBack(4);
   s.pushBack(1);
   s.pushBack(2);
   s.pushBack(3);
   s.pushBack(4);
   // [ 1, 2, 3, 4, 1, 2, 3, 4 ]
   System.out.println(s.toString());
   s.remove(2);
   // [ 1, 3, 4, 1, 2, 3, 4 ]
   System.out.println(s.toString());
   s.removeAll(4);
   // [ 1, 3, 1, 2, 3 ]
   System.out.println(s.toString());
  }  
  public static void main(String[] args) {
   test1(args);
   test2(args);
  }
}

在这里插入图片描述
在这里插入图片描述

  • 7
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
链表是一种常见的数据结构,其中每个节点包含一个数据部分和一个指向下一个节点的指针部分。链表通常通过指针连接起来,形成一个链式结构。对于链表的插入操作,常见的有法和法两种方法。 法是将新节点插入链表的部,也就是成为新的结点,如下面的代码所示: ```c typedef struct node { int data; struct node *next; } Node; // 法 void insert_head(Node **head, int data) { Node *new_node = (Node*)malloc(sizeof(Node)); // 创建新节点 new_node->data = data; // 将数据复制到节点中 new_node->next = *head; // 将新节点的next指针指向原结点 *head = new_node; // 将新节点设置为新的结点 } ``` 法是将新节点插入链表的部,也就是成为新的结点,如下面的代码所示: ```c // 法 void insert_tail(Node **head, int data) { Node *new_node = (Node*)malloc(sizeof(Node)); // 创建新节点 new_node->data = data; // 将数据复制到节点中 new_node->next = NULL; // 将新节点的next指针设置为NULL if (*head == NULL) { // 如果链表为空 *head = new_node; // 新节点成为结点 } else { // 如果链表不为空 Node *p = *head; while (p->next != NULL) { // 遍历链表,找到最后一个节点 p = p->next; } p->next = new_node; // 将新节点插入到链表末 } } ``` 以上两个函数中,都使用了双重指针来修改结点指针的值。在法中,我们将新节点的next指针指向原结点,再将新节点设置为新的结点;在法中,我们遍历链表找到最后一个节点,然后将新节点插入到末。 当然,以上两种方法都有各自的优缺点,需要根据具体情况来选择使用哪种方法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值