雙向迴圈連結串列的頻度自學習演算法
阿新 • • 發佈:2019-01-05
題目源自嚴奶奶的資料結構題集(c語言版) p19頁的Algo2.38
ps:嚴奶奶的書預設都是帶有頭結點的。
設有一個雙向迴圈連結串列,每個結點中除有prior,data,next三個域以外,還增設了一個訪問頻度域freq。在連結串列被啟用之前,freq域的值均被初始化為零,而每當對連結串列進行一次Locate(L,x)的操作之後,被訪問的結點(即元素值等於x的結點)中的頻度域freq的值便增加1,同時調整連結串列中結點之間的次序,使其按照訪問頻度非遞增的次序順序排列,一遍始終保持被頻繁訪問的結點總是靠近表頭結點。試編寫符合上述要求的Locate(L,x)操作的演算法。
思路:Locate到等於x的點,freq自增1,由於是遞減排列,p指標向前尋找到第一個比x的freq大或者相等的結點,插在p後面
程式碼
標頭檔案
//Status.h
#pragma once
#define TRUE 1
#define OK 1
#define FALSE 0
#define ERROR 0
#define OVERFLOW -1
typedef int Status;
//DuCycle_LinkList.h #pragma once #include <stdio.h> #include "Status.h" typedef int ElemType; typedef struct DuCycle_Lnode { ElemType data; struct DuCycle_Lnode * next; struct DuCycle_Lnode * prior; int freq; }DuCycle_Lnode,* DuCycle_List; Status Init(DuCycle_List &L); Status SelfLearning_Locate(DuCycle_List &L, ElemType e);//Algo2.38 Status Make_List(DuCycle_List &L); Status Trav_DuCycle_List(DuCycle_List L);
函式檔案
//fun.cpp #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #include "DuCycle_LinkList.h" Status Init(DuCycle_List &L) { L = (DuCycle_Lnode *)malloc(sizeof(DuCycle_Lnode)); if (!L) exit(OVERFLOW); L->freq = 0; L->prior = L->next = NULL; L->data = NULL; return OK; }//Init Status Trav_DuCycle_List(DuCycle_List L) { DuCycle_Lnode * p; p = L->next; if (L->next == NULL) return ERROR; while (p != L) { printf("%d(%d) ", p->data,p->freq); p = p->next; } /*putchar('\n'); p = L->next; while (p != L) { printf("%d", p->freq); p = p->next; }*/ putchar('\n'); return OK; }//Trav_DuCycle_List Status SelfLearning_Locate(DuCycle_List &L,ElemType e)//Algo2.38 //自學習的Locate演算法,結點中增加freq表示訪問的頻度 //每次訪問將自組所有織結點重新按照freq降序排列 { DuCycle_Lnode *p, *q; p = NULL; q = L->next; while (q->next!=L&&q->data!=e) { q = q->next; } if (q->data == e)//發現e { q->freq++; p = q->prior; while (p!=L&&p->freq<q->freq)//移動p到第一個比e的freq大的結點上,或者頭結點 { p = p->prior; } q->next->prior = q->prior; q->prior->next = q->next;//ditach q q->next = p->next;//rejoin q p->next->prior = q; p->next = q; q->prior = p; printf("element found.\n"); return OK; } printf("element not found.\n"); return ERROR;//未發現e }//SelfLearning_Locate Status Make_List(DuCycle_List &L) { int n; printf("plz input the node you want to add.\n"); scanf("%d", &n); printf("plz input %d numbers in.\n", n); for (int i = 0; i < n; i++) { ElemType e; scanf("%d", &e); DuCycle_Lnode *s= (DuCycle_Lnode *)malloc(sizeof(DuCycle_Lnode)); if (!s) return ERROR; s->data = e; s->freq = 0; if (L->next != NULL) { s->next = L->next; L->next->prior = s; L->next = s; s->prior = L; } else { L->next = s; L->prior = s; s->prior = L; s->next = L; } } printf("List make succeed.\n"); return OK; }//Make_List
主函式
//main.cpp
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include "DuCycle_LinkList.h"
#include "Status.h"
int main(void)
{
DuCycle_List L;
ElemType e;
int n;
Init(L);
Make_List(L);
Trav_DuCycle_List(L);
printf("input the element you want to locate.(not a number to quit)\n");
while (scanf("%d",&e))
{
SelfLearning_Locate(L, e);
Trav_DuCycle_List(L);
}
system("pause");
return 0;
}
執行結果如下:
第一篇部落格,寫的不好還請見諒。如果有錯誤的地方歡迎留言指出 :)