- 浏览: 342844 次
- 性别:
- 来自: 上海
-
文章分类
最新评论
-
alafqq:
很好的一篇启蒙hashmap的文章;HASHTABLE的93行 ...
使用数组和链表实现hash表存储信息 -
小帅1127:
我擦,我还以为有什么大坑呢,这也写出来。。。
if..else if和if..if的区别 -
fncj:
转下http://www.dodoer.com
hadoop单机版搭建图文详解 -
yueshang520:
Spring注解原理的详细剖析与实现 -
fncj:
转下,谢谢http://www.whohelpme.com/b ...
Spring注解原理的详细剖析与实现
1、定义
数组又叫做顺序表,顺序表是在内存中开辟一段连续的空间来存储数据,数组可以处理一组数据类型相同的数据,但不允许动态定义数组的大小,即在使用数组之前必须确定数组的大小。而在实际应用中,用户使用数组之前有时无法准确确定数组的大小,只能将数组定义成足够大小,这样数组中有些空间可能不被使用,从而造成内存空间的浪费。
链表是一种常见的数据组织形式,它采用动态分配内存的形式实现。链表是靠指针来连接多块不连续的的空间,在逻辑上形成一片连续的空间来存储数据。需要时可以用new分配内存空间,不需要时用delete将已分配的空间释放,不会造成内存空间的浪费。
2、二者区分:
A 从逻辑结构来看
A-1. 数组必须事先定义固定的长度(元素个数),不能适应数据动态地增减的情况。当数据增加时,可能超出原先定义的元素个数;当数据减少时,造成内存浪费。
A-2. 链表动态地进行存储分配,可以适应数据动态地增减的情况,且可以方便地插入、删除数据项。(数组中插入、删除数据项时,需要移动其它数据项)
B 从内存存储来看
B-1. (静态)数组从栈中分配空间, 对于程序员方便快速,但是自由度小
B-2. 链表从堆中分配空间, 自由度大但是申请管理比较麻烦.
数组在内存中开辟连续的一块区域,如果一个数据要两个内存单元,一组5个数据10个单元就够了,无需标记其地址,因为数组定义时候标顶了第一个原始的地址,其他四个都知道了。
链表可可以是连续的,也可以是不连续的,但一般都是不连续的,一链5个数据,如果每个数据本身用2个内存单元,那么10个单元是不够的,因为每个数据都要表示出下个数据在哪里,所以一个数据本身用2个单元,再用1个单元表示此链下一个数据在什么地址。
C从访问顺序来看
数组中的数据在内存中的按顺序存储的,而链表是随机存储的!
C-1.要访问数组中的元素可以按下标索引来访问,速度比较快,如果对他进行插入操作的话,就得移动很多元素,所以对数组进行插入操作效率很低!
C-2.由于链表表是随机存储的,链表在插入,删除操作上有很高的效率(相对数组),如果要访问链表中的某个元素的话,那就得从链表的头逐个遍历,直到找到所需要的元素为止,所以链表的随机访问的效率就比数组要低
3、分别用数组和链表实现队列:
3-1数组实现
public class Queue <E>{ //每次放入队列的元素的个数 private int initLen=0; //每次增长的队列空间的大小 private int increaseLen=0; private Object[] src; //己放入对象的个数 private int count=0; public Queue(int initLen,int increaseLen){ this.initLen=initLen; this.increaseLen=increaseLen; src = new Object[initLen]; } public Queue(int initLen){ this(initLen,initLen/2); } public Queue(){ this(20,10); } /** * 在末尾向队列中增加一个字符串 * @param s:向队列中增加的字符串 */ public void add(E e){ src[count]=e; count++; if(count>=initLen){ //新建数组,是原数组长度的length+1 Object[] temp=new Object[src.length +increaseLen]; //将原数组中的复制到新数组中 for(int i=0;i<count;i++) { temp[i]=src[i]; } src=temp; } } /** * 在指定位置向队列中增加一个字符串s * @param s 向队列中增加的字符串 * @param index 队列中指定的位置 */ public void add(E e,int index){ if(count>=initLen){ //新建数组,是原数组长度的length+increaseLen Object[] temp=new Object[src.length +increaseLen]; //将原数组中的复制到新数组中 for(int i=0;i<count;i++) { temp[i]=src[i]; } //新数组赋值给原数组 src=temp; } //将原数组从index处的元素向后以一位 for(int i=count;i>index;i--) { src[i]=src[i-1]; } //将s添加到新数组中指定位置 src[index]=e; } /** * 得到队列中指定位置的字符串 * @param index 队列中指定的位置 * @return 返回指定位置的字符串 */ public E get(int index){ if(index>=0&&index<=count){ return (E)src[index]; } else return null; } /** * 返回当前字符串的位置 * @param s当前字符串 * @return 当前字符串的位置 */ public int getPos(E e){ int temp=-1; for(int i=0;i<count;i++){ if(e.equals(src[i])){ temp=i; break; } } //System.out.println("位置是:"+temp); if(temp==-1) System.out.println("队列中没有与 \""+e+"\" 匹配的字符串!"); return temp; } /** * 得到队列中字符串的长度即大小 * @return 返回的是字符串的大小 */ public int size(){ return count; } /** * 删除队列中指定位置的字符串 * @param index 要删除字符串的位置 * @return 返回锁删除的字符串 */ public E delete(int index){ //System.out.println("字符串的长度为"+src.length); //新建数组,是原数组长度的length+1 Object[] temp=new Object[count-1]; E e; //将原数组index前的元素复制到新数组中 for(int i=0;i<index;i++) { temp[i]=src[i]; } e=(E)src[index]; //将原数组index后的元素复制到新数组中 for(int i=index+1;i<count;i++) { temp[i-1]=src[i]; } //新数组赋值给原数组 src=temp; count--; //System.out.println("字符串的长度为"+src.length); return e; } /** * 删除指定的字符串 * @param s要删除的字符串 * @return TRUE删除成功 FALSE删除失败 */ public Boolean delete(E e){ int temp=-1; for(int i=0;i<count;i++){ if(e.equals(src[i])){ temp=1; break; } } if(temp!=-1)return true; return false; } /** * 替换队列中指定位置的字符串 * @param s新的字符串 * @param index要更新字符串的位置 * @return */ public Boolean replace(E e,int index){ if(index>count){ System.out.println("长度超出!!"); return false; } E temp; temp=(E)src[index]; src[index]=e; e=temp; return true; } }
3-2链表实现
public class Node<E> { public E Elem; public Node<E> next; public Node(E elem){ Elem=elem; } public String toString(){ return Elem.toString(); } } public class LinkQueueDemo <E>{ public Node head=null; public Node tail=null; /** * 在末尾向队列中增加一个节点 * @param s:向队列中增加的字符串 */ public void add(E elem){ if(head==null){ head=new Node(elem); tail=head; }else{ tail.next=new Node(elem); tail=tail.next; } //System.out.println("插入的Node是:"+elem); } /** * 得到队列中指定位置的字符串 * @param index 队列中指定的位置 * @return 返回指定位置的字符串 */ public Node get(int index){ Node temp=head; int count=0; if(index>this.size()){ System.out.println("index is out of the size:"+this.size()); return null; }else if(temp==null){ System.out.println("queue is empty;"); return null; }else{ while(count!=index){ count++; temp=temp.next; } return temp; } } /** * 返回当前节点的位置 * @param s当前字符串 * @return 当前字符串的位置 */ public int getPos(E e){ Node temp=head; Node query_Node=new Node(e); int count=0; if(temp==null){ System.out.println("queue is empty;"); return -1; }else{ while(temp.Elem!=query_Node.Elem&&temp.next!=null){ count++; temp=temp.next; } if(temp.next==null){ System.out.println("there is no such Node"); return -1; } return count; } } /** * 得到队列中字符串的长度即大小 * @return 返回的是字符串的大小 */ public int size(){ int len=0; Node temp=head; if(head==null) return 0; while(temp!=null){ len++; temp=temp.next; } return len; } /** * 删除队列中指定位置的字符串 * @param index 要删除字符串的位置 * @return 返回锁删除的字符串 */ public Node delete(int index){ Node temp=head; Node pretem=temp; int count=0; if(index>this.size()){ System.out.println("index is out of the size:"+this.size()); return null; }else if(temp==null){ System.out.println("queue is empty;"); return null; }else{ while(count!=index){ count++; pretem=temp; temp=temp.next; } pretem.next=temp.next; } return temp; } /** * 删除队列中第一个Node * @return 返回锁删除的node */ public Node delete(){ Node temp=head; if(temp==null){ System.out.println("the queue is empty!"); return null; }else{ if(head.next!=null){ head=head.next; } else{ head=null; } return temp; } } /** * 删除指定的字符串 * @param s要删除的字符串 * @return TRUE删除成功 FALSE删除失败 */ public Boolean delete(E e){ return false; } /** * 替换队列中指定位置的字符串 * @param s新的字符串 * @param index要更新字符串的位置 * @return */ public Boolean update(E e,int index){ Node temp=head; int count=0; if(index>this.size()){ System.out.println("index is out of the size:"+this.size()); return false; }else if(temp==null){ System.out.println("queue is empty;"); return false; }else{ while(count!=index){ count++; temp=temp.next; } temp.Elem=e; } return true; } public void printQueue(){ Node temp=head; int count=0; while(temp!=null){ System.out.println(count+":"+temp+" "); temp=temp.next; count++; } } }
评论
嗯,确实,这点我没有考虑到,这个内部定义会更好一些
public Queue(int initLen,int increaseLen){ 12. this.initLen=initLen; 13. this.increaseLen=increaseLen; 14. src = new Object[initLen]; 15. } 16. 17. public Queue(int initLen){ 18. this(initLen,initLen/2); 19. } public Queue(){ 22. this(20,10); 23. }
你的想法很好,可以让用户自己决定开辟多少空间,也可以由我们自己决定开辟多少空间,我就没想到(惭愧啊!~)。但是我很好奇,为什么你要加上第一个构造函数呢?如果用户输入的需要增加的空间过大,会很浪费资源的。那个要增长的空间长度可以由我们自己定啊!~(个人见解)
发表评论
-
apache日志信息详解
2011-11-06 21:19 6319一、访问日志的格式 Apache内建了记录服务器 ... -
浏览器如何工作
2011-08-19 08:57 0http://taligarsiel.com/Projects ... -
编码实现用JDK中的Proxy实现springAOP功能
2011-08-18 15:04 792http://blog.csdn.net/iamtheevil ... -
Spring注解原理的详细剖析与实现
2011-08-14 23:09 84350本文主要分为三部分: ... -
Spring装配基本属性的原理分析与代码实现
2011-08-11 15:37 1481首先,做一个配置属性的基本测试。修改beans.xml,使引用 ... -
编码剖析Spring依赖注入的原理
2011-08-10 20:01 1868一、注入依赖对象 基本类型对象注入: <b ... -
Spring的三种实例化Bean的方法
2011-08-10 14:03 1Spring的三种实例化Bean的方法 1、 使用 ... -
Spring管理bean的原理自定义实现
2011-08-10 10:44 62441、Spring通过BeanDefinition管理基于S ... -
spring环境搭建与测试
2011-08-10 08:40 3473Chapter1、搭建与测试spring的环境 1、 ... -
java回调机制实现
2011-08-08 09:06 2107Java的接口支持提供了一种获得回调的等价功能的 ... -
log4j的使用与详细分析
2011-08-05 13:32 2693一、什么是log4j? http://logging.a ... -
log4j使用详解
2011-08-04 23:05 2http://logging.apache.org/log4j ... -
java解析XML的四种方法的学习与比较
2011-03-30 20:55 7295四种XML解析方法: ... -
自定义日志模块实现
2011-03-30 09:58 1167package wxy.XXXX.Utils; impo ... -
synchronized(this)
2011-03-29 09:17 70581、当两个并发线程访问同一个对象object中的这个synch ... -
详细解析Java中抽象类和接口的区别(转)
2011-03-24 23:48 976在Java语言中, abstract cl ... -
NIO学习笔记(三)---通道
2011-03-09 23:06 16051、通道基础 ... -
NIO学习笔记(2)--缓冲区
2011-03-09 18:20 9901、一个Buffer对象是固定数量的数据的容器。其作用是 ... -
封锁管理子系统模拟实现java版
2011-03-09 18:01 1247封锁管理子系统模拟实现 文件锁定 ... -
NIO学习笔记(一)I/O缓冲区操作
2011-03-07 20:04 1287上图简单描述了数据从外部磁盘向运行中的进程的内存区域移动的 ...
相关推荐
本话题主要探讨了两种常用的数据结构——数组和链表——在实现队列这一线性数据结构时的应用。队列是一种先进先出(First In First Out, FIFO)的数据结构,它的主要操作包括入队(enqueue)、出队(dequeue)以及...
Python 实现栈和队列 栈和队列是两种常用的数据结构,在编程设计中广泛应用。...本文介绍了如何使用 Python 实现栈和队列,包括使用数组和链表两种方法。栈和队列是两种常用的数据结构,在编程设计中广泛应用。
队列和栈都是描述数据存取方式的概念,它们可以使用数组或链表实现。 队列是一种先进先出(First-In-First-Out,FIFO)的数据结构,元素的添加和删除都是从队列的两端进行的。队列可以使用数组或链表实现,数组实现...
本篇文章将深入探讨如何用数组和链表两种数据结构来实现队列。 ### 数组实现队列 数组实现队列的优势在于访问速度快,因为数组是连续存储的,可以通过下标直接访问元素。但数组的大小是固定的,所以在创建时需要...
总结一下,C++中的循环队列可以通过数组和链表两种方式实现,每种实现都有其特点。数组实现访问速度快,但处理满队列和空队列需要特殊考虑;链表实现插入和删除操作灵活,但访问速度较慢。模板机制使得循环队列可以...
数组、链表、堆栈和队列、线性表和顺序表 数组、链表、堆栈和队列是最基本的数据结构,任何程序都会涉及到其中的一种或多种。数据结构是指数据之间的相互关系,即组织形式,有逻辑结构和物理结构之分。逻辑结构有...
本篇文章主要探讨的是两种基本的数据结构——数组与链表。通过对比它们的特点、优缺点以及适用场景,帮助读者更好地理解何时选择哪种数据结构更为合适。 #### 数组与链表概述 **数组**是一种常见的数据结构,它是...
数组和链表是两种基本的数据结构,它们各自有其适用的场景和特点。在计算机科学中,选择合适的数据结构对于程序的效率和性能至关重要。 数组是一种线性数据结构,它在内存中以连续的方式存储元素。这意味着数组的...
在 Java 中,LinkedList 的内部使用双端链表队列原理实现,而 ArrayList 的内部使用双端数组队列原理实现。 Java 实现自定义双端队列可以通过链表和数组两种方式实现,双端队列可以充当单端队列,也可以用于充当栈...
在计算机科学中,数组和链表是两种最为基本且广泛使用的数据结构,它们承载着计算机存储和处理数据的重任。尽管它们各自拥有不可替代的特性,但其适用场景和性能效率却大相径庭,因此在实际开发过程中,正确选择和...
本文将深入探讨两种队列实现方式:循环链表队列和循环数组队列,并通过代码示例进行详细解析。 #### 循环链表队列 循环链表队列是一种使用链表实现的队列,其中最后一个节点的指针指向第一个节点,形成一个循环。...
在计算机科学中,数据结构是组织、存储和处理数据的方式,它们是算法设计的基础。...在实际编程中,Java提供了ArrayList和LinkedList两种内置的列表实现,分别基于数组和链表,可以根据需要选择使用。
在众多数据结构中,数组和链表是最为基础且常用的两种。它们在存储和处理数据方面呈现出不同的特点,各自拥有独特的优势和局限性,因此在不同的应用场景中扮演着至关重要的角色。下面将对数组和链表进行详细分析,并...
本文主要讲解了C语言中数组和链表的概念及操作,包括数组指定位置插入和删除、链表的结构、静态链表和动态链表、单链表的建立和遍历、双向链表的概念、循环链表的概念等。同时也涉及到了链表的实战应用和拓展思维。 ...
逻辑结构和物理结构是两种不同的概念,逻辑结构是对数据元素之间的关系的抽象描述,而物理结构是对数据元素在存储器中的存储方式的描述。两者都是数据结构的组成部分,但它们是不同的层次,逻辑结构是理论思想,而...
在Java编程中,数据结构是基础,而数组和链表是两种常见的线性数据结构。它们各有特点,适用于不同的场景。下面将详细讨论这两种数据结构的区别。 首先,数组是一种静态分配内存的数据结构,其所有元素在内存中是...
数组和链表作为两种基础的数据结构,它们的特点和使用场景各不相同,深入了解它们的区别与作用对于编程人员至关重要。 数组是一种简单而又强大的数据结构,它在内存中占据一块连续的空间,以顺序的方式存储同一类型...
队列有两种存储形式:链式和循环数组存储。 在哈工大软件设计代码中,队列的实现是使用循环数组存储结构的。该存储结构的实现是使用模板类的方式,定义了一个名为MyQueue的类,包含了队列的基本操作:入队、出队、...
在Java编程语言中,数组和链表是两种基础且重要的数据结构。它们各自有独特的特点和使用场景,尤其是在处理大量数据时,理解它们的工作原理和性能特性至关重要。本压缩包文件"数组的扩容和链表结构.zip"包含了关于...
数组和链表是两种基本的数据结构,它们各自有其独特的优缺点,在不同的场景下有着不同的应用。 数组是一种静态数据结构,它在内存中占据连续的空间,这意味着数组的大小在创建时就已经固定,不能轻易地增加或减少。...