优先双链表
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)简单使用实例