複雜單鏈表的複製

題目:有一個複雜鏈表,其結點除了有一個m_pNext指針指向下一個結點外,還有一個m_pSibling指向鏈表中的任一結點或者NULL。其結點的C++定義如下:請完成函數ComplexNode* Clone(ComplexNode* pHead),以複製一個複雜鏈表。

//複雜鏈表的複製
struct ComplexNode{
	int m_nValue;
	ComplexNode *m_pNext;
	ComplexNode *m_pSibling;
};
//(1)以空間來取得效率,在O(n)時間內完成複製
ComplexNode* clone1(ComplexNode *pHead);
//(2)不消耗額外的空間,在O(n)時間內完成複製
ComplexNode* clone2(ComplexNode *pHead);

//(1)以空間來取得效率,在O(n)時間內完成複製
ComplexNode* clone1(ComplexNode *pHead){
	std::map<ComplexNode*, ComplexNode*> map_node;
	if(pHead == NULL) return NULL;

	//第一遍先完成複製
	ComplexNode* pcloneHead = NULL;
	ComplexNode* pclonePre = NULL;
	ComplexNode* p = pHead;
	while( p != NULL ) {
		ComplexNode *pcloneNode = new ComplexNode();
		pcloneNode->m_nValue = p->m_nValue;
		pcloneNode->m_pNext = NULL;
		pcloneNode->m_pSibling = NULL;

		if(pcloneHead == NULL) 
			pcloneHead = pclonePre = pcloneNode;
		else{
			pclonePre ->m_pNext = pcloneNode;
			pclonePre = pcloneNode;
		}

		//將clone節點和原始節點形成映射
		map_node.insert(std::make_pair(p, pcloneNode));
		p = p->m_pNext;
	}
	
	//第二遍完成pSibling變量的賦值
	p = pHead;
	ComplexNode *q = pcloneHead;
	while( p != NULL ) {
		//假設p節點的鄰接點是S,則在map中找到S節點對應的S'節點
		if( p->m_pSibling != NULL)
			q->m_pSibling = map_node.find(p->m_pSibling)->second;
		p = p->m_pNext;
		q = q->m_pNext;
	}
	return pcloneHead;
}


//(2)不消耗額外的空間,在O(n)時間內完成複製
ComplexNode* clone2(ComplexNode *pHead){
	if( pHead == NULL ) return NULL;
	
	ComplexNode *p = pHead;
	ComplexNode *pcloneHead = NULL;

	//第一遍依次在每個原始節點的後面插入一個clone節點
	while( p != NULL ){
		ComplexNode* pcloneNode = new ComplexNode();
		pcloneNode->m_nValue = p->m_nValue;
		pcloneNode->m_pNext = p->m_pNext;	//clone節點連接p後一節點
		pcloneNode->m_pSibling = NULL;
		p->m_pNext = pcloneNode;			//p節點連向當前節點

		p = pcloneNode->m_pNext;
	}

	//第二遍賦值每一個節點的sibling 節點
	p = pHead;
	while( p != NULL ){
		if( p->m_pSibling != NULL )
			p->m_pNext->m_pSibling = p->m_pSibling->m_pNext;
		p = p->m_pNext->m_pNext;
	}

	//第三遍分割節點
	p = pHead;
	pcloneHead = pHead->m_pNext;
	ComplexNode* q = pcloneHead;
	p = q->m_pNext; 
	
	//令q在前,p在後,先令q = p的後一節點,q 移一步;然後另p= q的後一節點,p後移一步
	while( p != NULL ){
		q->m_pNext = p->m_pNext;
		q = q->m_pNext;

		p->m_pNext = q->m_pNext;
		p = p->m_pNext;
	}
	return pcloneHead;
}


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