四、双向链表复制
题目描述
设一带头结点的双向循环链表表示的线性表: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 */
测试输入 | 期待的输出 | 时间限制 | 内存限制 | 额外进程 | |
---|---|---|---|---|---|
测试用例 1 | 1 2 3 4 5 -1 | Link 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秒 | 64M | 0 |
测试用例 2 | 10 20 -1 | Link next:20,10, Link prior:10,20, NewL next:20,10,20, NewL prior:20,10,20, | 1秒 | 64M | 0 |
测试用例 3 | 1 2 3 4 5 6 7 8 9 10 11 12 -1 | Link 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秒 | 64M | 0 |
解题思路
函数参数传入的是头结点Dhead
的位置,Dhead->prior
即找到an
结点。使用两个指针p
、q
,其中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;
}
}