队列是常用的数据结构,是一个有序列表,遵循先进先出的原则,即先进入队列的数据要先取出来,后存入的要后取出。且它只允许在表的前端(front)进行删除,在表的后端(rear)进行插入操作,队列的数据元素又称为队列元素。在插入一个队列元素称为入队,删除一个队列元素称为出队。所以只有最早进入队列的元素才能最先从队列删除。

可以用数组或者链表来实现。本篇就用java分别来实现队列的基本功能。

数组实现

用数组来实现的话问题就在于一个数组新创建出来长度就已经固定,所以在增删操作时就要不断新建新的数组,把原来复制过去,再进行增删。

开始先定义新建一个数组

public class arrayQ {private Object[] sa=new Object[0];}

接着就是实现一些基本功能,增删改查,获取个数,遍历

public void add(Object s) {//1.新建一个数组,是原数组长度+1,扩容Object[] temA=new Object[sa.length+1];//2.把原数组的,复制到新数组for(int i=0;i<sa.length;i++){temA[i]=sa[i];}//数据结加新数组最后一个位子temA[temA.length-1]=s;sa=temA;}

public Object pop() {//1.新建一个数组,是原数组长度-1,缩小Object[] temB=new Object[sa.length-1];//2.取出出队的数据Object a = sa[sa.length-1];//3.复制除最后一个队列元素的所有元素for(int i=0;i<sa.length-1;i++) {temB[i] = sa[i];}sa = temB;return a;}

改:

public void update(int index,Object s) {if (index < 0 || index >= sa.length) {System.out.println("位置不合法");}sa[index] = s;}

查:

public Object get(int index){if (index < 0 || index >= sa.length) {System.out.println("位置不合法");return null;}Object m=sa[index];return m;}

获得队列中元素的个数:

public int size(){return sa.length;}

遍历打印队列:

public void print() {for(int i=0;i<sa.length;i++) {System.out.println(""+sa[i]);}}

为了使用方便,还可以增加一些功能在指定位置增删元素,不过这样还能算队列吗哈哈

//增public void insert(int index,Object s) {if (index < 0 || index >= sa.length)System.out.println("位置不合法");// 定义一个新的数组,长度是array.length-1Object[] newArray = new Object[sa.length + 1];for (int i = 0; i < index; i++) {newArray[i] = sa[i];}newArray[index] = s;for (int i = index ; i < sa.length; i++) {newArray[i+1] = sa[i];}// 将newArray的地址赋给arraysa = newArray;}//删public void remove(int index) {if (index < 0 || index >= sa.length)System.out.println("位置不合法");// 定义一个新的数组,长度是array.length-1Object[] newArray = new Object[sa.length - 1];// 将array数组中的数据存入到newArray数组中,但是index不需要for (int i = 0; i < index; i++) {newArray[i] = sa[i];}for (int i = index + 1; i < sa.length; i++) {newArray[i - 1] = sa[i];}// 将newArray的地址赋给arraysa = newArray;}

这样数组实现就基本完成了。

链表实现

之前讲过链表结构,这里用单向链表来实现,首先得先定义一个小类--节点类

class linknode {public Object data;// 每个节点的数据public linknode next;// 每个节点指向下一个节点的连接}

开始得定义头尾部两个指针和计数器(方便得到队列长度)

public class QueueLinklist {private int size = 0;//队列大小public linknode front = null;//队列在头部删除public linknode rear = null;//队列在尾部进入}

接着就是增删改查的基本功能

增,这里队列中有元素和没元素的操作是不同的,无元素时将头尾指针都指向新加入的节点;有元素时,将原尾部元素的next指向新节点,并将尾部指针指向新节点。

public void add(Object value) {//加入队列linknode newnode = new linknode();newnode.data = value;if(null == front) {//原本无元素front = newnode;rear = front;}else {//原本有元素rear.next = newnode;rear = newnode;}size++;}

删,在有元素的情况下进行,删除时将头指针指向下一个就可以了,当元素减为空时,尾指针置为空

public linknode queueremove() {//从队列中头部删除if(size != 0 ) {front = front.next ;size--;if(size == 0) {rear = null;}return front;}else {return null;}}

改,思路是将队列从头指针开始遍历,当次数达到了输入的索引值,就修改该处节点的data值

public void update(int index,Object value) {//改int count=0;linknode tempNode=new linknode();tempNode=front;while(count!=index){tempNode=tempNode.next;count++;}tempNode.data = value;}

查,和改是同样的思路,直接返回就好了

public Object get(int index) {//查int count=0;linknode tempNode=new linknode();tempNode=front;while(count!=index){tempNode=tempNode.next;count++;}return tempNode.data;}

遍历打印,从头节点开始递归打印就可以了

public void printLinKqueue(linknode root) {//遍历打印链表if(null !=root) {Object data=root.data;String s=(String)data;System.out.println(""+s);printLinKqueue(root.next);}}

同样的,为了方便依旧还可以增加在指定位置增删操作,这样也可以加深对结构的理解

也分两种情况,插入或删除的位置是否为头部

public void insert(int index,Object value) {//插入指定位置if (index < 0 || index >getlength() - 1) {System.out.println("插入位置不合法");}int currentnode = 0;linknode newNode=new linknode();newNode.data = value;linknode temp = front;while (temp.next != null) {if(index == 0) {//头部插入newNode = front;newNode.next = front.next;}//找到上一个节点的位置if ((index - 1) == currentnode) {//temp表示的是上一个节点//将原本由上一个节点的指向交由插入的节点来指向newNode.next = temp.next;//将上一个节点的指向要插入的节点temp.next = newNode;}currentnode++;temp = temp.next;}}public void remove(int index) {if (index < 0 || index >getlength() - 1) {System.out.println("删除位置不合法");}linknode temp =front;int currentnode = 0;while (temp.next != null) {if(index == 0) {//头部删除front = front.next;break;}//找到上一个节点的位置if ((index - 1) == currentnode) {//temp表示的是上一个节点//将想要删除的节点存储一下linknode deleteNode = temp.next;//想要删除节点的下一个节点由上一个节点来指向temp.next = deleteNode.next;}currentnode++;temp = temp.next;}}

这样链表的实现就基本完成了。

我们可以和java集合框架中已有的ArrayList和LinkedList比较一下性能,比如增加百万级数据所需要的时间。具体的分析等到集合框架分析的时候再讲吧。

分类: 游戏攻略 标签: 暂无标签

评论

暂无评论数据

暂无评论数据

目录