1. 程式人生 > >單鏈表反轉(C++)

單鏈表反轉(C++)

單鏈表是很基礎的演算法題
有至少三種方法可以實現:

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;
}