2024王道408数据结构 P39 T20
思考过程
- 首先还是先看题目,这题有一点繁琐,有题意可知我们先要找到data值为x的结点,然后让该结点的f值+1,最后再把它从链表里删除,插入到合适的位置让链表降序排列。
- 明确了题目的意思之后我们先设指针p和q,
struct node *q, *p = L->next;
p用来遍历链表找到值为x的结点,我们直接while (p && p->data != x) p = p->next
,这样让p就直接到找值为x的结点,我们假设链表长这个样子,x为3,如下图所示 - 这时候我们就把值为3的结点的f+1,+1之后我们就可以删除这个结点了,
if (p->next != NULL) p->next->prior = p->prior//如果该结点正好是链表中的最后一个结点时就不用执行这一步 ; p->prior-next = p->next;
这一步就是把该结点删除,之后让q指针指向p的前驱结点,如下图所示 - if判断q指针的f值是否>p指针的f值,如果大于的话就表示p指针指向的结点应该插入在这个位置,如果小于或等于的话就让q指针往前移动
while (q != L && q->f <= p->f) q = q->prior;
这一步是为了让q找到适合p插入的位置。 - 找到适合插入的位置之后就是插入结点了。
最后完整代码附上
//
// Created by 黎圣 on 2023/7/26.
//
#include "iostream"
typedef struct node
{
int data, f;
struct node *next, *prior;
}*linklist;
//我举的例子
int a[5] = {1,2,3,4,5};
int n = 5;
//创建双链表
void CreateTowaylist(linklist &L)
{
L = (linklist)malloc(sizeof(struct node));
struct node *s;
struct node *r = L;
L->prior = NULL;
L->next = L;
for (int i = 0; i < n; i++)
{
s = (linklist)malloc(sizeof(struct node));
s->data = a[i];
s->f = 0;
s->next = r->next;
r->next->prior = s;
r->next = s;
s->prior = r;
r = s;
}
r->next = NULL;
}
//打印出来方便我看
void display(linklist L)
{
struct node *s = L->next;
while (s)
{
printf("%d ", s->data);
s = s->next;
}
printf("\n");
}
//题目最主要的代码
linklist Locate(linklist &L, int x)
{
struct node *q, *p = L->next;
while (p&& p->data != x)
p = p->next;
if (!p) printf("x不存在");
else
{
p->f++;
//双向链表删除结点
if (p->next != NULL) p->next->prior = p->prior;//如果此时p是链表中最后一个值的话就可以不用做这一步了
p->prior->next = p->next;
q = p->prior;
while (q != L && q->f <= p->f) q = q->prior;//让q去找适合p结点插入的地方
//双向链表插入结点
p->next = q->next;
q->next->prior = p;
p->prior = q;
q->next = p;
}
return p;
}
int main()
{
linklist L;
CreateTowaylist(L);
display(L);
Locate(L, 3);
display(L);
return 0;
}
这题我也是卡了好久好久不知道哪出了问题,花的时间也很多,最后还是感谢b站up主@吸血小金鱼,思路都来自于她。