已知p指向双向循环链表中的一个结点,其结点结构为data、prior、next三个域,写出算法change(p),交换p所指向的结点和它的前缀结点的顺序。

#include<assert.h>
typedef struct SLnode
{
	int data;
	struct SLnode* prior;
	struct SLnode* next;
}SLnode,*SLnodelist;
//创建结点
SLnode* createhead(int data)
{
	SLnode* newnode = (SLnode*)malloc(sizeof(SLnode));
	newnode->data = data;
	newnode->next = newnode->prior = newnode;
	return newnode;
}
//初始化哨兵位
SLnode* ListInit()
{
	SLnode* newnode = createhead(0);
}
//尾插
void ListPushBank(SLnode* plist, int x)
{
	assert(plist);
	SLnode* ret = plist->prior;
	SLnode* newnode = createhead(x);

	ret->next = newnode;
	newnode->next = plist;
	newnode->prior = ret;
	plist->prior = newnode;
}
void printlist(SLnode* plist)
{
	SLnode* ret = plist->next;
	while (ret != plist)
	{
		printf("%d->", ret->data);
		ret = ret->next;
	}
	printf("NULL\n");
}
void change(SLnodelist p)
{
	SLnodelist q;
	q = p->prior;

	q->prior->next = p;
	p->prior = q->prior;

	q->next = p->next;
	p->next->prior = q;

	q->prior = p;
	p->next = q;

}
int main()
{
	int n, num;
	SLnode* plist = ListInit();
	printf("请输入链表的长度\n");
	scanf("%d", &n);
	printf("请输入元素\n");
	for (int i = 0; i < n; i++)
	{
		scanf("%d", &num);
		ListPushBank(plist,num);
	}
	printf("双链表的元素如下\n");
	printlist(plist);
	printf("请输入你要交换的的结点的值\n");
	SLnodelist q = (SLnodelist)malloc(sizeof(SLnode));
	scanf("%d", &q->data);
	SLnodelist p;
	p = plist->next;
	while (p != plist)
	{
		if (p->data == q->data)
		{
			change(p);
			break;
		}
		else
		{
			p = p->next;
		}
	}
	printf("交换后\n");
	printlist(plist);
	return 0;
}

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 算法change(p)的步骤如下: 1. 如果p为空或者p的前驱结点为空,则直接返回。 2. 定义一个临时变量temp,将p的前驱结点赋值给temp。 3. 将p的前驱结点的前驱结点的next指针指向p。 4. 将p的next指针指向temp。 5. 将p的前驱结点的next指针指向p的next指针所指向结点。 6. 如果p的next指针不为空,则将p的next指针所指向结点的prior指针指向p的前驱结点。 7. 如果p的前驱结点的prior指针不为空,则将p的前驱结点的prior指针指向p。 8. 返回。 ### 回答2: 算法change(p)的实现步骤如下: 1. 首先判断p是否为空,若为空则返回。 2. 判断p所指向结点是否为链表的头结点,若是则返回。 3. 定义两个指针q和r,分别指向p的前驱结点和p所指向结点。 4. 将p的前驱结点的next指针指向p的下一个结点,保证链表的连续性。 5. 将p的前驱结点赋值给p所指向结点的prior指针,保证链表的双向性。 6. 将p所指向结点赋值给p的前驱结点的next指针,保证链表的双向性。 7. 将p所指向结点的next指针指向p的前驱结点,保证链表的双向性。 8. 将p的next指针指向p所指向结点的next指针,保证链表的连续性。 9. 将p所指向结点的next指针赋值给p所指向结点的prior指针,保证链表的双向性。 10. 将p所指向结点赋值给p所指向结点的next指针的前驱结点,保证链表的双向性。 11. 返回链表。 该算法的时间复杂度为O(1),对于双向循环链表,只需要进行常数次的操作即可完成结点和其前驱结点交换。 ### 回答3: 算法change(p)的实现思路如下: 1. 判断p是否为空指针或p所指向结点是否为链表的头结点,如果满足条件,则无法交换,直接返回。 2. 获取p所指向结点的前驱结点pre和后继结点next,分别通过p->prior和p->next指针获取。 3. 如果pre为头结点,则将链表的头结点修改为p所指向结点。 4. 将p所指向结点与pre结点的前驱结点pre_prev连接。 5. 将p所指向结点与其后继结点next连接。 6. 将pre_prev结点与p所指向结点连接。 7. 将p所指向结点的前驱结点修改为pre_prev。 8. 将p所指向结点的后继结点修改为pre。 9. 返回修改后的链表。 具体的算法实现如下: ```cpp void change(Node *p) { if (p == NULL || p->prior == NULL) { return; // 无法交换,直接返回 } Node *pre = p->prior; Node *next = p->next; if (pre == head) { head = p; // 若pre为头结点,则修改头结点 } Node *pre_prev = pre->prior; pre_prev->next = p; p->prev = pre_prev; p->next = pre; pre->prev = p; pre->next = next; if (next != NULL) { next->prev = pre; } } ``` 以上是算法change(p)的具体实现,核心思想是通过调整各个结点之间的连接关系实现结点交换。该算法的时间复杂度为O(1)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值