java中线性结构的例子_java数据结构--线性结构

一、数据结构

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

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

二、数组

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

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

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

0940344eb5450761cc9a4a8af92347e2.png

插入元素:

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

删除元素:

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

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

public class ArrayDemo {

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 array = new ArrayDemo<>();

Person p = new Person("张三", "m");

array.insert(p, 0);

array.trans();

array.delete(0);

System.out.println("---");

array.trans();

}

}

三、链表

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

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

6164aca1782b13db8e81de49bc0421ae.png

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

节点类:

public class Node {

private T data;

private Node pre;

private Node 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 pre, Node 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 getPre() {

return pre;

}

public void setPre(Node pre) {

this.pre = pre;

}

public Node getNext() {

return next;

}

public void setNext(Node next) {

this.next = next;

}

}

链表类

public class LinkedListDemo {

private Node head;//头结点

private Node tail;//尾节点

private int size;//链表大小

public LinkedListDemo(){

head = new Node(null, null, null);

tail = new Node(null, head, null);

head.setNext(tail);

size = 0;

}

public MyIterator iterator(){

return new MyIterator();

}

public void add(T data){

Node node = new Node(data);

node.setPre(tail.getPre());

tail.getPre().setNext(node);

tail.setPre(node);

node.setNext(tail);

size++;

}

public void remove(T data){

Node node = head;

while(tail != node.getNext()){

Node 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 node = head;

while(tail != node.getNext()){

Node currentNode = node.getNext();

System.out.println(currentNode.getData().toString());

node = currentNode;

}

}

/**

*

* 项目名: adt

* 类名: LinkedListDemo.java

* 类描述: 定义一个该链表的迭代器来访问

* 备注:

* 创建日期:2014-10-10

* 创建时间:上午12:10:46

* @param

*/

@SuppressWarnings("hiding")

private class MyIterator implements Iterator{

@SuppressWarnings("unchecked")

private Node currentNode = (Node) head.getNext();//节点读取当前位置

private Node 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 list = new LinkedListDemo();

//往链表中加入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 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]

四、队列

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

也可以用链表结构。

8c58e870923d5afd6603676bd0078494.png

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

public class QueueDemo {

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

System.out.println(object[i].toString());

}

}

}

测试类:

public class TestQueue {

/**

* @param args

*/

public static void main(String[] args) {

QueueDemo queue = new QueueDemo();

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]

=====

=====

五、栈

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

6bdb7ca1b72e62f69bcba92031a7be88.png

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

public class StackDemo {

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

System.out.println(object[i].toString());

}

}

}

测试类:

public class TestStack {

/**

* @param args

*/

public static void main(String[] args) {

StackDemo queue = new StackDemo();

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]

=====

=====

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

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

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

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

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值