提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
关于数组,链表,的简单结构讲解
配以与jdk中的LinkedList,ArrayList的比较
前言
关于数组和链表
什么是数组?
在数组中,每一个数组都有一个地址,同时可以通过数组的下标方便的算出每个元素的内存地址,从而实现快速访问和赋值。如果我们要查询数组中指定位置的元素,我们可以通过数组名[索引]来获取,比如图中的scores[2]
在数组的插入和删除中,如果是在数组尾部插入或删除一个元素则可以直接进行,但如果在其他位置插入或者删除则需要调整其他元素的位置,比如你删除数组的第一个元素之后,需要把后面的所有元素都往前移动一位。声明Java数组时,会在内存中开辟一块连续指定大小的空间,用来存储固定大小的同类型元素。
什么是链表?
链表是一种物理存储上非连续、非顺序的存储结构。数据元素的逻辑顺序是通过链表中的指针链接次序实现的。就好比是班里的同学的学号、每个同学上课所坐的位置坑都不是固定的,但是通过他们之间学号的连续性,通过1号可以找到2号同学,链表就是这样,不仅存储了数值,还存储着下一个元素的地址
ArrayList 类是一个可以动态修改的数组,与普通数组的区别就是它是没有固定大小的限制,我们可以添加或删除元素。
ArrayList 继承了 AbstractList ,并实现了 List 接口
LinkedList类是一个继承于AbstractSequentialList的双向链表。它也可以被当作堆栈、队列或双端队列进行操作
一、数组实现队列的增删改查
代码如下(示例):
public class Demoarr {
//数组
private int[] arr;
//数组有效的大小
private int size;
public Demo01() {
arr=new int[100];
}
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
public Demo01(int max) {
arr=new int[max];
}
//数组的插入
public void insert(int value) {
arr[size]=value;
size++;
}
//数组的查找
public int find(int findKey) {
for(int i =0 ;i<size;i++) {
if(arr[i]==findKey) {
return i;
}
}
return -1;
}
//数组的删除
public void delete(int deleteKey) {
int i = find(deleteKey);
if(i == -1) {
System.out.println("您要删除的值不存在,或者已经删除");
}else {
for(int j=i;j<size;j++) {
arr[j]=arr[j+1];
}
}
}
//数组的修改
public void update(int oldKey,int newKey) {
int i = find(oldKey);
if(i==-1) {
System.out.println("该值不存在,无法更新");
}else {
arr[i]=newKey;
}
}
//显示数组中的所有元素
public void disPlay() {
for(int i =0;i<size;i++) {
System.out.print(arr[i]+" ");
}
System.out.println();
}
}
而引用ArrayList后实现队列会变得更加方便快捷
代码如下:
public static void main(String[] args) {
//增加
ArrayList list= new ArrayList();
list.add("gc1");
list.add(" gc2");
list.add(2, "gc3");
System.out.println(list);
ArrayList sublist = new ArrayList();
sublist.add(" w1");
sublist.add(" w2");
list.addAll(1, sublist);
System.out.println(list);
//删除指定元素
list.remove("w1");
System.out.println(list);
//根据索引删除
list.remove(2);
list.remove(2);
System.out.println(list);
//批量删除
list.removeAll(sublist);
System.out.println(list);
//修改
list.set(0, "zz");
System.out.println(list);
//查看
ArrayList li = new ArrayList();
li.add("rgc");
li.add("hhh");
li.add("ccp");
li.add("gcd");
list.addAll(li);
list.add("123");
//根据索引查看
System.out.println(list.get(1));
System.out.println(list);-=0
}
二、链表实现队列的增删改查
下面主要说一下单链表的增删改查的实现方式以及用Java实现单链表的增删改查功能
//实现单链表的增、删、插
class NodeManager {
private Node root; // 根节点
private int currentIndex = 0; // 节点的序号,每次操作从0开始
public void add(int data) {
if ( root == null ) {
root = new Node(data);
} else {
root.addNode(data);
}
}
public void delNode(int data) {
if ( root == null ) return ;
if ( root.getData() == data ) {
Node tmp = root;
root = root.next;
tmp = null;
} else {
root.delNode(data);
}
}
public void print() {
if ( root != null ) {
System.out.print(root.getData() + " ");
root.printNode();
System.out.println();
}
}
public boolean findNode(int data) {
if ( root == null ) return false;
if ( root.getData() == data ) {
return true;
} else {
return root.findNode(data);
}
}
public boolean updateNode(int oldData, int newData) {
if ( root == null ) return false;
if ( root.getData() == oldData ) {
root.setData(newData);
return true;
} else {
return root.updateNode(oldData, newData);
}
}
// 向索引之前插入
public void insert(int index, int data) {
if ( index < 0 ) return ;
currentIndex = 0;
if ( index == currentIndex ) {
Node newNode = new Node(data);
newNode.next = root;
root = newNode;
} else {
root.insertNode(index, data);
}
}
// 谁拥有数据,谁提供方法
class Node {
private int data;
private Node next; // 把当前类型作为属性
public Node(int data) {
this.data = data;
}
public void setData(int data) {
this.data = data;
}
public int getData() {
return data;
}
// 添加节点
public void addNode(int data) {
if ( this.next == null ) {
this.next = new Node(data);
} else {
this.next.addNode(data);
}
}
// 删除节点
public void delNode(int data) {
if ( this.next != null ) {
if ( this.next.getData() == data ) {
Node tmp = this.next;
this.next = this.next.next;
tmp = null;
} else {
this.next.delNode(data);
}
}
}
// 输出所有节点
public void printNode() {
if ( this.next != null ) {
System.out.print(this.next.getData() + " ");
this.next.printNode();
}
}
// 查找节点是否存在
public boolean findNode(int data) {
if ( this.next != null ) {
if ( this.next.getData() == data ) {
return true;
} else {
return this.next.findNode(data);
}
}
return false;
}
// 修改节点
public boolean updateNode(int oldData, int newData) {
if ( this.next != null ) {
if ( this.next.getData() == oldData ) {
this.next.setData(newData);
return true;
} else {
return this.next.updateNode(oldData, newData);
}
}
return false;
}
// 插入节点
public void insertNode(int index, int data) {
currentIndex ++;
if ( index == currentIndex ) {
Node newNode = new Node(data);
newNode.next = this.next;
this.next = newNode;
} else {
this.next.insertNode(index, data);
}
}
}
}
总结
总结:LinkedList的链表结构导致查询比较慢,但是新增和删除的话效率是比较高的,因为只涉及到指向节点的指针的改变,不需要像ArrayList那样需要对数组位置的变动。链表和数组的差异决定了它们的不同使用场景,如果需要很多对数据的访问,则适合使用数组;如果需要对数据进行很多移位操作,则设和使用链表。