JSMS38-复制复杂链表-剑指offer26

376 阅读2分钟

复杂链表的定义:

结构体:

typedef struct d{
	int data;
	struct d *next;          //指向下一个节点
	struct d *random;        //指向一个随机节点
}node;

题目就是要求复制这个复杂链表,通常有三种解法,解法2是利用空间换取效率,利用哈希表。解法3是直接在原来的链表的结点N后面创建需要复制的N',这个时候N'的random指向的是N->random->next,最后N'这个链表的随机指针就指向了相应的结点。然后分割这两个链表就行了。

#include <stdio.h>
#include <stdlib.h>

typedef struct d{
	int data;
	struct d *next;
	struct d *random;
}node;

node *creatLink(int *a,int *rand,int len)    //创建复杂链表
{
	node *tmp[len];
	int n=0;
	node *head=(node *)malloc(sizeof(node));
	head->data=a[n];
	node *ret=head;
	tmp[n]=head;
	 
	for(n=1;n<len;n++)
	{
		node *s=(node *)malloc(sizeof(node));
		s->data=a[n];
		s->next=NULL;
		head->next=s;
		head=s;
		tmp[n]=head;
	}
	n=0;
	for(node *t=ret;t;t=t->next)
	{
		t->random=tmp[rand[n++]];
	}
	return ret;
}

node *split(node *h)    //将N+N'链表分割,然后返回N'链表
{
	printf("I am here!"); 
	node *ret=h->next;
	node *p=h;
	node *q=h->next;
	for(;p;)
	{
		p->next=q->next;
		q->next=p->next;
		p=q->next;
		if(p!=NULL)
		{
			q=p->next;
		}
	}
	return ret;
}


node *copyLink(node *s)      //拷贝复杂链表
{
	node *p,*h,*ret;
	h=ret=s;
	
	for(;h;)		
	{	//这个for循环是遍历链表,将链表的N结点N'复制到结点N后面 
		node *n=(node *)malloc(sizeof(node));
		n->data=h->data;
		n->next=h->next;
		h->next=n;
		h=n->next;
	}
	for(h=s,p=s->next;h;)     //这里是将N'->random指向随机结点的循环
	{		
		p->random=h->random->next;
		h=h->next->next;
		if(h!=NULL)
		{
			p=h->next;
		}
	} 	
	ret=split(ret);
	return ret;
}

void PrintLink(node *s)    //打印链表
{
	printf("\n");
	for(;s;s=s->next)
	{
		printf("%d->",s->data);
	}
}

void PrintRand(node *s)   //打印复杂链表指向的random的值
{
	printf("\n");
	for(;s;s=s->next)
	{
		printf("%d->",s->random->data);
	}
}

 
int main()
{
	int a[]={0,1,2,3,4};
	int randArray[]={4,3,1,0,2};
	int len=sizeof(a)/sizeof(a[0]);
	node *s=creatLink(a,randArray,len);
	PrintLink(s); 
	PrintRand(s);
	node *cop=copyLink(s);
//	PrintLink(cop);
	PrintRand(cop);
	
}