數據結構習題——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;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章