数据结构习题——6LOCATE操作

time_limit

3000MS

memory_limit

10000KB

description

设有一个双向循环链表,每个结点中除有pre,data和next三个域外,还增设了一个访问频度域freq。在链表被起用之前,频度域freq的值均初始化为零,而每当对链表进行一次LOCATE(L,x)的操作后,被访问的结点(即元素值等于x的结点)中的频度域freq的值便增1,同时调整链表中结点之间的次序,使其按访问频度非递增的次序排列,以便始终保持被频繁访问的结点总是靠近表头结点。试编写符合上述要求的LOCATE操作的程序。

input

第一行输入双向循环链表的节点数m和被访问的节点数n,

第二行输入双向循环链表各节点的值,

第三行依次输入被访问的节点。

output

输出符合上述要求的双向循环链表。

输出经过n次LOCATE后的链表。

sample_input

7 1

a b c d e f g

d

sample_output

d a b c e f g

#include <stdio.h>
#include <stdlib.h>
typedef struct DNode{
    char c;
    struct DNode *llink;
    struct DNode *rlink;
    int freq;
    //int turn;
}DNode,*PDNode;

typedef struct DList{
    PDNode head,tail;
}DList,*PDList;

PDList init_dlist(int m,char *s)
{
    int i;
    PDNode pl,pr,pn;
    PDList plist;
    plist=(PDList)malloc(sizeof(DList));
    plist->head=pl=(PDNode)malloc(sizeof(DNode));
    plist->tail=pr=(PDNode)malloc(sizeof(DNode));
    pl->rlink=pl->llink=pr;			//创建循环双链表,头节点和尾节点,并不存储数据
    pr->llink=pr->rlink=pl;

    for(i=0;i<m;i++){
        pn=(PDNode)malloc(sizeof(DNode));
        //scanf("%c",&pn->c);		//出现bug,会读进   " \n "
        pn->c=s[i];
        pn->llink=pl;
        pn->rlink=pr;
        pl->rlink=pn;
        pr->llink=pn;
        pl=pl->rlink;
        pn->freq=0;
        //pn->turn=i;
    }
    return plist;
}

void locate(PDList plist,char *s,int m,int n)
{
    int i;
    char a,t;
    PDNode pn,pend,pbegin,pi,pj;
    pn=plist->head->rlink;
    for(i=0;i<n;i++){
        a=s[i];
        while(pn->c!=a){
            pn=pn->rlink;
        }
        pn->freq++;
    }
    //下面开始排序,以结构体中turn的大小作为freq相同时顺序的标准
    /****
        for(pi=pn->llink;pi->freq<=pn->freq;pi=pi->llink);		//从pn这个节点开始往前找与t他freq相同的节点的最左边节点  的前一个节点
        pi=pi->rlink;
		if(pi==pn)continue;		//pi即与他freq相同的最左边的节点
        for(pj=pi;pj->freq==pi->freq;pj=pj->rlink); //pj即与他freq相同的最右一个节点
        pj=pj->llink;
		for(;pn->turn>pi->turn;pi=pi->rlink)if(pi==pj){		//在pi和pj间找到pn所要插入的位置
			pi=pi->rlink;
			break;  }
        pi=pi->llink;

        pn->llink->rlink=pn->rlink,pn->rlink->llink=pn->llink;
        pn->llink=pi,pn->rlink=pi->rlink,pi->rlink->rlink=pn,pi->rlink=pn;  //pn插入目标位置
    }
    *******/

    /*******
    下列算法为:选择排序
    新建两个节点,将原有链表重新连接,原有链表置空
    找m轮,每轮中freq最大的记录再pj中,连接至新链表上
    ******/
    DNode dnhead,dntail;

    dntail=*(plist->tail);
    dnhead=*(plist->head);
    PDNode phead=&dnhead,ptail=&dntail;
    phead->	rlink=plist->head->rlink;
    plist->	head->rlink->llink=phead;
    ptail->llink=plist->tail->llink;
    plist->tail->llink->rlink=ptail;

    plist->head->rlink=plist->head->llink=plist->tail;
    plist->tail->rlink=plist->tail->llink=plist->head;
    pn=plist->head;
    for(i=0;i<m;i++){
    	pj=pi=phead->rlink;
        for(pi=phead->rlink;pi!=ptail;pi=pi->rlink){
            if(pj->freq<pi->freq)pj=pi;
        }
        pj->llink->rlink=pj->rlink;
        pj->rlink->llink=pj->llink;
        //插入pj
        pn->rlink=plist->tail->llink=pj;
        pj->llink=pn,pj->rlink=plist->tail;
        pn=pn->rlink;
    }

}

void show(PDList plist)
{
    PDNode pn,pend;
    pn=plist->head->rlink;
    pend=plist->tail;
    while(pn!=pend){
        printf("%c ",pn->c);
        pn=pn->rlink;
    }
    printf("\n");
}
int main()
{
    int m,n,i;
    char s1[100],s2[100],c;
    scanf("%d%d",&m,&n);
    //fflush(stdin);
    for(i=0;i<m;i++){
		c=getchar();
		//if(i!=0||i!=m-1)scanf(" ");
		scanf("%c",&s2[i]);
    }
    PDList plist;
    plist=init_dlist(m,s2);
    //fflush(stdin);
    for(i=0;i<n;i++){
        c=getchar();
		//if(i!=0||i!=n-1)scanf(" ");
		scanf("%c",&s1[i]);
    }
    locate(plist,s1,m,n);
    show(plist);
    return 0;
}

 

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值