王道数据结构第二章2.20题

在这里插入图片描述
这道题之前有难到我的一个点是,如何去将最近访问的节点排在频度相同的节点前面。

这道题解决方法就是:当你每找到一个想要找的值,就将其从链表上摘除掉,然后,在链表中寻找它应该插入的位置。这里的话,也就是比较频度值,当我们的频度值相同的时候,我们只要也采取将节点插入到它们前面的策略,就可以实现将最近访问的节点排在频度相同的节点前面。

代码如下:

#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;
}

运行截图:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

五月的天气

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值