本文介紹用鏈表實現一個隊列,並同系統隊列比較在運行一千萬個數時增、刪、查功能的性能
首先,創建結點,包括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);
}
我的:
系統:
- 之前在寫查詢的時候就想有沒有辦法優化,,現在終於找到了方法。。
又捕獲一種學習方法~~