解题思路:
首先,输入该循环链表,在头结点指向为空时,即链表为空时,新增节点的指向就是其本身。以后新增节点以后,指针域保存的是第一个结点的地址。其次,进行排除。设置两个指针,分别为prev和p。p是prev的后继节点。p在每次数了3之后就删除该p所指向的节点。如果不需要删除,就移动两个指针。删除之后,就可以不移动指针。最后,当p和prev再次相遇在头结点时,循环结束。因此,设置一个second变量来判断是否是刚进入循环。


注意事项:
删除之后,就可以不移动指针。


参考代码:

#include<stdc++.h>

using namespace std;

struct Node

{

int data;

Node* next;

};

void Print(Node* p)

{

int res = p->data;

cout << res << " ";

}

Node* input(Node* head,int n)

{

Node* temp = head;

//插入节点

for (int i = 1; i <= n; i++)

{

Node* newNode = new Node();

newNode->data = i;

//如果头结点是空的,就自己指向自己

if (temp->next == NULL)

{

newNode->next = newNode;

temp = newNode;

head = newNode;

}

else//以后新增节点以后,指针域保存的是第一个结点的地址。

{

temp->next = newNode;

newNode->next = head;

temp = newNode;

}

}

return temp;

}

Node* Mani(Node* head)

{

Node* prev = head->next;

Node* p = prev;

int second = 0;

int i = 1;//从1开始,第一个不用移动指针

while (1)

{

if (second == 1)

{

break;//当p和prev再次相遇在头结点时,循环结束。因此,设置一个second变量来判断是否是刚进入循环。

}

if (i == 1)

{

i++;

continue;

}

else

{

if (i % 3 == 1)//删除之后,就可以不移动指针。

{

i++;

continue;

}

else {//如果不需要删除,就移动两个指针。本身在删除之前也是需要移动指针的

prev = p;

p = p->next;

}

if (i % 3 == 0)//p在每次数了3之后就删除该p所指向的节点

{


prev->next = p->next;

delete(p);

p = prev->next;

}

}

//判断删除的条件

i++;

//如果不用删的话,就移动指针

if (prev == p)

{

second = 1;

}

}

return p;

}

int main()

{

//输入n

int n;

cin >> n;


Node* head = new Node();

head->next = NULL;


head = input(head,n);//输入该循环链表,

// Print(head);

//遍历链表,当第二次达到prev = p = head时,退出循环,输出最后的结果

head = Mani(head);


//输出链表

Print(head);

return 0;

}



点赞(0)
 

0.0分

1 人评分

C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:

一点编程也不会写的:零基础C语言学练课程

解决困扰你多年的C语言疑难杂症特性的C语言进阶课程

从零到写出一个爬虫的Python编程课程

只会语法写不出代码?手把手带你写100个编程真题的编程百练课程

信息学奥赛或C++选手的 必学C++课程

蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程

手把手讲解近五年真题的蓝桥杯辅导课程

评论列表 共有 0 条评论

暂无评论