用連結串列實現佇列
阿新 • • 發佈:2019-02-05
所有的資料結構都可以大致分為兩類,由連續單位構成或者由離散單位構成,具體到實體也就是陣列實現或者連結串列實現。陣列實現的資料結構方便查詢和修改但不方便增刪,連結串列實現的資料結構則剛好相反,適於增刪卻不便於查詢。 今天我們用連結串列來實現佇列。 我們需要實現的功能無非增刪查改,這也是一般的資料結構都會具備的功能。 一、關於Myqueue 我們為這個佇列設定一個Node型別的頭結點head,這個頭結點並不放資料,僅僅存一個指標,這樣會更便於後面的插入和刪除操作。然後再定義一個Node型的結點cur來表示當前結點,以及定義一個int 型的size記錄佇列的長度。 二、關於Node 我想實現的只是一個簡單的單向佇列,所以僅僅包含資料域data和指向下一個結點的“指標”next(Java中沒有指標,只是類似一個索引),並且定義一個構造方法。(如果想實現雙向佇列可以定義front,next兩個指標)程式碼如下:
三、增刪查改 增 :增添操作給的引數是新加入的資料 1.我們先建立一個新的節點來接受資料。 2. 然後按照表是否為空表分討論,因為兩種情況的head指標位置是不同的。若為空表,則把新節點當作表頭即可,讓head 和cur都指向它;若不是空表,建立節點後讓cur指向它。 程式碼如下:
public class Myqueque {
public Node head; //頭結點,不存資料
public Node cur; //當前節點
public int size; //佇列長度
public class Node {
public Object data;
public Node next;
public Node(Object data) {
this.data = data;
}
}
三、增刪查改 增 :增添操作給的引數是新加入的資料 1.我們先建立一個新的節點來接受資料。 2. 然後按照表是否為空表分討論,因為兩種情況的head指標位置是不同的。若為空表,則把新節點當作表頭即可,讓head 和cur都指向它;若不是空表,建立節點後讓cur指向它。 程式碼如下:
// 增 public void Add(Object input) { Node addnode = new Node(input); if(head==null) { //如果頭結點不存在 head=addnode; head.next=null; cur=head;//移動當前節點到頭節點 } else { //頭節點存在,移動當前節點的位置 cur.next=addnode; cur=cur.next; } size++; //陣列的大小++ }
刪:刪除操作給的引數是希望刪除的位置。
刪除前也要問自己一個問題:表是不是空的?如果空了刪個鬼哦;
如果刪的是表頭,移動頭指標就好了;
如果刪的是中間,則需要改變一下中間被刪除節點的前一個節點,讓其next繞過希望刪除的節點temp;如果是刪除表尾,則直接讓cur.next=null。但是其實這兩種情況可以合併為temp.next=temp.next.next;
// 刪
public void Delete(int index) {
// Object retuNode; 如果希望取得想刪除節點的值就創一個節點接收資料,最後返回。此處我不想返回它的值,可以自己靈活更改
if (size <= 0) //陣列的size必須大於0
System.out.println("Error.");
else {
if(index==0){ //刪頭節點
// retuNode=head.data;
head=head.next; //關鍵句
}
else if (index > 0 && index <= size) { //刪除中間或表尾
int count = 0;
Node temp=head;
while (count != index) {
temp=temp.next;
count++;
}
retuNode=temp.next.data;
temp.next=temp.next.next; //關鍵句
size--;
}
else { //輸入越界
System.out.println("No such node.");
}
}
}
查:查詢操作給的引數是被查詢元素的位置index同樣的,要考慮給的index是否合理,有沒有越界;接下來定義一個節點temp接收資料,操作很簡單了,不解釋了
//查
public Object Search(int index) {
int count = 0;
Node temp=head;
if (index >= 0 && index < this.Size()) {
while (count<index) {
temp = temp.next;
count++;
}
return temp.data;
} else { //如果要找的index越界
System.out.println("No such node.");
return null;
}
}
改:修改與查詢十分相似,區別僅僅是引數除了修改的位置還多了個數據N,因為不知道N是什麼型別的所以用Object;
步驟就是先查詢,再賦值。
// 改
public void Change(int index,Object N) {
int count = 1;
Node temp=head;
if (index >= 0 && index <= this.Size()) {
while (count != index) {
temp = temp.next;
count++;
}
temp.data=N;
// System.out.println(temp.data+"hhhhhhhhh已修改"); //除錯用的
} else {
System.out.println("No such node.");
}
}
好了現在佇列建立好了,我們給它新增一個測試類看看對不對:
public class Test {
public int number;
public String name;
public Test(int num,String s){
number=num;
name=s;
}
/*public String toString() {
return getClass().getName() +;
}*/
public static void main(String[] args) {
Test t1=new Test(1,"hhhhh");
Test t2=new Test(2,"xxxxx");
Test t3=new Test(3,"eeeee");
Test t4=new Test(4,"aaaaa");
Myqueque q=new Myqueque();
q.Add(t1);
q.Add(t2);
q.Add(t3);
q.Add(t4);
Test test1=(Test)q.Search(0);
// Test test2=(Test)q.Change(3,"這是被修改的");
System.out.println("sssssssssss+"+test1.number+":"+test1.name);
//System.out.println("333333333333333+"+test2.number+":"+test2.name);
q.Change(3,"這是被修改的");
q.Delete(0);
Test ts4=(Test)q.Search(0);
System.out.println("shanchu"+ts4.number+":"+ts4.name);
q.Change(3, "hahahhah");
}
}
測試的結果我就不放截圖了(哈哈哈。。。)你可以自己試試哦