鏈表翻轉的兩種方法(遞歸+非遞歸)

          前天在論壇上看到有位同學在問鏈表轉置的問題,下面的人不是在別的地方拷貝來的代碼(還有錯誤),要麼就是一點解釋都沒有

 鏈表定義

typedef struct node
{
	ElemType data;
	struct node * next;

}ChainNode;

typedef struct
{
	ChainNode *head;

	int size;

	ChainNode *tail;
}List;


 

/*********************************************************
	總體思路就是將鏈表看作是兩條鏈
	每次都從舊鏈表裏面取第一個作爲新鏈表的表頭,

*********************************************************/
void ReserveList(List * plist)        //非遞歸實現,
{
	ChainNode * phead;	//新鏈表的頭 開始的第一個節點
	ChainNode * pt;		//舊鏈表的頭 開始的第二個節點
	ChainNode * pn;		//舊鏈表頭的下一個

	phead = plist->head;

	if(phead && phead->next&& phead->next->next)		//首先確定
	{
		phead = plist->head->next;	//新鏈表就是以第一個節點開始,依次在表頭添加節點,添加的節點是舊鏈表的第一個節點
		pt = phead->next;		//舊鏈表,舊鏈表被取走頭結點之後放入新鏈表的表頭,
		pn = pt->next;
		phead->next = 0;	
		
		while(pt)
		{
			pn = pt->next;		//pn是舊鏈表的第二個節點
			
			pt ->next = phead;	//取舊鏈表的第一個節點插入新鏈表
			phead = pt;		

			pt = pn;		//舊鏈表往後移動
		}
	}
	plist->head->next = phead;		//新鏈表重新賦值到整個鏈表
}

/*********************************************************
	遞歸思想,原理也是從就鏈表上依次取元素放入到新鏈表
	直到就鏈表被取完,
	開始的時候新鏈表是空的
*********************************************************/
ChainNode * ReserveListRe(ChainNode * oldlist,ChainNode * newlist)
{
	ChainNode * pt;
	
	pt = oldlist->next;		//取舊鏈表的表頭,pt是現在的舊鏈表

	oldlist->next = newlist;	//就舊鏈表插入到新鏈表

	newlist = oldlist;		//如果舊鏈表是空,表示舊鏈表被取完了,新鏈表就是翻轉之後的鏈表

	return (pt == NULL) ? newlist : ReserveListRe(pt,newlist);

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章