数组:是将元素在内存中连续存储的;它的优点:因为数据是连续存储的,内存地址连续,所以在查找数据的时候效率比较高;它的缺点:在存储之前,我们需要申请一块连续的内存空间,并且在编译的时候就必须确定好它的空间的大小。在运行的时候空间的大小是无法随着你的需要进行增加和减少而改变的,当数据两比较大的时候,有可能会出现越界的情况,数据比较小的时候,又有可能会浪费掉内存空间。在改变数据个数时,增加、插入、删除数据效率比较低。
链表:是动态申请内存空间,不需要像数组需要提前申请好内存的大小,链表只需在用的时候申请就可以,根据需要来动态申请或者删除内存空间,对于数据增加和删除以及插入比数组灵活。还有就是链表中数据在内存中可以在任意的位置,通过应用来关联数据(就是通过存在元素的指针来联系)。
数组和链表就拿增加数据来说,数组中增加一个元素,需要移动大量的元素,在内存中空出一个元素的空间,然后将增加的元素放到空出的空间中;而链表就是将链表中最后的一个元素的指针指向新增的元素,在指出新增元素是尾元素就好了。
数组应用场景:
1、数据比较少;
2、经常做的运算是按序号访问数据元素;
3、数组更容易实现,任何高级语言都支持;
4、构建的线性表较稳定。
/**
* 自定义长度可变的数组[存放字符串]
* @author Administrator
*/
public class my {
// 定义一个长度为0的初始数组
private String[] src = new String[0];
/**
* 存放数据
* @param s 要存放的数据
*/
public void add(String s) {
// 定义一个新数组长度是源数组长度+1
String[] dest = new String[src.length + 1];
// 将原数组的数据拷贝到新数组中
System.arraycopy(src, 0, dest, 0, src.length);
// 将新数据放到新数组的最后一个位置
dest[dest.length - 1] = s;
// 将原数组指向新数组
src = dest;
}
/**
* 取出数据
* @param index 要取出的数据的下标
*/
public String get(int index) {
String s = src[index];
return s;
}
/**
* 根据下标删除数据
* @param index要删除的数据的下标
*/
public void delete(int index) {
String[] dest=new String[src.length-1];
//将下标小于index的拷贝到新数组对应的下标
System.arraycopy(src,0,dest,0,index);
//将下标大于index的拷贝到新数组下标的位置为原数组的下标位置-1
System.arraycopy(src,index+1,dest,index,src.length-index-1);
//将src指向新数组
src=dest;
}
/**
* 删除指定的数据
* @param s要删除的数据,如果有重复的数据,就删除下标最小的
*/
public void delete(String s) {
int t=-1;
for(int i=0;i<src.length;i++){
if(s.equals(src[i])){
t=i;
break;
}
}
//如果s在数组中出现过,t一定是大于等于0的
if(t>=0){
delete(t);
}
}
/**
* 将数据插入到指定位置
* @param index 要插入的位置
* @param s 要插入的数据
*/
public void insert(int index,String s){
String[] dest = new String[src.length+1];
//将新数据放到新数组指定的位置
dest[index]=s;
//将下标小于index的数据拷贝到新数组对应的下标位置
System.arraycopy(src,0,dest,0,index);
//将下标大于等于index的数据拷贝到 新数组下标+1的位置
System.arraycopy(src, index, dest,index+1, src.length-index);
src=dest;
}
/**
* 修改数据
* @param index要修改的数据的下标
* @param s修改后的数据
*/
public void update(int index, String s) {
src[index] = s;
}
/**
* 获得数据个数
*/
public int size() {
return src.length;
}
}
/**
* 自定义长度可变数组的测试类
*
* @author Administrator
*
*/
public static void main(String[] args) {
// 创建数组对象
my arr = new my();
// 增加数据
arr.add("AA");
arr.add("BB");
arr.add("CC");
arr.add("DD");
arr.add("EE");
arr.add("FF");
//根据下标删除数据
arr.delete(3);
//删除指定的数据
arr.delete("BB");
//将数据插入到指定位置
arr.insert(0,"on");
//修改数据
arr.update(2, "up");
//获得数据个数
arr.size();
// 取出数据
for (int i = 0; i < arr.size(); i++) {
String s = arr.get(i);
System.out.println(s);
}
}
}
//结果
// on
// AA
// up
// EE
// FF
链表应用场景:
1、对线性表的长度或者规模难以估计;
2、可以频繁做插入删除操作;
3、构建动态性比较强的线性表。
/**
* 自定义链表类【双向链表】
*
* @author Administrator
*
*/
public class MyLinkList<E> {
// 初始状态下,链表没有任何结点,头结点为null,尾结点为null
private Node<E> head = null;
private Node<E> last = null;
private int num = 0;// 数据个数
// 增加数据
public void add(E e) {
// 根据数据创建结点对象
Node<E> node = new Node<E>(e);
// 如果链表中已经有结点,就将node作为last的下一个结点
if (last != null) {
last.next = node;
node.front = last;
last = node;
} else {
// 如果链表中还没有结点,node就是第一个结点
// 既是头结点,又是尾结点
head = node;
last = node;
}
num++;
}
//插入数据
public void insert(int index, E e) {
// 创建新结点
Node<E> node = new Node<E>(e);
// 找到index位置的结点
Node<E> n1 = getNode(index);
// 找到n1的前一个结点
Node<E> n2 = n1.front;
n2.next = node;
node.front = n2;
node.next = n1;
n1.front = node;
num++;
}
public void delete(int index) {
}
public void delete(E e) {
}
public void update(int index, E e) {
Node<E> n1 = getNode(index);
n1.data = e;
}
public E get(int index) {
Node<E> node = getNode(index);
return node.data;
}
//根据内容确定下标
private int getIndex(E e){
int index=-1;
Node<E> n = head;
while(n!=null){
index++;
if(n.data.equals(e)){
break;
}
n=n.next;
}
return index;
}
public int getIndex2(E e){
for(int i=0;i<num;i++){
E e2 = get(i);
if(e2.equals(e)){
return i;
}
}
return -1;
}
//根据下标确定结点
private Node<E> getNode(int index) {
int t = -1;
if (index >= 0 && index < num) {
Node<E> n = head;
while (n != null) {
t++;
if (t == index) {
break;
}
n = n.next;
}
return n;
} else {
// 抛出异常
throw new IndexOutOfBoundsException("下标超出边界!index:" + index
+ ",size:" + num);
}
}
public int size() {
return num;
}
}
// 内部的结点类,主要为MyLinkList类服务
class Node<E> {
// 结点的数据
E data;
// 对下一个结点的引用
Node<E> next;
// 对前一个结点的引用
Node<E> front;
// 创建结点对象的时候必须指定数据
public Node(E e) {
data = e;
}
}
public class Main {
public static void main(String[] args){
myLinkList<String> mm=new myLinkList<String>();
mm.add("AA");
mm.add("BB");
mm.add("CC");
mm.add("DD");
mm.add("EE");
mm.insert(2,"链");
mm.update(3, "表");
for(int i=0;i<mm.size();i++){
String s=mm.get(i);
System.out.println(s);
}
}
}
//结果
// AA
// BB
// 链
// 表
// DD
// EE
分享到:
相关推荐
Java 数组链表效率对比 Java 中的数组和链表是两种常用的数据结构,它们都可以用来存储和操作数据。然而,在实际开发中,选择合适的数据结构和遍历方式对程序的性能和效率有着非常重要的影响。下面我们将对 Java 中...
本篇文章将深入探讨如何使用Java数组来模拟实现链表数据结构,以此来增强对链表理解的同时,也能看到数组在特殊场景下的运用。 链表是由一系列节点(或称为元素)组成的线性数据结构,每个节点包含数据和指向下一个...
Java中的数组和链表是两种常见的线性数据结构,各有优缺点,适用于不同的场景。下面我们将详细探讨这两种数据结构的区别。 **数组(Array)** 数组是一种在内存中连续存储相同类型元素的数据结构。它的主要特点...
数组、链表和集合的区别和应用场景以及堆和栈的区别 数组和集合的区别: 1. 数组的长度是固定的,而集合的长度是动态不固定的。 2. 数组的存储类型是单一的,同一个数组只能存储同一数据类型的数据,而集合可以...
总之,Java中的动态数组链表,如ArrayList,提供了灵活的数据存储和操作方式,适用于需要频繁访问元素但对插入和删除速度要求不是特别高的场景。理解并熟练掌握ArrayList的使用和内部机制对于提升Java编程能力至关...
Java集合,HashMap底层实现和原理(1.7数组+链表与1.8+的数组+链表+红黑树) 在Java集合中,HashMap是一个常用的数据结构,它基于Map接口实现,元素以键值对的方式存储,并且允许使用null键和null值。由于key不允许...
在Java编程中,数据结构是基础,而数组和链表是两种常见的线性数据结构。它们各有特点,适用于不同的场景。下面将详细讨论这两种数据结构的区别。 首先,数组是一种静态分配内存的数据结构,其所有元素在内存中是...
"数组和链表" 数组和链表是两种常见的线性数据结构,它们都是由具有相同类型的n(n≥0)个数据元素组成的有限序列。...数组和链表是两种常见的线性数据结构,它们各自的优缺点,选择哪种数据结构取决于具体的应用场景。
总之,Java中的栈可以通过数组或链表两种方式实现,每种实现都有其优势和适用场景。选择哪种实现取决于具体的应用需求,如内存使用、插入删除效率等因素。在实际编程中,可以根据具体问题来决定采用哪种数据结构实现...
Java 中链表和数组的区别 Java 中链表和数组都是数据结构,但它们有着本质的差异。在这篇文章中,我们将探讨链表和数组的区别,並探讨它们各自的特点、优缺点和应用场景。 数组 数组是一种线性结构,可以直接索引...
### JavaSE中的数组集合与链表...通过上述分析,我们可以清楚地看到链表集合相较于数组集合的优势所在,特别是在频繁插入和删除操作的场景中。链表集合提供了一种更为灵活的数据管理方式,能够有效提高程序的运行效率。
本压缩包文件"数组的扩容和链表结构.zip"包含了关于Java数组扩容和链表结构存储的相关知识点,我们将详细探讨这两个主题。 首先,我们来看Java数组。数组是一种线性数据结构,它在内存中连续存储相同类型的数据元素...
在Java等编程语言中,ArrayList和LinkedList分别是基于数组和链表实现的集合类。ArrayList本质上是动态数组,查询速度快,但插入和删除慢,且线程不安全。LinkedList作为链表实现,查询慢但增删快,同样线程不安全。...
Java数组堆栈是指使用Java编程语言实现的基于数组的堆栈数据结构。该数据结构提供了基本的堆栈操作,如push、pop、peek、isEmpty、exist等方法。下面是对Java数组堆栈的详细解释。 标题: Java数组堆栈 描述: 文章...
数组、链表和哈希表是计算机科学中最基础且重要的数据结构,它们各自有独特的优点和应用场景。在处理数据存储和检索时,选择合适的数据结构至关重要。 数组是一种线性数据结构,它在内存中占用连续的空间,每个元素...
2. 在Java中使用数组和集合有什么不同的场景和优缺点? 3. 如何选择使用ArrayList还是LinkedList? 4. Set集合如何保证元素的唯一性? 5. Map接口的实现类有什么区别,以及各自的应用场景是什么? 6. 在多线程环境下...
本压缩包"基于JAVA实现的常用数据结构代码"包含了多个关键的数据结构实现,包括复杂度分析、动态数组、链表、栈、队列以及二叉搜索树。以下是这些数据结构的详细说明: 1. **复杂度**:在计算机科学中,复杂度分为...
在Java中,我们通常使用数组或链表来实现线性表。本话题聚焦于使用动态数组来实现线性表,这是一种常见的数据结构实现方式,因为它既保留了数组的高效访问特性,又能灵活地调整大小以适应数据的变化。 动态数组,也...
下面我们将深入探讨Java数组的基础知识、类和接口的概念,以及有序数组的实现。 1. **Java中数组的基础知识** - **数组的声明与初始化**:声明一个数组需要指定其类型,例如`int[] intArray`,然后通过`new`操作符...
在OpenJDK或其他Java实现中,我们可以看到ArrayList是如何管理其内部数组,以及如何执行扩容和元素操作的详细步骤。这有助于我们优化代码,比如避免在循环中进行可能导致扩容的操作,以提高性能。 总结来说,Java中...