連結串列實現按頻度訪問
阿新 • • 發佈:2018-11-10
對連結串列中的資料項進行訪問時頻度加1,保證頻繁訪問的結點總靠近表頭。
輸入輸出樣例:1組
#1
- 樣例輸入:
5 //表中元素個數 1 2 3 4 5 //表中元素內容 3 //一共locate3次 3 //第一次Locate 3 3 //第二次Locate 3 4 //第三次Locate 4
- 樣例輸出:
1 2 3 4 5 //原表中元素輸出 3 1 2 4 5 //第一次Locate 3 後的變化 3 1 2 4 5 //第二次Locate 3 後的變化 3 4 1 2 5 //第三次Locate 4 後的變化
這裡注意我們需要使用二級指標,否則我們進行的是值傳遞
#include <stdio.h> #include <stdlib.h> #define max 10 typedef struct lnode { int data; struct lnode *next; struct lnode *prior; int freq; } pnode, *DLinklist; pnode *creatnode(int data)//建立新結點 { pnode* node = (pnode*)malloc(sizeof(pnode)); node->data = data; node->prior = node->next = NULL; node->freq = 0; return node; } pnode *insert(DLinklist *s, int data) //在表尾插入,使用二級指標,進行地址傳遞 { pnode *node = creatnode(data); pnode *p; p = (*s); while(p->next != NULL) { p = p->next; } p->next = node; node->prior = p; node->next = NULL; return *s; } void Locate(DLinklist *s, int data) //訪問資料 { pnode *p, *q; p = (*s)->next; q=(*s); while(p && p->data != data)//q為p的前驅 { q = p; p = p->next; }//找出待刪結點 p->freq++;//頻度增加 while(q != *s && q->freq < p->freq)//找出比p的頻度大的結點,準備進行尾插 { q = q->prior; } p->prior->next = p->next; //刪除待刪結點 if(p->next != NULL) p->next->prior = p->prior; p->next = q->next; if(q->next != NULL) { q->next->prior = p; q->next = p; p->prior = q; }//插入適當位置,使其freq按遞增排列 } int main() { pnode *node; node = (pnode*)malloc(sizeof(pnode)); node->prior = node->next = NULL; int x, num, i = 0, locatecout; int arr[max]; scanf("%d", &num); while(i < num)//輸入資料 { scanf("%d", &x); node = insert(&node, x); i++; } pnode* p = node->next; while(p != NULL) { printf("%d%c", p->data, (p->next != NULL)?' ':'\n'); p = p->next; } scanf("%d", &locatecout); for(i = 0; i < locatecout; i++) { scanf("%d", &arr[i]); } for(i = 0; i < locatecout; i++) { Locate(&node, arr[i]); pnode* p = node->next; while(p != NULL) { printf("%d%c", p->data, (p->next != NULL)?' ':'\n'); p = p->next; } } return 0; }