從尾到頭列印鍊錶
思路:先把鍊錶翻轉,然後將翻轉後的鍊錶列印出來
這種方法:因為多分配鍊錶節點指標,故可能會對記憶體的消耗要大一點
時間複雜度為o(n)
vector
printlistfromtailtohead(listnode *head)
head=p2;//鍊錶翻轉後,頭結點為p2
while(head!=null)
return a;
}
遞迴方法:占用記憶體要少
vector
dev;
vector
printlistfromtailtohead(listnode *head)
return dev;
}
鍊錶中倒數第k個結點
思路:先統計鍊錶中一共有的節點數:n
倒數第k個節點,則為正數第n-k+1個節點
正序找到這個節點
時間複雜度為o(n)
listnode *(listnode *phead,int k)
//以上統計所得為鍊錶的節點個數
count=count-k;//用來正序訪問用
phead=temp;//讓phead還是指向鍊錶的首位址
if(count>=0)
else
return null;
}
合併兩個排序的鍊錶
時間複雜度為o(n)
listnode* merge(listnode* phead1, listnode* phead2)
else
//把p2的當前節點插入新建鍊錶
}if(p1==
null)
cur->next=p2;
if(p2==
null)
cur->next=p1;
return p3->next;
}
刪除鍊錶中重複的節點
時間複雜度為 o(n)
listnode * deleteduplication(listnode *phead)
//若存在多個連續相同的值,則上述while迴圈結束後,pnext為最後乙個重複值的節點。
pdel=pnext;
p=pnext->next;//下乙個要比較的節點為當前重複值得最後乙個的下乙個
delete pdel;
}else
//當前節點不是重複值,則把這個節點鏈結在新建鍊錶中
temp->next=
null;//最後乙個節點為空
return pnew->next;
}
5.二叉搜尋樹與雙向鍊錶
輸入一棵二叉搜尋樹,將該二叉搜尋樹轉換成乙個排序的雙向鍊錶。要求不能建立任何新的結點,只能調整樹中結點指標的指向。
treenode *(treenode *root)
return cur;
}void convertnode(treenode *root,treenode *
&last_node)//注意此處形參為引用型別
6.鍊錶中環的入口結點
時間複雜度o(n)
listnode *entrynodeofloop(listnode *root)
return p1;}}
return
null;
}
如果要計算環中的長度:可以採用上述快慢指標相遇後,在繼續走,然後記錄從這次相遇到下一次相遇慢指標走過的步數,即為環中節點個數。
7.兩個鍊錶的第乙個公共結點
思路:找兩個鍊錶的公共節點,最暴力的解決辦法為:遍歷第乙個鍊錶的每個節點,然後在第二個節點中尋找是否存在與其相同的節點,如果存在,則返回第乙個存在相同的節點。這種方法如果鍊錶長度分別為m,n則時間複雜度為o(mn) 第二種方法是考慮從兩個鍊錶的尾部向前遍歷,最後乙個相同的節點為鍊錶的公共節點,因為單鏈表只存在乙個next指標,不能倒敘遍歷,這裡需要借助兩個棧。把兩個鍊錶元素分表放入兩個棧中,依次取棧頂元素。第乙個最後乙個相同的為第乙個公共節點。這種方法的時間複雜度為o(m+n)但是這種方法需要額外開闢棧空間,所以空間複雜度為:o(m+n)
第三種解決辦法:兩個鍊錶長度可能不同,我們先求出每個鍊錶的長度,然後求出兩個鍊錶長度差diff。讓長度大的鍊錶,先往前移動diff個節點,然後兩個鍊錶再一起移動。當兩個鍊錶移動到的節點相同時為第乙個公共節點。這種方法的時間複雜度為o(m+n)但是不需要開闢額外空間,空間複雜度節省。
int lengthoflist(listnode *phead)
return sum;
}listnode *firstcommonnode(listnode *phead1,listnode *phead2)
else
while(p1&&p2)
return null;
}
8.複雜鍊錶的複製
題目描述:
輸入乙個複雜鍊錶(每個節點中有節點值,以及兩個指標,乙個指向下乙個節點,另乙個特殊指標指向任意乙個節點),返回結果為複製後複雜鍊錶的head。(注意,輸出結果中請不要返回引數中的節點引用,否則判題程式會直接返回空)
思路:(1)先複製每乙個鍊錶節點圖1中所有節點,並且每複製乙個節點把其插入到原先節點的後邊如圖2 ;
(2)複製完所有節點後,則原先節點與新複製的節點構成乙個新鍊錶,但是每隔乙個都是新複製的鍊錶節點。根據這一規律,則原先乙個節點的random指標指向的節點,在新複製的節點中對應的應是原來指向的下乙個節點:new->random=old->random->next如圖3;
(3)當完成上述兩部分之後,則新結點的隨機指標已經指向正確,但是next指標指向錯誤,此時第乙個節點的複製節點的指標指向第二個節點,其實應該指向第二個節點的複製節點。所以需要調整一下,圖4 圖5
圖1
圖2
圖3
圖4
圖5
**如下:
randomlistnode* clone(randomlistnode* phead)
//把新複製節點的random指標正確指向
p=phead;
while(p)
//當random指標分配好之後,進行新複製節點next指標的調整
p=phead;//p指向新舊節點組成的鍊錶的首節點,也是原先鍊錶的第//乙個節點
head=p->next;//新複製鍊錶的首節點為組合鍊錶的第二個節點
while(p->next)//此處p知識新建鍊錶中正在經歷的節點,p要把所有的//節點經歷一次
return head;
}
劍指offer 鍊錶
單向鍊錶的結構定義 typedef int datatype struct listnode 問題1 往鍊錶的末尾新增乙個結點 給定頭結點,往末尾插入乙個結點 void insertnode listnode head,datatype key listnode p head while p nex...
劍指offer 鍊錶
鍊錶 鍊錶是一種動態資料結構 struct listnode 往鍊錶的末尾新增乙個節點的c 程式如下 void addtotail listnode phead,int value 注意第乙個引數phead是乙個指向指標的指標。當我們往乙個空鍊錶插入乙個結點時,else pnode m pnext ...
劍指offer 鍊錶
在乙個排序的鍊錶中,存在重複的結點,請刪除該鍊錶中重複的結點,重複的結點不保留,返回煉表頭指標。思路1 遞迴版 class solution 找到當前節點與下乙個節點不重複的點,從不重複的點開始遞迴 return deleteduplication phead next else 思路2 非遞迴版 ...