这道题之前有难到我的一个点是,如何去将最近访问的节点排在频度相同的节点前面。
这道题解决方法就是:当你每找到一个想要找的值,就将其从链表上摘除掉,然后,在链表中寻找它应该插入的位置。这里的话,也就是比较频度值,当我们的频度值相同的时候,我们只要也采取将节点插入到它们前面的策略,就可以实现将最近访问的节点排在频度相同的节点前面。
代码如下:
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
typedef struct Node
{
int data;
int freq;
struct Node* prev;
struct Node* next;
}Node;
void print_list(Node* list);
//建立一个不循环双向链表
Node* Init_List()
{
Node* new = (Node*)malloc(sizeof(Node));
assert(new);
new -> data = 0;
new -> freq = 0;
new -> prev = new;
new -> next = NULL;
Node* p = new; //在插入过程中作为指示指针
//尾插法创建链表
int size;
printf("please enter the list size: ");
scanf("%d",&size);
printf("please enter the number: ");
int number;
for(int i = 1; i <= size; i++)
{
Node* add = (Node*)malloc(sizeof(Node));
assert(add);
scanf("%d",&number);
add -> data = number;
add -> freq = 0;
add -> prev = p;
p -> next = add;
add -> next = NULL;
p = p->next;
}
return new;
}
//对于党频度相同时,让最近一次访问的节点排在前面的做法就是,
//当地两个节点频度值相同时,我们让正在寻找位置的节点,插在和它频度值相同的节点前面即可
void freq_less(Node* head, int e)
{
Node* p = head->next;
Node* save;
//这里先假设链表值有重复
while(p)
{
Node* point = p->next;
if(p -> data == e)
{
p->freq ++;
//save = delete_node(p); //这里应该不能用外部函数,否则会断链
//将该节点从链表上摘除
save = p;
p = p->next;
save->prev->next = p;
p->prev = save->prev;
//看来是插入的锅
Node* q = head->next;
while(q)
{
int i = 1;
//printf("%d\n", q->freq);
if(q->freq <= save->freq)
{//往寻找需要插入的位置插入
Node* first = head;
for(int j = 1; j <= i ;j++)
{
first = first->next;
}
save->next = first;
save -> prev = first->prev;
first -> prev -> next = save;
first -> prev = save;
break;
}
else
{
i++;
q = q->next;
}
}//while
}//if
p = point;
}//while
}
void print_list(Node* list)
{
Node* p = list->next;
while(p)
{
printf("%d ",p -> data);
p = p->next;
}
printf("\n");
}
int main(int argc, char const *argv[])
{
Node* list = Init_List();
print_list(list);
freq_less(list,4);
freq_less(list,1);
freq_less(list,2);
freq_less(list,1);
freq_less(list,2);
print_list(list);
return 0;
}
运行截图: