数组模拟双链表
雙鏈表
實(shí)現(xiàn)一個(gè)雙鏈表,雙鏈表初始為空,支持5種操作:
(1) 在最左側(cè)插入一個(gè)數(shù);
(2) 在最右側(cè)插入一個(gè)數(shù);
(3) 將第k個(gè)插入的數(shù)刪除;
(4) 在第k個(gè)插入的數(shù)左側(cè)插入一個(gè)數(shù);
(5) 在第k個(gè)插入的數(shù)右側(cè)插入一個(gè)數(shù)
初始化
雙鏈表,需要開三個(gè)數(shù)組。
e[]存放該節(jié)點(diǎn)的數(shù)值,
l[] 數(shù)組存放該節(jié)點(diǎn)左邊的節(jié)點(diǎn),
r[]數(shù)組存放該節(jié)點(diǎn)右邊的節(jié)點(diǎn)。
初始化:使用哨兵節(jié)點(diǎn)0和1,下標(biāo)為0的節(jié)點(diǎn)記為頭結(jié)點(diǎn)head,下標(biāo)為1的節(jié)點(diǎn)記為尾節(jié)點(diǎn)tail。
void init(){r[0]=1,l[1]=0;idx=2; }插入節(jié)點(diǎn)
在下標(biāo)為k的節(jié)點(diǎn)右邊插入節(jié)點(diǎn)數(shù)值為x,該節(jié)點(diǎn)的下標(biāo)為idx,首先需要e[idx]=x;然后分為四步,
step1:看該節(jié)點(diǎn)的右節(jié)點(diǎn)
step2:看該節(jié)點(diǎn)的左節(jié)點(diǎn)
step3:看原來的右節(jié)點(diǎn)的左節(jié)點(diǎn)
step4:看k的右節(jié)點(diǎn)
需要注意的是:step3和step4不能交換順序,這是因?yàn)閞[k]存在被提前更新的風(fēng)險(xiǎn)。
void add(int k,int x){e[idx]=x;r[idx]=r[k];l[idx]=k;l[r[k]]=idx;//該步在前,防止r[k]被提前更新r[k]=idx;idx++; }
在k節(jié)點(diǎn)左邊插入一個(gè)節(jié)點(diǎn),數(shù)值為x,相當(dāng)于求l[k]l[k]l[k] 的右節(jié)點(diǎn),只需要調(diào)用上述的add函數(shù),將k改為k左邊的節(jié)點(diǎn)l[k]l[k]l[k]。
刪除節(jié)點(diǎn)
刪除下標(biāo)為k的節(jié)點(diǎn),只需要使得k的左節(jié)點(diǎn) l[k]l[k]l[k]的右節(jié)點(diǎn)為r[k]r[k]r[k],相反,k的右節(jié)點(diǎn)r[k]r[k]r[k]的左節(jié)點(diǎn)變?yōu)?span id="ozvdkddzhkzd" class="katex--inline">l[k]l[k]l[k]。
void remove(int k){r[l[k]]=r[k];l[r[k]]=l[k]; }本題需要注意:
因?yàn)?和1號節(jié)點(diǎn)已經(jīng)占用,所用第k個(gè)節(jié)點(diǎn)對應(yīng)的是下標(biāo)為k+1的節(jié)點(diǎn)。比如第1個(gè)節(jié)點(diǎn),對應(yīng)的下標(biāo)是2.
ac代碼
#include<iostream> using namespace std; const int maxn=1e5+10;int l[maxn],r[maxn],e[maxn],idx;//初始化 void init(){//0表示左端點(diǎn),1表示右端點(diǎn)r[0]=1,l[1]=0;idx=2;//因?yàn)?和1已經(jīng)被占用 }//在下標(biāo)為k的節(jié)點(diǎn)的右邊,插入一個(gè)點(diǎn)int add(int k,int x){e[idx]=x;r[idx]=r[k];l[idx]=k;l[r[k]]=idx;r[k]=idx;idx++; }//刪除第k個(gè)點(diǎn) void remove(int k){r[l[k]]=r[k];l[r[k]]=l[k]; } int main(){init();int m,k,x;string op;cin>>m;while(m--){cin>>op;//cout<<op<<endl;if(op=="R"){cin>>x;add(l[1],x);}else if(op=="L"){cin>>x;add(0,x);}else if(op=="D"){cin>>k;remove(k+1);}else if(op=="IL"){cin>>k>>x;add(l[k+1],x);}else if(op=="IR"){cin>>k>>x;add(k+1,x);}}for(int i=r[0];i!=1;i=r[i]) cout<<e[i]<<" ";return 0;}總結(jié)
- 上一篇: 易收付是哪家支付公司
- 下一篇: opencv图片处理和摄像头边缘检测