一、数据结构

数据结构由数据和结构两部分组成,就是将数据按照一定的结构组合起来,这样不同的组合方式有不同的效率,可根据需求选择不同的结构应用在相应在场景。数据结构大致

分为两类:线性结构(如数组,链表,队列,栈等),非线性结构(如树,图,表等)。本文介绍下线性结构,下章介绍非线性结构。

二、数组

数组表示一组有限个相同类型的数据的集合,顺序存储,下标从0开始,其特点是可以根据下标快速的查找到元素,但在增加和删除元素时会导致大量的数据位置的变动,即这

种情况下性能不高,故数组一般多用于查找频繁,增,删较少的情况。

下图为一个二维数组的结构图:

插入元素:

当往数组某位置上插入元素时,需要将位置后的所有元素往后移动一个位置。

删除元素:

当删除数组上的某个元素时,需要将该元素后的所有元素的位置往前移动一个位置。

下面简单实现数组中插入元素和删除元素功能:

public class ArrayDemo<T> {

	private Object[] array ;

	private int length = 0;

	private final static int DEFAULT_CAPACITY = 10;

	public ArrayDemo(){
super();
this.array = new Object[DEFAULT_CAPACITY];
this.length = DEFAULT_CAPACITY;
} public ArrayDemo(int length){
super();
if(length < 0){
throw new IllegalArgumentException("error length:"+length);
}
this.array = new Object[length];
this.length = length;
} public ArrayDemo(Collection<? extends T> c){
array = c.toArray();
length = c.size();
if(array.getClass() != Object[].class){
array = Arrays.copyOf(array, length, Object[].class);
}
} /**
* 在数组array的index位置处插入一个元素t,如果已经满了,则移除最后一个元素
* @param array
* @param t
* @param indext
*/
public void insert(T t, int index){
if(null == t){
throw new NullPointerException("null Pointer!");
}
if(index < 0 || index > length-1){
throw new IndexOutOfBoundsException("index is error");
}
for(int pos = length-1; pos>index; pos--){
array[pos] = array[pos-1];
}
array[index] = t;
} /**
* 删除指定位置上的数组元素
* @param array
* @param index
*/
public void delete(int index){
if(null == array){
throw new NullPointerException("null Pointer!");
}
int length = array.length;
if(index < 0 || index > length-1){
throw new IndexOutOfBoundsException("index is error");
}
for(int pos = index; pos < length-1; pos++){
array[pos] = array[pos+1];
}
array[length-1] = null;
} /**
* 遍历输出数组中所有元素
*/
public void trans(){
if(null == array){
throw new NullPointerException("null Pointer!");
}
for(int pos=0; pos< length; pos++){
System.out.println(array[pos]);
}
}
}
public class Person {

	private String name;

	private String sex;

	public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public String getSex() {
return sex;
} public void setSex(String sex) {
this.sex = sex;
} @Override
public String toString() {
return "Person [name=" + name + ", sex=" + sex + "]";
} public Person(String name, String sex) {
super();
this.name = name;
this.sex = sex;
} @Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((sex == null) ? 0 : sex.hashCode());
return result;
} @Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person other = (Person) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (sex == null) {
if (other.sex != null)
return false;
} else if (!sex.equals(other.sex))
return false;
return true;
}
}

测试类:

public class TestArray {

	public static void main(String[] args) {
ArrayDemo<Person> array = new ArrayDemo<>();
Person p = new Person("张三", "m");
array.insert(p, 0);
array.trans();
array.delete(0);
System.out.println("---");
array.trans();
}
}

三、链表

链表是一种有序的列表。链表的内容通常存储在内存中分散的位置上。链表由节点组成,每个节点的结构都是相同的。节点分为数据域和链域,数据域顾名思义,就是存放节点

节点的内容,链域存放的是下一个节点的指针或引用。如果是双向链表的话,链域中还会有前一个节点的指针或引用。下图为单向链表各节点间的关系图。

下面来实现一个简单的链表结构

节点类:

public class Node<T> {

	private T data;

	private Node<T> pre;

	private Node<T> next;

	public Node(){
super();
this.pre = null;
this.next = null;
} public Node(T data){
super();
this.data = data;
this.pre = null;
this.next = null;
} public Node(T data, Node<T> pre, Node<T> next){
super();
this.data = data;
this.pre = pre;
this.next = next;
} public T getData() {
return data;
} public void setData(T data) {
this.data = data;
} public Node<T> getPre() {
return pre;
} public void setPre(Node<T> pre) {
this.pre = pre;
} public Node<T> getNext() {
return next;
} public void setNext(Node<T> next) {
this.next = next;
}
}

链表类

public class LinkedListDemo<T> {

	private Node<T> head;//头结点

	private Node<T> tail;//尾节点

	private int size;//链表大小

	public LinkedListDemo(){
head = new Node<T>(null, null, null);
tail = new Node<T>(null, head, null);
head.setNext(tail);
size = 0;
} public MyIterator<T> iterator(){
return new MyIterator<T>();
} public void add(T data){
Node<T> node = new Node<T>(data);
node.setPre(tail.getPre());
tail.getPre().setNext(node);
tail.setPre(node);
node.setNext(tail);
size++;
} public void remove(T data){
Node<T> node = head;
while(tail != node.getNext()){
Node<T> currentNode = node.getNext();
if(currentNode.getData().equals(data)){
currentNode.getPre().setNext(currentNode.getNext());
currentNode.getNext().setPre(currentNode.getPre());
size--;
break;
}
node = currentNode;
}
} public void print(){
Node<T> node = head;
while(tail != node.getNext()){
Node<T> currentNode = node.getNext();
System.out.println(currentNode.getData().toString());
node = currentNode;
}
} /**
*
* 项目名: adt
* 类名: LinkedListDemo.java
* 类描述: 定义一个该链表的迭代器来访问
* 备注:
* 创建日期:2014-10-10
* 创建时间:上午12:10:46
* @param <T>
*/
@SuppressWarnings("hiding")
private class MyIterator<T> implements Iterator<T>{ @SuppressWarnings("unchecked")
private Node<T> currentNode = (Node<T>) head.getNext();//节点读取当前位置 private Node<T> returnedNode = currentNode;//返回节点的位置 @Override
public boolean hasNext() {
return currentNode == tail? false:true;
} @Override
public T next() {
if(!hasNext()){
throw new IndexOutOfBoundsException();
}
returnedNode = currentNode;
currentNode = currentNode.getNext();
return returnedNode.getData();
} @Override
public void remove() {
if(!hasNext()){
throw new NoSuchElementException();
}
returnedNode.getPre().setNext(returnedNode.getNext());
returnedNode.getNext().setPre(returnedNode.getPre());
returnedNode = returnedNode.getNext();
currentNode = returnedNode;
size--;
}
}
}

测试类:

public class TestDemo {

	public static void main(String[] args) {
LinkedListDemo<Person> list = new LinkedListDemo<Person>();
//往链表中加入10个元素
for(int i=0; i<10;i++){
Person p = new Person("zhang"+i, "m");
list.add(p);
}
list.print();
System.out.println("========");
Person p = new Person("zhang1", "m");
list.remove(p);//移除自定的元素
list.print();
System.out.println("========");
Person p1 = new Person("zhang4", "m");
Iterator<Person> iterator = list.iterator();
while(iterator.hasNext()){
Person person = iterator.next();
if(person.equals(p1)){
iterator.remove();//迭代器移除制定元素
break;
}
}
list.print();
}
}

结果:

Person [name=zhang0, sex=m]
Person [name=zhang1, sex=m]
Person [name=zhang2, sex=m]
Person [name=zhang3, sex=m]
Person [name=zhang4, sex=m]
Person [name=zhang5, sex=m]
Person [name=zhang6, sex=m]
Person [name=zhang7, sex=m]
Person [name=zhang8, sex=m]
Person [name=zhang9, sex=m]
========
Person [name=zhang0, sex=m]
Person [name=zhang2, sex=m]
Person [name=zhang3, sex=m]
Person [name=zhang4, sex=m]
Person [name=zhang5, sex=m]
Person [name=zhang6, sex=m]
Person [name=zhang7, sex=m]
Person [name=zhang8, sex=m]
Person [name=zhang9, sex=m]
========
Person [name=zhang0, sex=m]
Person [name=zhang2, sex=m]
Person [name=zhang3, sex=m]
Person [name=zhang5, sex=m]
Person [name=zhang6, sex=m]
Person [name=zhang7, sex=m]
Person [name=zhang8, sex=m]
Person [name=zhang9, sex=m]

四、队列

队列数据结构类似于生活中队列,有一个很重要的特性:先进先出。即增加元素肯定是在队列的尾部添加,删除元素肯定是删除队列头部的元素。队列的实现可以用数据结构,

也可以用链表结构。

下面简单是一个用数组结构实现的队列结构:

public class QueueDemo<T> {

	private Object[] object;

	/**
* 队列容量
*/
private int capicity; /**
* 队列中元素的个数
*/
private int size; private final static int DEFAULT_CAPICAL = 10; public QueueDemo(){
capicity = DEFAULT_CAPICAL;
object = new Object[capicity];
} public QueueDemo(int capicity){
this.capicity = capicity;
object = new Object[this.capicity];
} public int size(){
return size;
} public boolean isEmpty(){
return size==0;
} /**
* 往队列中添加元素
* @param t
*/
public void add(T t){
if(size == capicity){
throw new IndexOutOfBoundsException("queue is full");
}
object[size++]=t;
} /**
* 移除队列中的元素
*/
public void remove(){
if(isEmpty()){
throw new IndexOutOfBoundsException("queue is empty");
}
for(int pos = 0; pos < size-1; pos++){//将整个数组往前以一个位置
object[pos] = object[pos+1];
}
size--;
} public void clear(){
Arrays.fill(object, null);
size=0;
} public void print(){
for(int i=0; i<size; i++){
System.out.println(object[i].toString());
}
}
}

测试类:

public class TestQueue {

	/**
* @param args
*/
public static void main(String[] args) {
QueueDemo<Person> queue = new QueueDemo<Person>();
for(int i=0; i<10; i++){
Person p = new Person("zhang"+i, "m");
queue.add(p);
}
queue.print();
System.out.println("=====");
while(queue.size() > 0){//依次删除队列头元素
queue.remove();
queue.print();
System.out.println("=====");
}
} }

输出:

Person [name=zhang0, sex=m]
Person [name=zhang1, sex=m]
Person [name=zhang2, sex=m]
Person [name=zhang3, sex=m]
Person [name=zhang4, sex=m]
Person [name=zhang5, sex=m]
Person [name=zhang6, sex=m]
Person [name=zhang7, sex=m]
Person [name=zhang8, sex=m]
Person [name=zhang9, sex=m]
=====
Person [name=zhang1, sex=m]
Person [name=zhang2, sex=m]
Person [name=zhang3, sex=m]
Person [name=zhang4, sex=m]
Person [name=zhang5, sex=m]
Person [name=zhang6, sex=m]
Person [name=zhang7, sex=m]
Person [name=zhang8, sex=m]
Person [name=zhang9, sex=m]
=====
Person [name=zhang2, sex=m]
Person [name=zhang3, sex=m]
Person [name=zhang4, sex=m]
Person [name=zhang5, sex=m]
Person [name=zhang6, sex=m]
Person [name=zhang7, sex=m]
Person [name=zhang8, sex=m]
Person [name=zhang9, sex=m]
=====
Person [name=zhang3, sex=m]
Person [name=zhang4, sex=m]
Person [name=zhang5, sex=m]
Person [name=zhang6, sex=m]
Person [name=zhang7, sex=m]
Person [name=zhang8, sex=m]
Person [name=zhang9, sex=m]
=====
Person [name=zhang4, sex=m]
Person [name=zhang5, sex=m]
Person [name=zhang6, sex=m]
Person [name=zhang7, sex=m]
Person [name=zhang8, sex=m]
Person [name=zhang9, sex=m]
=====
Person [name=zhang5, sex=m]
Person [name=zhang6, sex=m]
Person [name=zhang7, sex=m]
Person [name=zhang8, sex=m]
Person [name=zhang9, sex=m]
=====
Person [name=zhang6, sex=m]
Person [name=zhang7, sex=m]
Person [name=zhang8, sex=m]
Person [name=zhang9, sex=m]
=====
Person [name=zhang7, sex=m]
Person [name=zhang8, sex=m]
Person [name=zhang9, sex=m]
=====
Person [name=zhang8, sex=m]
Person [name=zhang9, sex=m]
=====
Person [name=zhang9, sex=m]
=====
=====

五、栈

栈结构与队列类似,不过区别在于栈是先进后出的。即最先进栈的元素是最后一个出栈的。栈的结构也可以用数组或链表来实现。

下面简单实现一个基于数组结构的栈,实现只是稍微修改下上面队列结构的代码。

public class StackDemo<T> {

	private Object[] object;

	private int capicity;

	private int size;

	private final static int DEFAULT_CAPICAL = 10;	

	public StackDemo(){
capicity = DEFAULT_CAPICAL;
object = new Object[capicity];
} public StackDemo(int capicity){
this.capicity = capicity;
object = new Object[this.capicity];
} public int size(){
return size;
} public boolean isEmpty(){
return size==0;
} public void add(T t){
if(size == capicity){
throw new IndexOutOfBoundsException("queue is full");
}
object[size++]=t;
} /**
* 修改移除元素的代码
*/
public void remove(){
if(isEmpty()){
throw new IndexOutOfBoundsException("queue is empty");
}
object[--size]=null;
} public void clear(){
Arrays.fill(object, null);
size=0;
} public void print(){
for(int i=0; i<size; i++){
System.out.println(object[i].toString());
}
} }

测试类:

public class TestStack {

	/**
* @param args
*/
public static void main(String[] args) {
StackDemo<Person> queue = new StackDemo<Person>();
for(int i=0; i<10; i++){
Person p = new Person("zhang"+i, "m");
queue.add(p);
}
queue.print();
System.out.println("=====");
while(queue.size() > 0){
queue.remove();
queue.print();
System.out.println("=====");
}
}
}

结果:

Person [name=zhang0, sex=m]
Person [name=zhang1, sex=m]
Person [name=zhang2, sex=m]
Person [name=zhang3, sex=m]
Person [name=zhang4, sex=m]
Person [name=zhang5, sex=m]
Person [name=zhang6, sex=m]
Person [name=zhang7, sex=m]
Person [name=zhang8, sex=m]
Person [name=zhang9, sex=m]
=====
Person [name=zhang0, sex=m]
Person [name=zhang1, sex=m]
Person [name=zhang2, sex=m]
Person [name=zhang3, sex=m]
Person [name=zhang4, sex=m]
Person [name=zhang5, sex=m]
Person [name=zhang6, sex=m]
Person [name=zhang7, sex=m]
Person [name=zhang8, sex=m]
=====
Person [name=zhang0, sex=m]
Person [name=zhang1, sex=m]
Person [name=zhang2, sex=m]
Person [name=zhang3, sex=m]
Person [name=zhang4, sex=m]
Person [name=zhang5, sex=m]
Person [name=zhang6, sex=m]
Person [name=zhang7, sex=m]
=====
Person [name=zhang0, sex=m]
Person [name=zhang1, sex=m]
Person [name=zhang2, sex=m]
Person [name=zhang3, sex=m]
Person [name=zhang4, sex=m]
Person [name=zhang5, sex=m]
Person [name=zhang6, sex=m]
=====
Person [name=zhang0, sex=m]
Person [name=zhang1, sex=m]
Person [name=zhang2, sex=m]
Person [name=zhang3, sex=m]
Person [name=zhang4, sex=m]
Person [name=zhang5, sex=m]
=====
Person [name=zhang0, sex=m]
Person [name=zhang1, sex=m]
Person [name=zhang2, sex=m]
Person [name=zhang3, sex=m]
Person [name=zhang4, sex=m]
=====
Person [name=zhang0, sex=m]
Person [name=zhang1, sex=m]
Person [name=zhang2, sex=m]
Person [name=zhang3, sex=m]
=====
Person [name=zhang0, sex=m]
Person [name=zhang1, sex=m]
Person [name=zhang2, sex=m]
=====
Person [name=zhang0, sex=m]
Person [name=zhang1, sex=m]
=====
Person [name=zhang0, sex=m]
=====
=====

六、几种简单的线性结构介绍完了,在实际的应用环境中需要参考各种数据结构的特点来选择。

数组:查找速度很快,但长度固定,增,删效率较低。

链表:增删效率较高,长度不固定,但查找需要从头遍历整个链表,效率较低。

队列:可用数组,链表实现,先进先出。

栈:可用数组,链表实现,先进后出。

java数据结构--线性结构的更多相关文章

  1. Java数据结构-线性表之单链表LinkedList

    线性表的链式存储结构,也称之为链式表,链表:链表的存储单元能够连续也能够不连续. 链表中的节点包括数据域和指针域.数据域为存储数据元素信息的域,指针域为存储直接后继位置(一般称为指针)的域. 注意一个 ...

  2. Java数据结构-线性表之顺序表ArrayList

    线性表的顺序存储结构.也称为顺序表.指用一段连续的存储单元依次存储线性表中的数据元素. 依据顺序表的特性,我们用数组来实现顺序表,以下是我通过数组实现的Java版本号的顺序表. package com ...

  3. java数据结构-非线性结构之树

    一.树状图 树状图是一种数据结构,它是由n(n>=1)个有限节点组成的具有层次关系的集合.因其结构看起来想个倒挂的树,即根朝上,叶子在下,故被称为"树". 特点: 1. 每个 ...

  4. Java数据结构-线性表之静态链表

    静态链表的定义: 节点由一个一维数组和一个指针域组成,数组用来存放数据元素,而指针域里面的指针(又称游标)用来指向下一个节点的数组下标. 这种链表称之为静态链表. 链表中的数组第一个和最后一个位置须要 ...

  5. Java数据结构和算法(四)赫夫曼树

    Java数据结构和算法(四)赫夫曼树 数据结构与算法目录(https://www.cnblogs.com/binarylei/p/10115867.html) 赫夫曼树又称为最优二叉树,赫夫曼树的一个 ...

  6. 【Java数据结构学习笔记之一】线性表的存储结构及其代码实现

    应用程序后在那个的数据大致有四种基本的逻辑结构: 集合:数据元素之间只有"同属于一个集合"的关系 线性结构:数据元素之间存在一个对一个的关系 树形结构:数据元素之间存在一个对多个关 ...

  7. Java数据结构和算法(一)线性结构之单链表

    Java数据结构和算法(一)线性结构之单链表 prev current next -------------- -------------- -------------- | value | next ...

  8. Java数据结构和算法(一)线性结构

    Java数据结构和算法(一)线性结构 数据结构与算法目录(https://www.cnblogs.com/binarylei/p/10115867.html) 线性表 是一种逻辑结构,相同数据类型的 ...

  9. Java数据结构介绍(线性结构和非线性结构)

    数据结构包括:线性结构和非线性结构. 线性结构 数据元素之间存在一对一的线性关系 包括顺序存储结构和链式存储结构.顺序存储的线性表称为顺序表,顺序表中的存储元素是连续的 链式存储的线性表称为链表,链表 ...

随机推荐

  1. STM32之系统滴答定时器

    一.SysTick(系统滴答定时器)概述 操作系统需要一个滴答定时器周期性产生中断,以产生系统运行的节拍.在中断服务程序里,基于优先级调度的操作系统会根据进程优先级切换任务,基于时间片轮转系统会根据时 ...

  2. 关于 jquery.showLoading 中 出现的 图标不在页面中间的问题

    很多人喜欢 showLoading   因为 这个实在是太简单了直接 showLoading() hideLoading() 就可以解决这个问题. 今天我们就来看一下  这个插件里面的一个错误 或者说 ...

  3. JAVA NIO之Character Set

    明白以下几个概念: 字母集(Character Set),汉字,特殊符号,字母这些都是字符集: 字符编码集(Coded character set),将字符集的字符使用数字进行编码:比如ASCII,就 ...

  4. iOS项目架构文档

    设计的项目架构主要引用MVVM+MVC架构,并以功能模块分级.以下为目录结构. 初级目录: 我们只需要关注SGZH文件夹下的目录,其他为Xcode管理的目录.可以看到此目录为项目初级目录,我们开发过程 ...

  5. 几MB的大图片变成几百KB

    使用windows自带的“画图”工具就可以. 1.用“画图”打开图片. 2.点击“重新调整大小” 弹出如下窗口 修改这里的“水平”和“垂直”,如都从100改为30.改完之后,点击确定,最后再“保存”或 ...

  6. 运行avalon.define()发生的事情

      avalon.define = function(id, factory) { var $id = id.$id || id if (!$id) { log("warning: vm必须 ...

  7. bzoj 3858: Number Transformation 暴力

    3858: Number Transformation Time Limit: 1 Sec  Memory Limit: 64 MBSubmit: 82  Solved: 41[Submit][Sta ...

  8. BZOJ 1754: [Usaco2005 qua]Bull Math

    Description Bulls are so much better at math than the cows. They can multiply huge integers together ...

  9. 【POJ 1988】 Cube Stacking (带权并查集)

    Cube Stacking Description Farmer John and Betsy are playing a game with N (1 <= N <= 30,000)id ...

  10. ANDROID_MARS学习笔记_S04_001_OAuth简介

    一.OAuth简介