雙向鍊錶的使用

2021-08-15 12:34:59 字數 1688 閱讀 6524

(本文僅為筆者學習,如有錯誤之處懇請各位讀者指正)

簡譯:你有一行盒子,從左到右依次編號為1,2,3,...,n。可以執行一以下4種指令:

指令保證合法,即x不等於y。例如,當n=6時在初始狀態下執行1 1 4後盒子序列為2 3 1 4 5 6。接下裡執行2 3 5.盒子序列變成2 1 4 5 3 6.在執行3 1 6,得到2 6 4 5 3 1.最終執行4,得到1 3 5 4 6 2.

輸入包含不超過10組資料,每組資料第一行為盒子個數n和指令條數m(1<=n,m<=100000),以下m行每行包含一條指令。每組資料輸出一行,即所有奇數字置的盒子編號之和。位置從左到右編號為1至n。

分析:採用雙向鍊錶,用left[i]和right[i]分別表示編號為i的盒子左邊和右邊的盒子編號(如果是0,表示不存在)。對於翻轉操作,如果真的去翻轉整條鏈則需要修改所有元素的指標。而實際上並不需要進行如此複雜的操作,在程式中增加乙個標誌位inv,表示有沒有翻轉操作(兩次翻轉可抵消:如果inv=1時又碰到一次4操作,則inv變為0)。

當碰到翻轉操作時將inv置1,由於並沒有對鍊錶進行翻轉,所以接下來當碰到1操作時需要轉化為2操作才能在為翻轉的鍊錶上執行(對鍊錶進行翻轉再將x移動到y的左邊=將x移動到y的右邊再對鍊錶進行翻轉),同理在inv=1的前提下,碰到2操作需要將其轉化為1操作再執行。最後根據inv的值進行不同的處理(inv=1時表示還需要將最後得到的鏈進行翻轉,inv=0時則不需要)。

(以下程式只是在陣列上模擬鍊錶和指標的操作,而非真正意義上的鍊錶和指標)

#include#define sum(n) n*(n+1)/2  // 等差數列求和 

using namespace std;

const int maxn = 100000+5;

int left[maxn],right[maxn]; // 鍊錶的左右指標陣列

// 連線兩個節點

void link(int l, int r)

int main()

right[0] = 1; // 頭結點的右指標指向1號節點

left[0] = n; // 頭結點的左指標指向尾結點

int op, x, y, inv = 0; // inv是否翻轉

while(m--)else if(op == 2)else if(op == 3)else if(left[x] == y)else

} }

} int odd = 0;

long long ans = 0;

for(int i=1; i<=n; i++)

// 盒子數為奇數時,翻轉後原先位於奇數字置上的盒子仍然位於奇數字置上,直接輸出ans

// 盒子數為偶數時,ans為翻轉後偶數字置上的和。用總和sum(n)減去ans得到翻轉後奇數字置上的和

if(inv && n%2==0)// 存在翻轉&&盒子個數為偶數

ans = (long long)sum(n)-ans;

printf("case %d: %lld\n", ++kase, ans);

} return 0;

}

雙向鍊錶的使用

1.單向鍊錶查詢的方向只能是乙個方向,而雙向鍊錶可以向前或者向後查詢 2.單向鍊錶不能自我刪除,需要借助輔助節點,而雙向鍊錶,則可以實現自我刪除,所以,單鏈表刪除節點時,總是想找到temp節點,temp是待刪除節點的前乙個節點2.1遍歷 遍歷方法和單鏈表一樣,只是可以向前,也可以向後遍歷 2.2新增...

mysql 雙向鍊錶 雙向鍊錶

雙向鍊錶是鍊錶變型,相比於單鏈表導航或者是向前和向後的兩種方式。以下是重要的術語來理解雙向鍊錶的概念 link 鍊錶的每個鏈路儲存資料稱為乙個元素。linkedlist linkedlist包含連線鏈結到名為首先第乙個鏈結,並稱為最後的最後乙個鏈結 last 雙向鍊錶表示 按照如上圖中所示,以下是要...

mysql的引雙向鍊錶 雙向鍊錶

public classdoublelinkedlist else 新增至鍊錶尾 paramnode public voidaddlast doublenode node else 按照某屬性的順序新增 paramnode public voidaddbyorder doublenode node ...