單鏈表反轉(C++)
阿新 • • 發佈:2019-02-05
單鏈表是很基礎的演算法題
有至少三種方法可以實現:
1:將單鏈表儲存為陣列,然後按照陣列的索引逆序進行反轉。
2:使用三個指標遍歷單鏈表,逐個連結點進行反轉。
3:從第2個節點到第N個節點,依次逐節點插入到第1個節點(head節點)之後,最後將第一個節點挪到新表的表尾。
方法1的問題是浪費空間。方法2和方法3效率相當。一般方法2較為常用。
在這裡只貼出前兩種方法。
方法1:
bool List::printListFromTailToHead() {
Node* temp = m_pList; //m_pList即為頭節點
int lengthOfList= 0,len=0;
while( temp !=NULL)
{
lengthOfList ++; //算出連結串列長度
temp=temp->next;
}
vector<int> n(lengthOfList) ; //申請合適大小的容器vector
len = lengthOfList; //記錄以便列印
temp=m_pList;
while(lengthOfList> 0)
{
n[lengthOfList-1] =temp->data; //倒序放入資料
temp=temp->next;
lengthOfList--;
}
for(int i=0;i<len;i++) //正序列印
cout << n[i]<<endl; //若要得到新連結串列此處要修改為正序建立新連結串列
return true;
}
方法2:
bool List: :listReversal()
{
Node* p=NULL;
Node* q=NULL;
Node* r=NULL;
p=m_pList; //頭節點
q=p->next; //用來判斷迴圈停止的條件
while(q) //原則是要用先儲存,存完才能用,以免被覆蓋
{
r=q->next; //儲存下一個指向
q->next=p; // 修改指向
p=q; //儲存當前結點,以便下次迴圈使用時能夠找到
q=r; //向下迴圈
}
m_pList->next=NULL; //最後修改原頭指標為尾指標
while(p)
{
cout<<p->data<<endl;
p=p->next;
}
return true;
}
提示:
以上兩段程式碼需要配合以前筆記中單鏈表部分中Node.cpp以及List.cpp檔案中程式碼,此外,為了可以使用容器vector,不要忘記加入#include<vector>
為了便於驗證,在函式內打印出data,此非明智之舉。
驗證程式碼domo.cpp:
#include<iostream>
#include"List.h"
using namespace std;
int main(void)
{
Node node1;
node1.data=3;
node1.next=NULL;
Node node2;
node2.data=4;
node2.next=NULL;
Node node3;
node3.data=5;
node3.next=NULL;
Node node4;
node4.data=6;
node4.next=NULL;
Node node5;
node5.data=7;
node5.next=NULL;
List *pList = new List();
cout<<"insert from tail:"<<endl;
pList->ListInsertTail(&node1);
pList->ListInsertTail(&node2);
pList->ListInsertTail(&node3);
pList->ListInsertTail(&node4);
pList->ListInsertTail(&node5);
pList->ListTraverse();
cout<<"after reversal by way1:"<<endl;
pList->printListFromTailToHead();
//cout<<"after reversal by way2:"<<endl;
//pList->listReversal();
delete pList;
pList = NULL;
return 0;
}