四、双向链表复制

四、双向链表复制

题目描述

设一带头结点的双向循环链表表示的线性表:L =(a1, a2, …… , an)
请写出一个时间复杂度为O(n)的算法,将L改造为:L =(a1, a2, ……, an-1, an, an-1, ……, a2, a1)

预设代码:

/* PRESET CODE BEGIN - NEVER TOUCH CODE BELOW */

/*
设一带头结点的双向循环链表表示的线性表:
L =(a1, a2, …… , an)
请写出一个时间复杂度为O(n)的算法,将L改造为:
L =(a1, a2, ……, an-1, an, an-1, ……, a2, a1)
*/

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

typedef int ElemType;
typedef struct DuLNode {
    ElemType        data;      // 数据域
    struct DuLNode  *prior;	   // 指向前驱的指针域
    struct DuLNode  *next;	   // 指向后继的指针域
} DuLNode, * DuLinkList;

// 函数原型 
void out_next(DuLinkList);
void out_prior(DuLinkList);
void rcopy(DuLinkList);		//这是你要编写的函数 

// 函数定义 
void out_next(DuLinkList DHead)
{	DuLinkList p = DHead->next; 
	while ( p != DHead )
	{	printf("%d,", p->data);
		p = p->next;
	}
	printf("\n");
}
void out_prior(DuLinkList DHead)
{	DuLinkList p = DHead->prior; 
	while ( p != DHead )
	{	printf("%d,", p->data);
		p = p->prior;
	}
	printf("\n");
}

int main()
{	DuLinkList DHead, p;
	int num;
	
	DHead = (DuLNode*)malloc( sizeof(DuLNode));
	DHead->data = -1;
	DHead->prior = DHead->next = DHead;   	// 生成表头

	scanf("%d", &num);
	while ( num != -1 )
	{	p = (DuLNode*)malloc( sizeof(DuLNode));
		p->data = num;
		p->next = DHead->next;	// 1.链接p的next链 
		DHead->next = p;		// 2.链接DHead的next链
		p->next->prior = p;		// 3.链接p的next的prior链
		p->prior = DHead;		// 4.链接p的prior链
		scanf("%d", &num);
	}
	printf("Link  next:");	out_next( DHead );
	printf("Link prior:");	out_prior( DHead );
	rcopy( DHead );
	printf("NewL  next:");	out_next( DHead );
	printf("NewL prior:");	out_prior( DHead );
	return 0;
}
/**************************************
void rcopy(DuLinkList DHead)
{
    This function is wating for you.
}
***************************************/

/* PRESET CODE END - NEVER TOUCH CODE ABOVE */
测试输入期待的输出时间限制内存限制额外进程
测试用例 11 2 3 4 5 -1Link next:5,4,3,2,1,
Link prior:1,2,3,4,5,
NewL next:5,4,3,2,1,2,3,4,5,
NewL prior:5,4,3,2,1,2,3,4,5,
1秒64M0
测试用例 210 20 -1Link next:20,10,
Link prior:10,20,
NewL next:20,10,20,
NewL prior:20,10,20,
1秒64M0
测试用例 31 2 3 4 5 6 7 8 9 10 11 12 -1Link next:12,11,10,9,8,7,6,5,4,3,2,1,
Link prior:1,2,3,4,5,6,7,8,9,10,11,12,
NewL next:12,11,10,9,8,7,6,5,4,3,2,1,2,3,4,5,6,7,8,9,10,11,12,
NewL prior:12,11,10,9,8,7,6,5,4,3,2,1,2,3,4,5,6,7,8,9,10,11,12,
1秒64M0

解题思路

函数参数传入的是头结点Dhead的位置,Dhead->prior 即找到an结点。使用两个指针pq,其中p指向an结点。

p指针向左扫描一个位置,就利用q指针向右建立一个结点,仿照main函数中的操作建立双向循环链表即可。

上机代码

void rcopy(DuLinkList DHead)
{
	//找到an结点
	DuLinkList p = DHead->prior, q=NULL;

	//建立双向循环链表
	while(p->prior != DHead)
	{
		p = p->prior;
		
		q = (DuLNode*)malloc(sizeof(DuLNode));
		q->data = p->data;
		q->prior = DHead->prior;
		q->prior->next = q;
		q->next = DHead;
		q->next->prior = q;
	}
}
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值