【数据结构】NOJ006 LOCATE操作

数据结构:双向循环链表
存储结构:链式存储
选择链式存储原因:节点要用freq域,用数组太麻烦
实现的操作:插入节点、访问节点、被访问节点需要往链表头移动

需要注意的地方:题中没有写清楚:当两个节点的prec相同时,该用什么顺序排列
比如下面这种情况:
假设用(val,freq)代表一个节点
假设原始链表为这样:
(头)→(1,2)→(2,1)→(3,0)→(4,0)
那么,访问了一次4后,节点4的freq从0变成了1,需要往前移动,移动之后的链表有下面两种可能性:
第一种(AC):(头)→(1,2)→ (2,1)→(4,1) →(3,0)
第二种(PE):(头)→(1,2)→ (4,1)→(2,1) →(3,0)
这就涉及到比较frec时,是<,还是<=的问题
根据本人测试,第一种是AC的,第二种是PE(我也不知道为啥不是WA?)

#include <iostream>
#include <stdlib.h>
#include <climits>

using namespace std;

typedef struct node
{
    char val;
    int freq;
    struct node *pre;
    struct node *next;
}*List;

int main()
{
	//初始化链表
    List L = (List)malloc(sizeof(struct node));
    L->freq = INT_MAX;	//头节点的freq改成最大值,这样方便之后比较	
    List tail = L;		//指向尾节点的指针,初始为头节点自己
    List tmp;
    //输入链表
    int m,n;
    cin>>m>>n;
    for(int i=0; i<m; i++) {
        tmp = (List)malloc(sizeof(struct node));
        cin>>tmp->val;
        tmp->freq = 0;		//新节点,freq=0
        tmp->pre = tail;	//插在队尾
        tail->next = tmp;	//插在队尾
        tmp->next = NULL;	//next暂时指向空
        tail = tmp;			//尾指针指向新节点
    }
    L->pre = tail;		//头节点的pre指向尾节点
    tail->next = L;		//尾节点的next指向尾节点

	//输入n个被访问的节点
    char x;
    List loc;
    while(n--) {
        cin>>x;
        //从前往后遍历,找节点x
        for(tmp=L->next; tmp!=L; tmp=tmp->next) {
        	//如果找到了
            if(tmp->val == x) {
            	//freq++,并先将这个节点从链表中取出来
                tmp->freq++;
                tmp->pre->next = tmp->next;
                tmp->next->pre = tmp->pre;

				//从这个节点原本的位置一路向前找
                loc=tmp->pre;
                while(loc->freq < tmp->freq)  //如果按照第一种情况处理,这里是<,会AC
                    loc=loc->pre;			  //如果按照第二种情况处理,这里是<=,会PE
                //退出while循环后,loc->freq 肯定>= tmp->freq
                //也就是需要把tmp插到loc后面
                tmp->pre = loc;
                tmp->next = loc->next;
                loc->next = tmp;
                tmp->next->pre = tmp;

                break;
            }
        }
    }
	//输出
    for(tmp=L->next; tmp->next!=L; tmp=tmp->next)
        cout<<tmp->val<<' ';
    cout<<tmp->val<<endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41727666/article/details/88982419