JAVA單循環鏈表和雙循環鏈表簡單操作
- 1、刪除單循環鏈表某結點的直接前驅點
- 2、三個循環鏈表儲存一個循環鏈表的不同類字符
- 3、有一雙鏈表,每個結點中除有 prior、data 和 next 域外,還有一訪問頻度 域freq,在鏈表被啓用前,其值均初始化爲零。每當在鏈表上進行一次LOCATE(L,x) 運算,元素值爲 x 的結點中 freq 域的值增 1,並使此鏈表中結點保持按 freq 遞減 的順序排列,以便使頻繁訪問的結點總是靠近表頭。設計滿足上述要求的LOCATE 算法。(問題描述是c/c++版的,使用JAVA寫這段代碼的時候是不需要傳遞LOCATE裏面的L的,因爲此時L是鏈表本身,L實際上就是this)
- 我們可以參考下面的圖,可以以結點3爲例畫一下圖(圖中的結點1是不保存數據的,實際上未參與操作)
1、刪除單循環鏈表某結點的直接前驅點
問題描述:假設在長度大於 1 的單循環鏈表中,既無頭結點也無頭指針。s 爲指向某 個結點的指針,試編寫算法刪除結點*s 的直接前驅結點。
這裏考慮的是:既然是刪除某個節點的直接前驅,舉個例子:假設現在我們有編號爲 1 2 3 4 5 的5 個結點,現在我們要刪除結點3的直接前驅結點,也就是2,那麼只需要讓結點 1 的next指向3就可以了,直接越過2,這樣就實現了。
不過這裏有一個問題,就是如果說輸入 2,那麼我們要刪除1,也就是讓5的next指向2,這時候會出錯,我們需要加一個判定爲表尾時的特殊情況
如果當前節點的下一個結點的下一個結點是我們輸入的結點,那麼就讓當前結點的next指向下一個結點的下一個結點(這裏要考慮一下當前結點是不是表尾的結點)
public void Delete(char e ){//刪除某結點直接前驅結點的方法
Node_lp current=this.header;
// Node_lp p=this.header;
for (int i = 0; i < size; i++) {// O(n)
if (current.next.next.getData()==e) {//如果當前節點的下一個結點的下一個結點是我們輸入的結點
if(tail.equals(current)){//如果當前結點是尾結點,那麼讓當前結點的指向下一個結點的下一個結點
current.setNext(current.next.next);
header=current.next;//然後此時需要修改header爲當前結點的下一個結點,否則header仍然是原來的頭節點
size--;
break;
}
current.setNext(current.next.next);//非特殊情況,同上
size--;
break;
}
current = current.next;
}
System.out.println("刪除後的鏈表:"+this);
}
2、三個循環鏈表儲存一個循環鏈表的不同類字符
問題描述:已知由單鏈表表示的線性表中,含有三類字符的數據元素(如:字母、 數字和其它字符),設計算法構造三個以循環鏈表示的線性表,使每一個表中只 含同一類的字符,且利用原表中的結點空間作爲這三個表的空間。(頭結點可以 另闢空間)
(實際上這裏我偷懶了,沒用原空間)
(實際上這裏我偷懶了,沒用原空間)
(實際上這裏我偷懶了,沒用原空間)
public void divi_3(){
Node current=header;
Loop_list a1=new Loop_list();
Loop_list a2=new Loop_list();
Loop_list a3=new Loop_list();
while(current!=null){//O(n)
if((current.getData()>='A' && current.getData()<='Z')||(current.getData()>='a' && current.getData()<='z')){
a1.add(current.data);
}
else if(current.getData()>='0' && current.getData()<='9'){
a2.add(current.data);
}
else{
a3.add(current.data);
}
current=current.next;
}
System.out.println("字母:"+a1);
System.out.println("數字:"+a2);
System.out.println("符號:"+a3);
}
3、有一雙鏈表,每個結點中除有 prior、data 和 next 域外,還有一訪問頻度 域freq,在鏈表被啓用前,其值均初始化爲零。每當在鏈表上進行一次LOCATE(L,x) 運算,元素值爲 x 的結點中 freq 域的值增 1,並使此鏈表中結點保持按 freq 遞減 的順序排列,以便使頻繁訪問的結點總是靠近表頭。設計滿足上述要求的LOCATE 算法。(問題描述是c/c++版的,使用JAVA寫這段代碼的時候是不需要傳遞LOCATE裏面的L的,因爲此時L是鏈表本身,L實際上就是this)
//這個鏈表在建立的時候是有頭結點的,頭節點裏什麼都沒有存
public void LOCATE(char x){//O(n+m)
Node current=header.next;//操作的開始先略過空的頭結點
int k;
while (current!=null&¤t.data!=x)//找到這個輸入的x之前一直往下走
{
current=current.next;
}
Node tem=header.next;//讓臨時結點爲第一個保存數據的結點
current.freq++;//當前結點值域+1
while(tem.freq>=current.freq){//讓臨時結點從頭開始找,找到值域大於等於當前結點的那個結點
tem=tem.next;//讓它向下走=移動一個
}
current.prior.next=current.next;//先將當前結點的前一個結點的next指向當前結點的後一個結點
current.next.prior=current.prior;//再將當前結點的後一個結點的prior指向當前節點的前一個結點
//此時當前結點只有piror和next連接它的前一個結點和後一個結點了
//但是它的前一個結點和後一個結點都不指向它了,我們可以認爲已經把它從鏈表上“卸”下來了
current.prior=tem.prior;//此時再將當前結點的prior指向臨時結點的前一個結點
current.next=tem;//再讓當前結點的next指向臨時結點
tem.prior.next=current;//然後讓臨時結點前一個結點的next指向當前結點,
tem.prior=current;//再把臨時結點的prior指向當前結點,這樣就把current又掛到鏈表上了
}
我們可以參考下面的圖,可以以結點3爲例畫一下圖(圖中的結點1是不保存數據的,實際上未參與操作)
想看完整代碼可以私信我(雖然寫得很辣雞)(我的圖好像掛了 發不上來 有點可惜)