1. 程式人生 > >c語言—複雜連結串列的複製

c語言—複雜連結串列的複製

所謂複雜連結串列,指的是連結串列中每個節點不僅有指向下一個節點的next指標,還有一個radom指標指向一個隨機節點,甚至可以指向自己,可以指向空。

typedef struct ListNode
{
	DataType data;
	struct ListNode* next;   //next指向下一個節點
	struct ListNode* radom;  //radom指向隨機節點
}ListNode;

所以複雜連結串列的複製考慮的因素就比較多,經過九九八十一難,我實現了這個功能。

最開始我是這樣認為的:


這是不對的,如果有連結串列中有相同的data,那就一定會出錯。

所以最好的辦法是:


ListNode* CopyList(ListNode* head)
{
	//1.插入節點  1 1 2 2 3 3 4 4 ……
	ListNode* cur = head;
	while(cur)
	{
		ListNode* next = cur->next;
		ListNode* copy = BuyNode(cur->data);
		cur->next = copy;
		copy->next = next;
		cur = next;
	}

	//2.這樣的話,拷貝的節點的radom一定在被拷貝的節點的radom的後面
	cur = head;
	while(cur)
	{
		ListNode* copy = cur->next;
		if(cur->radom != NULL)
		{
			copy->radom = cur->radom->next;
		}
		cur = copy->next;
	}

	//3.把新舊連結串列拆開,先拆一個節點當頭
	cur = head;
	ListNode* copyHead = NULL;//作新連結串列的頭
	ListNode* copyTail = NULL;//作新連結串列的尾

	while(cur)
	{
		ListNode* copy = cur->next;
		ListNode* next = copy->next;

		cur->next = next;

		if(copyHead == NULL)
		{
			copyHead = copy;
			copyTail = copy;
		}

		else
		{
			copyTail->next = copy;
			copyTail = copy;
		}

		cur = next;
	}

	return copyHead;
}

其中,BuyNode函式是這樣的:

ListNode* BuyNode(DataType data)
{
	ListNode* node = (ListNode*)malloc(sizeof(ListNode));
	assert(node);
	node->data = data;
	node->next = NULL;
	node->radom = NULL;
	return node;
}
以下是測試程式碼,這樣寫易於測試程式的對錯:
void test()
{
	ListNode* node1 = BuyNode(1);
	ListNode* node2 = BuyNode(2);
	ListNode* node3 = BuyNode(3);
	ListNode* node4 = BuyNode(4);

	node1->next = node2;
	node2->next = node3;
	node3->next = node4;

	node1->radom = node2;
	node2->radom = NULL;
	node3->radom = node3;
	node4->radom = node1;   //1->2  2->NULL  3->3  4->1

	ListNode* test = CopyList(node1);
}



通過驗證,程式正確。