本文介绍用链表实现一个队列,并同系统队列比较在运行一千万个数时增、删、查功能的性能
首先,创建结点,包括next、data属性
我的:
private node root; //根节点
private node last; //尾节点
public int size = 0; //链表的大小
public class node { //创建结点类
public object data; //结点中存放的数据值
public node next; //指向下一个结点
public node(object data, node next) { //构造
this.data = data;
this.next = next;
}
}
在Java jdk中,它直接定义了前趋结点,然而我的是在后面的方法中新创建的
Java jdk:
private static class Node<E> {
E item;
Node<E> next;
Node<E> prev;
Node(Node<E> prev, E element, Node<E> next) { //传入三个参数:前趋、此元素、后继
this.item = element; //结点中存放的值
this.next = next;
this.prev = prev; //前趋结点
}
}
入队:
我的:
// 新元素从尾部进队列
public void In_Queue(Object obj) {
node newNode = new node((object) obj, null);
if (root == null) { //当队列为空,把新数据放入根节点中
root = last = newNode;
} else { //队列非空,从尾部入队
last.next = newNode;
last = last.next;
}
size++;
}
Java jdk中
Java jdk:
void linkLast(E e) {
final Node<E> l = last;
final Node<E> newNode = new Node<>(l, e, null); //新结点的前趋是尾节点,后继是null,即新定义尾结点
last = newNode;
if (l == null)
first = newNode; //队空
else
l.next = newNode;
size++;
}
入队操作两者比较:
通过比较添加10000000个数所需要的时间,对比两个方法的性能
LinkedList<Object> list = new LinkedList<>();
long start = System.currentTimeMillis();
for (int i = 0; i < 10000000; i++) {
list.add(i);
}
long end = System.currentTimeMillis();
System.out.println(end - start);
外套一个循环,运行10次的结果:
我的程序:
系统:
- 首先,感觉系统的代码更简洁,它在创建结点的时候,直接传入三个参数,后面用着就很方便
- 系统程序在新建结点的时候就已经建立好last和newNode的关系了,然而我的程序,新建结点且赋值之后,还要把新结点设置为尾结点。
出队
我的:
// 从队首删除元素
public void Out_Queue() {
node preNode = new node(null, null); //新建前趋结点
preNode = root; //指向根节点
if (size == 0) {
System.out.println("队空");
} else {
root.data = null; //把根节点的内容干掉
root = root.next; //根节点的后结点变成根节点(假溢出的根源)
size--;
}
}
Java jdk:
private E unlinkFirst(Node<E> f) {
// assert f == first && f != null;
final E element = f.item;
final Node<E> next = f.next; //和我的preNode一个效果
f.item = null;
f.next = null; // help GC
first = next; //把f.next指向first
if (next == null) //用f.next判断队空(我用的是最初创建好的计数器size)
last = null;
else
next.prev = null; //头节点的下一个结点的前趋结点(头节点)变成null
size--;
return element;
}
下面进行测试
先进队10000000个数,然后几下这些数出队的时间
public static void main(String[] args) {
long S = 0;
for (int m = 0; m < 10; m++) {
Queue queue = (Queue) Init_Queue();
for (int i = 0; i < 10000000; i++) {
queue.In_Queue(i);
}
long start = System.currentTimeMillis();
for (int i = 0; i < 10000000; i++) {
queue.Out_Queue();
}
long end = System.currentTimeMillis();
long S1 = end - start;
System.out.println(end - start);
S = S + S1;
}![](https://img-blog.csdnimg.cn/20191024004340605.png)
System.out.println("平均时间" + S / 10);
}
我的程序:
系统:
- 我的时间竟然比它的短!!!我惊呆了
- 个人认为是因为它用的那个 prev ,我在把根节点变成null后,直接把根节点的后结点变成根节点;而系统程序是根节点的下一个结点的前趋结点变成null。
- 删除一个结点,比增加一个结点快了n倍。
查找
我的:
// 查找元素
public void Find(int index) {
node goalNode = new node(null, null);
goalNode = root;
if (index < 0 || index >= size) {
System.out.println("超出范围!!!");
} else if (index == 0) {
// System.out.println(goalNode.data);
} else {
for (int i = 0; i < index; i++) { //通过头结点遍历(感觉很不妥)
goalNode = goalNode.next;
}
// System.out.println(goalNode.data);
}
}
Java jdk:
//判断插入的位置和总长度的关系,优化
public E get(int index) {
checkElementIndex(index); //判断是否超出存储的长度
return node(index).item;
}
Node<E> node(int index) {
// assert isElementIndex(index);
if (index < (size >> 1)) { //如果插入的位置小于链表总长度一半
Node<E> x = first; //从头节点开始往后
for (int i = 0; i < index; i++)
x = x.next;
return x;
} else {
Node<E> x = last; //如果大于一半
for (int i = size - 1; i > index; i--) //从尾节点往前
x = x.prev;
return x;
}
}
不用看运行结果就知道,肯定是系统的快,机智!!
但是呢,还是数字更有说服力,我通过设定500个1-10000000的随机数让它去查询来比较结果:
public class Main {
public static void main(String[] args) {
long S = 0;
for (int n = 0; n < 10; n++) {
LinkedList<Object> list = new LinkedList<>();
for (int i = 0; i < 10000000; i++) {
list.add(i);
}
long start = System.currentTimeMillis();
for(int i = 0;i<50;i++){
Random random =new Random();
int index = random.nextInt(10000000)+1;
list.get(index);
}
long end = System.currentTimeMillis();
long S1 = end - start;
System.out.println(end - start);
S = S + S1;
}
System.out.println("平均时间" + S / 10);
}
我的:
系统:
- 之前在写查询的时候就想有没有办法优化,,现在终于找到了方法。。
又捕获一种学习方法~~