复制复杂(多指针)链表

题目:

复杂链表的复制。 在此链表中,每个节点不光含有一个指向下一个节点的next指针,还有一个指针any, 指向链表中任意节点或者 NULL。如图:

                    __________
                   V                  |
         A ---> B ---> C ---> D ---> E --->F
         |          |____^__________^   
         |__________|

方法一:

第一步:先复制原链表中的每一个节点。 

第二步:由于每一个节点上还有一个any指针需要填充,所以第二步依次遍历每一个节点在原链表中的位置,并依次填充。代码略。

此算法的复杂度:O(n^2)
算法二将对此做了优化,算法复杂度为:O(n)

方法二:

假设复杂链表用N表示,

第一步:给每一个N创建一个新的节点N',然后把创建好的每一个N'添加在N的后面。
第二步:通过遍历一次链表,将复制后的N'从长链表中分离出来,组成一个新的链表,新的链表即为复制后的复杂链表。 

此算法的复杂度:O(n)

代码:

#include <stdio.h>
#include <stdlib.h>
//声明节点样子
typedef struct node{
	char ch;
	struct node* next;
	struct node* any;
}Node;
//显示链表
void show(Node* phead)
{
	Node* tmp = phead;
	while(tmp != NULL){
		printf("%c\t", tmp->ch);
		if(tmp->any != NULL)
			printf("%c any is: %c\n", tmp->ch, tmp->any->ch);
		else 
			printf("%c any is NULL\n", tmp->ch);
		tmp = tmp->next;
	}
	printf("\n");
}
//创建复杂链表
Node* create(Node* phead, char ch)
{
	Node* tmp = malloc(sizeof(Node));
	tmp->ch = ch;
	tmp->next = NULL;
	tmp->any = NULL;
	Node* find = phead;

	if(phead == NULL)
		phead = tmp;
	else {
		while(find->next != NULL)
			find = find->next;
		find->next = tmp;
	}
	return phead;
}
//给链表中的另一个指针any赋值
void create_complex_list(Node* phead)
{
	Node* tmp = phead;
	tmp = tmp->next;

	Node* A = phead;
	A->any = tmp->next;
	
	Node* B = tmp;
	tmp = tmp->next->next;

	Node* D = tmp;
	D->any = B;
	tmp = tmp->next;

	B->any = tmp; 
}
//删除链表
void destory(Node* phead)
{
	Node* tmp = NULL;
	while(phead){
		tmp = phead;
		phead = phead->next;
		free(tmp);
	}
}
// 复制N节点为N',并加在N的后面,合成一条长链表
void clone_nodes(Node* phead){Node* clone = phead;if(phead == NULL){printf("Head is NULL. \n");exit(1);}while(clone != NULL){Node* tmp = malloc(sizeof(Node));tmp->ch = clone->ch;tmp->next = clone->next;tmp->any = clone->any;clone->next = tmp;clone = tmp;clone = clone->next;}}

//将长链表中的N'分离出来,形成新的复杂链表
Node* separate_nodes(Node* phead)
{
	int count = 0 , i = 1;
	Node* newhead = NULL;
	Node* newtail = NULL;
	Node* tmp = phead;

	while(tmp != NULL){
		count++;
		tmp = tmp->next;
	}
 
	Node* find = phead;
	while(find != NULL){
		if(find->ch == find->next->ch){
			tmp = find->next;
			find->next = tmp->next;			
			tmp->next = NULL;
			if(newhead == NULL){
				newhead = tmp;
				newtail = newhead;
			} else {
				newtail->next = tmp;
				newtail = newtail->next;
			}
		}
		find = find->next;
	}
	return newhead;
}

int main()
{
	Node* head = NULL;
	
	head = create(head, 'A');
	create(head, 'B');
	create(head, 'C');
	create(head, 'D');
	create(head, 'E');
	create(head, 'F');
	// 创建一个复杂的链表
	create_complex_list(head);

	printf("复制前: \n");
	show(head);

      // 复制N节点为N',并加在N的后面,合成一条长链表
	clone_nodes(head);	

      /**********************************************
	 将长链表中的N'分离出来,合成一条短的链表,此
       链表为复制后的复杂链表。
      ***********************************************/
	Node* new = separate_nodes(head);
	printf("复制后: \n");
	show(new);

	destory(head);

	return 0;
}

结果:



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值