双向链表L每次访问元素后,元素按访问频度递减次序排列

来源:互联网 发布:mac快速认证 编辑:程序博客网 时间:2024/06/06 00:28

/*
问题描述:双向链表L(结点中含有fre频度),每次访问元素后,元素按访问频度递减次序排列
说明: 这个问题题非常向操作系统中应用的一些算法了,比如说涉及到内存、磁盘中数据的访问,换出等。这个链表中保存的是按照最近最常使用的顺序排列的。

*/

#include <iostream>using namespace std;typedef struct DNode{    int data;   //数据    DNode *pre,*next;   //前一个,后一个指针    int fre;        //访问频度,初始化为0}DNode,*DLinklist;void CreateDList(DLinklist &Dl){    DNode * head = new DNode,*temp;    head->fre = -1;    head->data = -1;    head->next = NULL;    head->pre = NULL;    int val;    cin>>val;    while(val != 9999)    {        temp = new DNode;        temp->fre = 0;        temp->data = val;        if(head->next != NULL)             head->next->pre = temp;        temp->next = head->next;        head->next = temp;        temp->pre = head;       // temp->next = NULL;       cin>>val;    }    Dl = head;}//按访问频繁度排序元素void Locate_x(DLinklist &DL,int x){    DNode * p = DL->next,*temp_pre = NULL,*temp_swa = NULL;    DNode *swa_bef = NULL,*swa_aft = NULL,*p_bef = NULL,*p_aft = NULL;   // cout<<"test"<<endl;    while(p != NULL)    {        if(x == p->data)        {            ++p->fre;            temp_pre = p->pre;            while(temp_pre -> fre != -1 && temp_pre->fre <= p->fre )            {                temp_pre = temp_pre->pre;            }                temp_swa = temp_pre->next;  //p的元素将放在temp_swa的元素前面                //如果前移的元素不等于本身                if(temp_swa != p)                {                    //p元素前移                    swa_bef = temp_swa->pre;    //temp_swa的前一个元素                    swa_aft = temp_swa->next;   //temp_swa的后一个元素                    p_bef = p->pre;             //p的前一个元素                    p_aft = p->next;             //p的后一个元素                    p_bef->next = p_aft;                    if(p_aft != NULL)                        p_aft->pre = p_bef;                    p->next = temp_swa;                    p->pre = swa_bef;                    swa_bef->next = p;                    swa_bef->next = p;                    temp_swa->pre = p;                }            break;        }        else            p = p->next;    }}//顺序输出单链表中的元素void PrintDList(DLinklist L){    DNode *p;    p = L->next;    while(p!=NULL)    {        if(p == L->next)            cout<<p->data;        else            cout<<" "<<p->data;        p = p->next;    }    cout<<endl;}

总结:对于链表的插入、删除有一点麻烦的就是会涉及到改变指针指向的问题。一不小心就会出现断链等错误。在这里采取了最直接的方法,就是把涉及到的结点都表示出来,这样虽然浪费了一点空间,但是,改变指针就方便多了。

其实在实际应用中还可以考虑一些简便的方法来处理注入交换结点、删除等问题。
比如说对于交换结点,我们可以直接交换其中的值,这样就不用改变指针了。对于删除可以采用一种叫做“懒惰删除”的方法,就是不删除,而是增加一个特殊标志,代表其删除了。这样也能达到简化的效果。

原创粉丝点击