链表中顺序表和单链表的区别
存储分配方式的不同
顺序表
- 一段连续的存储单元一次存储线性表的数据元素
- 顺序表代码的实现,其本质就是一个数组和最大容量(也就是数组的长度)以及现有的长度。当我们每存储进一个数据的时候,他的现有长度增加,当增加到最大的容量的时候,我们就需要给顺序表扩容。
- 我们很难把顺序表的空间容量全部利用。
- 与单链表相比它无须为表中元素之间的逻辑关系增加额外的存储空间
单链表
1. 采用的链式存储结构,用一组任意的存储单元存放线性表
2. 就是我们添加了一个引用,这个引用中存放了下一个数据的地址,从而把这些数据从逻辑上串联起来
3. 也就是我们可以利用到所用的空间来存放数据,但是需要为数据之间的逻辑关系增加额外的空间开销
时间性能
- 查找一个数 顺序表的时间复杂度为 O(1) ; 单链表的时间复杂度为 O(n)
- 插入和删除 (都为O(n)) 但顺序表因为在插入一个数或删除一个数后要移动大量的数据而导致的时间复杂度为O(n), 而单链表在找出某位值的引用之时花费了O(n)的时间复杂度,而插入位置和删除这个数的时间复杂仅为O(1);
空间性能
- 顺序表的顺序结构需要预分配存储空间,容易发生浪费空间和数据溢满的情况
- 单链表不需要分配存储空间结构,只要有就可以分配,元素个数也不受限制,但是它每一个节点都需要增加一点空间开销来保证链表的逻辑结构。
代码
自己写的顺序表代码
package myArrayList;
import java.util.Arrays;
public class MyArrayList {
private int[] array = new int[20];
private int size = 0;
public int[] getArray() {
return array;
}
public void setArray(int[] array) {
this.array = array;
}
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
public void prin() {
if (size == 0) {
return;
}
for (int i = 0; i < size; i++) {
System.out.print(array[i] + " ");
}
}
//尾插
public boolean add (int num) {
//size 从0开始计数 size等于19的时候 array.length已经等于20了
if (this.size >= array.length - 1) {
return false;
}
array[size] = num;
size++;
return true;
}
//在指定位置插入 一个数
public void add (int index, int num) {
if (this.size >= array.length - 1) {
return;
}
if (index >= array.length - 1) {
return;
}
if (index >= size) {
array[size] = num;
size++;
return;
}
for (int i = size; i > index - 1; i--) {
array[i] = array[i-1];
}
array[index - 1] = num;
size++;
}
//移除一个数
public int removeNum(int x) {
for (int i = 0; i <= size; i++) {
if (array[i] == x) {
for (int j = i; j < size; j++) {
array[j] = array[j+1];
}
size--;
return x;
}
}
return -1;
}
//移除某个位置上的数
public boolean remove(int index) {
if (index > size) {
return false;
}
if (index < 1) {
return false;
}
if (index == size) {
array[size] = 0;
size--;
return true;
}
for (int i = index - 1; i < size; i++) {
array[i] = array[i+1];
}
size--;
return true;
}
//获取 index下标下的数
public int get(int index) {
if (index > size || index < 0) {
return -1;
}
return array[index - 1];
}
//将index下标位置的数设为element
public int set (int index, int element) {
if (index < 1 || index > size) {
return -1;
}
array[index - 1] = element;
return array[index - 1];
}
// 包含某个数
public boolean contains(int x) {
for (int i = 0; i < size; i++) {
if (array[i] == x) {
return true;
}
}
return false;
}
// 返回找到的第一个数的下标
public int indexOf(int element) {
for (int i = 0; i < size; i++) {
if (array[i] == element) {
return i + 1;
}
}
return -1;
}
// 返回最后一个这个数的下标
public int lastIndexOf(int element) {
for (int i = size -1; i > 0 ; i--) {
if ( array[i] == element) {
return i+1;
}
}
return -1;
}
//清空
public void clear () {
size = 0;
}
// 获取长度
public int length() {
return size;
}
}
自己写的单链表代码
package myLinkedList;
class Node {
public int val; // 存储的值
public Node next; // 存放的下一个节点
public Node(int val) {
this.val = val;
}
}
public class MyLinkedList {
// 头节点
private Node head = null;
private int size = 0;
//头插法
public void add (int val) {
if (this.head == null) {
this.head = new Node(val);
this.size++;
return;
}
Node node = new Node(val);
//头插法
node.next = this.head;
this.head = node;
this.size++;
}
//向表中间的插入一个数
public void insertNum(int index, int num) {
// index 不符合条件 插入失败
// size 的话 无法为插
// size 加1的话 可以将这个数字插入尾部
if (index > size + 1 || index < 0) {
return;
}
Node node = new Node(num);
Node cur = this.head;
Node pre = null;
int i = 1;
while (cur != null && i < index) {
pre = cur;
cur = cur.next;
i++;
}
// index == 1 时候
if (pre == null) {
node.next = this.head;
this.head = node;
this.size++;
return;
}
// 其他时候
pre.next = node;
node.next = cur;
this.size++;
}
//删除一个数
public boolean remove(int num) {
Node cur = this.head;
Node pre = null;
while (cur != null) {
if (cur.val == num) {
if (pre == null) {
this.head = this.head.next;
} else {
pre.next = cur.next;
}
this.size--;
return true;
}
pre = cur;
cur = cur.next;
}
return false;
}
public void clear() {
this.head = null;
this.size = 0;
}
public int length() {
return this.size;
}
public void prin() {
Node cur = this.head;
for (int i = 0; i < size; i++) {
System.out.print(cur.val + " ");
cur = cur.next;
}
}
}