前兩章寫了單鏈表的操作,在這裏,寫了一個循環單鏈表。爲了更好地實現各操作,在此引入頭結點,這裏的頭結點與前兩章定義的頭結點不同,前兩章的頭結點即首節點,而這裏的頭結點並不是首節點。這樣說可能有些糊塗。那就再詳細地解釋一下頭結點和首節點的區別,頭結點是物理上的第一個節點,但是它存放的不是我們所需要的數據,而是鏈表的一些信息,如鏈表的長度等,也可以是null,當鏈表爲空時,頭結點爲空,但是它存在,它的next指向自身,假設頭結點聲明爲head,那麼鏈表爲空時的條件爲head.next=head;若鏈表不爲空,則head.next指向邏輯上的第一個節點,這個邏輯上的第一個節點就是首節點,首節點是什麼呢?比如我們現在鏈表中存放的是教師職工的信息,第一個老師的編號是001,那麼第一個節點中存放的就是編號爲001的教工信息。這個存放001教工信息的節點就是首節點。首節點是邏輯上的第一個節點,是物理上的第二個節點。如果還是不明白,參照下圖再看一遍:
在上圖中,first存放的是教工001的信息,second存放的是教工002的信息。在head中,存放的是鏈表的信息,不存放教工信息。若該鏈表爲空,則爲下圖所示,head的next指針指向自身。
下面是循環單鏈表的具體操作實現代碼:
package ListLink;
/*
* 循環單鏈表的簡單操作
*/
public class CircleLinkList {
/*
* first爲頭結點,不存放內容,若後面無內容,指向自身,若後面有內容,則指向首節點
* 這裏的頭結點與前面兩章的頭結點不一樣,之前的頭結點即爲首節點,這裏頭結點是物理上的第一個節點,
* 指向首節點,頭結點中內容可以爲空,也可以存儲鏈表長度等數據
* 首節點指的是邏輯上存放數據的第一個節點
* 請注意區分
* 至於爲什麼在首節點之前使用頭結點,我們不使用頭結點的時候,執行插入、刪除操作的時候,
* 往往要考慮我們插入/刪除的位置是不是位於首節點位置,以及原鏈表是否爲空的問題
* 引入頭結點,則不需要考慮這些問題
*
*/
public Node first=null;
int len=1; //鏈表節點數
int tmp=0; //當前節點位置
public CircleLinkList()
{
first=new Node(null);
first.next=first;
}
//在尾部插入數據
public void addNodeEnd(Teacher teacher)
{
Node node=new Node(teacher);
Node temp=first;
while(temp.next!=first)
temp=temp.next;
temp.next=node;
node.next=first;
len++;
}
//在頭部插入數據
public void addNodeFirst(Teacher teacher)
{
Node node=new Node(teacher);
node.next=first.next;
first.next=node;
len++;
}
/*
* 根據用戶需求將數據插入鏈表中
* 此處的index最好不要傳值爲0,若傳值爲0,則將頭結點覆蓋,此時只有一個節點,即頭結點,
* 若傳值爲0 後繼續添加節點,則繼續添加,在此步驟之前鏈表中的節點數據則不存在了
*/
public void addNode(int index,Teacher teacher)
{
Node node=new Node(teacher);
Node previous=first;
Node current=first;
while(tmp!=index)
{
previous=current;
current=current.next;
tmp++;
}
node.next=current;
previous.next=node;
len++;
tmp=0;
}
//在尾部刪除數據
public void deleteNodeEnd()
{
Node previous=first;
Node current=first;
while(current.next!=first)
{
previous=current;
current=current.next;
}
previous.next=first;
len--;
}
//刪除頭部數據
public void deleteNodeFirst()
{
Node node=first.next;
first.next=node.next;
len--;
}
/*
* 刪除任意位置的數據
* 此處若寫刪除0節點的數據是無用的
* 另外,若此處實現的是刪除0節點,該鏈表長度不變
* 儘量不要刪除0節點
*
*/
public void deleteNode(int index)
{
int temp=index%len;
Node previous=first;
Node current=first;
while(tmp!=temp)
{
previous=current;
current=current.next;
tmp++;
}
previous.next=current.next;
len--;
tmp=0;
}
//查詢某位置的節點信息並打印出來
public void getNodeIndex(int index)
{
Node node=first;
while(tmp!=index)
{
node=node.next;
tmp++;
}
tmp=0;
System.out.println("查詢的教工信息是:");
node.display();
System.out.println("查詢結束");
}
//查詢滿足某條件的信息並打印出來
public void getNodeData(Teacher teacher)
{
int temp=0;
Node node=first;
for(int i=0;i<len-1;i++)
{
node=node.next;
if(node.teacher.getSno()==teacher.getSno())
{
System.out.println("查詢的教工信息是:");
node.display();
temp++;
System.out.println("查詢結束1");
}
}
if(temp==0)
{
System.out.println("未查詢到教工信息");
System.out.println("查詢結束");
}
}
//將所有的數據打印出來
public void PrintAll()
{
Node node=first.next;
while(node!=first)
{
node.display();
node=node.next;
}
}
public static void main(String[] args)
{
CircleLinkList cll=new CircleLinkList();
//cll.PrintAll();
Teacher teacher=new Teacher("001","小明","男",22,"1222","wewew");
cll.addNodeEnd(teacher);
Teacher teacher1=new Teacher("001","小明","男",23,"1222","wewew");
cll.addNodeEnd(teacher1);
Teacher teacher2=new Teacher("002","小明","男",22,"1222","wewew");
cll.addNodeEnd(teacher2);
Teacher teacher3=new Teacher("003","小明","男",22,"1222","wewew");
cll.addNodeFirst(teacher3);
Teacher teacher4=new Teacher("004","小明","男",22,"1222","wewew");
cll.addNode(2,teacher4);
// cll.deleteNodeEnd();
// cll.deleteNodeFirst();
cll.deleteNode(6);
//cll.getNodeIndex(2);
cll.PrintAll();
// Teacher teacher5=new Teacher("001","小紅","男",22,"1222","wewew");
// cll.getNodeData(teacher5);
}
}
使用的Node和Teacher類與上一篇的Teacher和Node類一樣。