优先双链表

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了优先双链表相关的知识,希望对你有一定的参考价值。

题目:

设有一个双链表,每个结点中除有prior,data和 next这3个域外,还有一个访问频度域 freq,在链表被启用前其值均初始化为0。每当在在链表上进行一次查找操作Locate(L, x)时,令元素值为x的结点中的freq域的值增加1,并使此链表中的结点保持按访问频度域递减的顺序排列,以便使频繁访问的结点总是靠近表头

(1)首先创建一个双链表。
(2) 设计一个符合上述要求的Locate(L, x)函数。
(3) 具有输出显示访问频度功能。
(4) 要求程序通过一个主菜单进行控制,在主菜单界面通过选择菜单项的序号来调用各功能函数。

 

说明:

这个我做的乱七八糟,而且最最关键的排列还没有完成。链表的定义都出了问题,可惜现在是牵一发动全身,时间上也快交了,先暂且这样吧,以后再修,

 

代码:

common.h

 1 //全体公用的头文件
 2 
 3 #ifndef COMMON_H
 4 #define COMMON_H
 5 
 6 #include<stdio.h>
 7 #include<stdlib.h>
 8 #include<string.h>
 9 #include<malloc.h>
10 #include<windows.h>
11 
12 #define ERROR 0
13 #define OK 1
14 #define WR -1
15 
16 #endif
17 
18 //windows.h提供了sleep()和system("cls")
19 //用来暂定和清屏

 

functions.h

 1 #ifndef FUN_H
 2 #define FUN_H
 3 
 4 
 5 #include "common.h"
 6 #include "struct.h"
 7 
 8 
 9 int menu_select(int times);
10 int InitList(DoubleList *L);
11 void DestroyLIst(DoubleList L);
12 DoubleList CreateDCList(DoubleList L);
13 void Locate(DoubleList L);
14 
15 
16 int haha(int n);   
17 void waka(void);
18 void wrong(void);
19 void gotoxy(int x,int y);
20 
21 
22 #endif

 

struct.h

 1 //结构体定义
 2 
 3 
 4 #ifndef STR_H
 5 #define STR_H
 6 
 7 #include "common.h"
 8 
 9 
10 typedef struct DNode
11 {
12     int data,freq;
13     struct DNode *prior,*next;
14 }DNode,*DoubleList;
15 
16 
17 #endif

 

functions.c

  1 //函数 
  2  
  3 #include "common.h" 
  4 #include "struct.h" 
  5 #include "functions.h" 
  6  
  7 //菜单驱动程序 
  8 int menu_select(int n) 
  9 { 
 10     int sn; 
 11     printf("*****优先双链表*****\n\n -----------------\n");Sleep(60); 
 12     printf("|   1 创建链表    |\n");Sleep(60); 
 13     printf("|   2 输入数据    |\n");Sleep(60); 
 14     printf("|   3 查询数据    |\n");Sleep(60); 
 15     printf("|   0 退出链表    |\n");Sleep(60); 
 16     printf(" -----------------\n\n");Sleep(60); 
 17     printf("  请选择功能0-3:");Sleep(60); 
 18     for(;;)                                                    //菜单功能选择 
 19     { 
 20         scanf("%d",&sn); 
 21         if(sn<0 || sn>3) 
 22         { 
 23             gotoxy(0,9); 
 24             wrong(); 
 25             printf("\r  请选择功能0-3:"); 
 26         }else 
 27             break; 
 28     } 
 29     if(n==0&&sn==0)                                            //防止第一次进就输入退出命令的错误 
 30     { 
 31         haha(3); 
 32         exit(1); 
 33     } 
 34     if((n==0&&sn==2)||(n==0&&sn==3))                        //必须按次序进行 
 35     { 
 36         if(sn==0) 
 37             return sn; 
 38         printf("\n  ->请先建立链表<-  \n"); 
 39         Sleep(800); 
 40     }else if(n==1&&sn==3){ 
 41         if(sn==0) 
 42             return sn; 
 43         printf("\n  ->请先录入数据<-  \n"); 
 44         Sleep(800); 
 45     } 
 46  
 47     return sn; 
 48 } 
 49  
 50 //初始化函数 
 51 int InitList(DoubleList *L) 
 52 { 
 53     *L=(DoubleList)malloc(sizeof(DNode)); 
 54     if(!L) 
 55         return WR; 
 56     (*L)->next= *L; 
 57     (*L)->prior= *L; 
 58     (*L)->data=0; 
 59     Sleep(50); 
 60     printf("   ->创");    Sleep(50); 
 61     printf("");    Sleep(50); 
 62     printf("");    Sleep(50); 
 63     printf("功<-"); 
 64     Sleep(800); 
 65     return OK; 
 66 } 
 67  
 68 //销毁函数 
 69 void DestroyLIst(DoubleList L) 
 70 { 
 71     DoubleList p,q; 
 72     p=L->next->next; 
 73     while(p!=L->next) 
 74     { 
 75         q=p; 
 76         p=p->next; 
 77         free(q); 
 78     } 
 79     haha(3); 
 80     exit(1); 
 81 } 
 82  
 83 //输入数据 
 84 DoubleList CreateDCList(DoubleList L) 
 85 { 
 86     DNode *p,*q; 
 87     int n=5,r=0; 
 88     char yorn; 
 89     Sleep(60); 
 90     system("cls"); 
 91     waka();Sleep(60); 
 92     printf(" *****插入菜单*****\n"); 
 93     q=L;
 94     printf("| 当前数据个数为:%d |\n",L->data);                        //新插时没有元素,q指向L 
 95     printf("-->>请输入数据:"); 
 96     do{ 
 97         p=(DNode *)malloc(sizeof(DNode));                            //对p进行内存分配 
 98         if(r)
 99         {
100             system("cls"); 
101             printf("\n--------------------\n");
102             printf(" *****插入菜单*****\n"); 
103             printf("\r| 当前数据个数为:%d |\n",L->data);
104             printf("-->>请输入数据:");r=0;
105         }
106         scanf("%d",&p->data); 
107         p->freq=0;                                                    //频度置零 
108         q->next=p;                                                    //q为当前的最后一个 
109         p->prior=q;                                                    //将p接在q之后即可 
110         L->next->prior=p;                                            //双链表,L只是一个头节点的作用 
111         p->next=L->next;                                            //需要处理最后一个于头结点的联系 
112         q=p;                                                        //q始终指向最后一个元素 
113         (L->data)++;                                                //将链表长度置于头结点中 
114         while(getchar()== );                                        //清空格,不知道有多少个,直接这样清了 
115         printf("是否继续输入(y/n):");                                //这样写会使表内只有一个元素时前后都指向自己 
116         scanf("%c",&yorn);                                          //而L的前继会始终指向L!!! 
117         gotoxy(0,4); 
118         r=1;
119     }while(yorn==y); 
120     printf("\n\n| >-输-入-结-束-<  |       "); 
121     Sleep(1000); 
122     waka(); 
123     system("cls"); 
124     return L; 
125 } 
126  
127 //查找函数          全走next路径!!!! 
128 void Locate(DoubleList L) 
129 {                                                                    //在选择菜单的限制 
130     DNode *p,*q,*m,*n;    
131     char yorn; 
132     int te,x; 
133     system("cls"); 
134     waka();Sleep(60); 
135     printf(" *****查找菜单*****\n"); 
136     do{ 
137         printf("-->>请输入数据:"); 
138         scanf("%d",&x); 
139         p=L->next; 
140         te=0; 
141         while(p!=L->next->prior) 
142         { 
143             if(L->next->prior->data==x) 
144             { 
145                 p=L->next->prior; 
146                 goto bug; 
147             } 
148             if(p->data!=x) 
149                 p=p->next; 
150             else{ 
151 bug:            te=1; 
152                 (p->freq)++; 
153                 printf("已查找到数据“%d”\n当前数据的频度为:%d\n",x,p->freq); 
154                 //将频度高的置前 
155                 m=q=L->next; 
156                 n=p; 
157                 while(q!=p) 
158                 { 
159                     if((p->freq>=q->freq)&&(q==L->next))
160                     {
161                         printf("ce shi\n");
162 
163 
164                     }
165                     else if(p->freq>=q->freq) 
166                     { 
167                         q->next=p->next; 
168                         q->prior=p->prior; 
169                         n->next->prior=q; 
170                         n->prior->next=q; 
171                         p->next=m->next; 
172                         p->prior=m->prior; 
173                         m->next->prior=p; 
174                         m->prior->next=p;  
175                     } 
176                     else 
177                         q=q->next; 
178                 } 
179               
180                 break; 
181             } 
182         } 
183         if(!te) 
184             printf("未能找到\n"); 
185         printf("是否继续查找(y/n):"); 
186         while(getchar()== ); 
187         scanf("%c",&yorn); 
188     }while(yorn==y); 
189     printf("是否查看数据(y/n):"); 
190     while(getchar()== ); 
191     if(getchar()==y) 
192     { 
193         system("cls"); 
194         waka(); 
195         printf("\n当前数据内容如下:\n"); 
196         Sleep(100); 
197         p=L->next; 
198         for(x=L->data;x>0;x--) 
199         { 
200             printf("数据:%d         频度:%d\n",p->data,p->freq); 
201             p=p->next; 
202             Sleep(100); 
203         } 
204         printf("退出(y/n):"); 
205         while(getchar()== ); 
206         scanf("%c",&yorn); 
207     } 
208  
209 } 
210  
211 int haha(int n) //退出部分 
212 { 
213     char tem[30]= "...........";                //用以循环打印... 
214     int i,j=0; 
215     printf("\n\n -"); 
216     for(i=0;i<8;i++) 
217     { 
218         printf("*-"); 
219         Sleep(40);                                //作用为暂停40ms 
220     } 
221     printf("\n|   ->退出中<-    |\n"); 
222 a:  for( i= strlen(tem); i >= 0; i--) 
223     { 
224         printf("\r    ");                        //所以才不会换行 
225         printf("%s", &tem[i]); 
226         printf(" "); 
227         Sleep(25); 
228     } 
229     j++; 
230     if(j<n) 
231         goto a; 
232     printf("\r|  ->退出完毕<-   |"); 
233     Sleep(300); 
234     printf("\n|  再见 (*^__^*)  |"); 
235     Sleep(300); 
236     printf("\n -"); 
237     for(i=0;i<8;i++) 
238     { 
239         printf("*-"); 
240         Sleep(40); 
241     } 
242     printf("\n\n\n"); 
243     return 0; 
244 } 
245 //将光标移动到坐标为(x,y)的地方 
246 void gotoxy(int x,int y)                        //此处代码来源于百度 
247 {                                                //作用为可以在指定坐标打印数据 
248     CONSOLE_SCREEN_BUFFER_INFO csbiInfo;        //好像 x,y 反了 
249     HANDLE hConsoleOut; 
250     hConsoleOut = GetStdHandle(STD_OUTPUT_HANDLE); 
251     GetConsoleScreenBufferInfo(hConsoleOut,&csbiInfo); 
252     csbiInfo.dwCursorPosition.X = x; 
253     csbiInfo.dwCursorPosition.Y = y; 
254     SetConsoleCursorPosition(hConsoleOut,csbiInfo.dwCursorPosition); 
255 } 
256 void waka(void)                                    //打印-------------------- 
257 { 
258     char a[30]="--------------------"; 
259     int i; 
260     printf("\n"); 
261     for(i=strlen(a);i>=0;i--) 
262     { 
263         printf("\r"); 
264         printf("%s",&a[i]); 
265         Sleep(20); 
266     } 
267     printf("\n"); 
268 } 
269 void wrong(void)                                //输入错误的信息 
270 { 
271     char wrong[30]="#    WRONG    #          "; 
272     int i; 
273     for(i=strlen(wrong);i>=0;i--) 
274     { 
275         printf("\r  "); 
276         printf("%s  ",&wrong[i]); 
277         Sleep(30); 
278     } 
279     Sleep(800); 
280 }

 

main.c

 1 #include "common.h"
 2 #include "struct.h"
 3 #include "functions.h"
 4 
 5 
 6 int main(void)
 7 {
 8     DoubleList L;
 9     int times=0;
10     for(;;)
11     {
12         switch(menu_select(times))
13         {
14             case 1:
15                 InitList(&L);
16                 times=1;
17                 break;
18             case 2:
19                 L=CreateDCList(L);
20                 times=2;
21                 break;            
22             case 3:
23                 Locate(L);
24                 break;
25             case 0:
26                 DestroyLIst(L);
27         }
28         waka();    
29         system("cls");
30     }
31 }

 

唉,真的是,不忍再看。

 

以上是关于优先双链表的主要内容,如果未能解决你的问题,请参考以下文章

PHP 数据结构队列(SplQueue)和优先队列(SplPriorityQueue)简单使用实例

基础数据结构---双链表go语言的代码实现

基础数据结构---双链表go语言的代码实现

双链表代码实现和讲解

(王道408考研数据结构)第二章线性表-第三节2:双链表的定义及其操作(插入和删除)

数据结构-编程实现一个双链表的建立,双链表的打印,双链表的测长