算法思想:读取当前进程Current,并对其进行冒泡排序。对Total中每一个节点进行搜索,如果在Current中说明未结束进程更新持续时间,如果不在Current中,说明已结束更新Finished的endTime和持续时间。对Current中每个节点搜索,在Total中并且Finished 的endTime不等于0,则重新启用该进程更新endTime和持续时间,如果在Total中,但endTime等于零,则还在进行不做操作,如果不在Total中,则是新加入的进程更新Total和Finished.对finish的进行排序,打印(endTime不等于0的为已结束进程)
主要/核心函数分析:调整结束时间及持续时间UpdateTime(Total, Current, Finished);调整重新调用的程序及新调用的程序UpdateProgarm(Total, Current, Finished);在前面算法思想中已经说明。
测试数据:本电脑
运行结果:运行前打开QQ,运行停顿时我用进程管理系统结束QQ的所有进程来查看正确性。每次与系统进程进行比较。
时间复杂度:每一秒更新的时间复杂度是O(2*Total*Current+Finished*Finished+Total*Total+2*Current+Finished)
心得体会:学会了单链表和双链表的区别与使用,同时也学会了如何获取系统当前进程。以及合适的中间媒介来完成所需工作,就像这题的Total链表就是媒介用来联系Current和Finished。还对链表排序有了更深层次的理解
1 #undef UNICODE 2 #undef _UNICODE 3 #include<iostream> 4 #include<iomanip> 5 #include<cstdio> 6 #include<windows.h> 7 #include<TLHELP32.h> 8 #include<iomanip> 9 #include<string> 10 #include"Psapi.h" 11 #include<ctime> 12 #pragma comment(lib,"Psapi.lib") 13 using namespace std; 14 15 typedef struct DLNode 16 { 17 char name[100];//进程名 18 int duration;//持续时间 19 int endTime;//结束时间 20 DLNode* prior, * next; 21 }DLNode, * DLinkList;//双向链表 22 23 typedef struct SLNode 24 { 25 char name[100];//进程名 26 int duration;//持续时间 27 int memory;//内存使用情况 28 SLNode* next; 29 }SLNode, * SLinkList;//单向链表 30 31 //获取内存 32 int GetMemoryInfo(DWORD processID) 33 { 34 //API 35 HANDLE hProcess; 36 PROCESS_MEMORY_COUNTERS pmc; 37 hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processID); 38 if (hProcess == NULL) 39 return 0; 40 41 //GetProcessMemoryInfo()用于获取内存的使用情况 42 if (GetProcessMemoryInfo(hProcess, &pmc, sizeof(pmc))) 43 { 44 CloseHandle(hProcess); 45 46 //pmc.WorkingSetSize就是程序在当前代码处的内存使用量 47 return pmc.WorkingSetSize; 48 } 49 } 50 51 //创建当前进程链表 52 int CreateList(SLinkList& S) 53 { 54 //头结点 55 S = (SLinkList)malloc(sizeof(SLNode)); 56 S->duration = 0; 57 S->memory = 0; 58 S->next = NULL; 59 60 SLinkList Fakehead = S, newnode; 61 62 //存放进程信息的结构体 63 PROCESSENTRY32 temp; 64 temp.dwSize = sizeof(temp); 65 66 //获取系统内的所有进程 67 HANDLE hProcessSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); 68 if (INVALID_HANDLE_VALUE == hProcessSnapshot) 69 { 70 printf("未获得进程!\n"); 71 return 0; 72 } 73 74 //获取进程 75 BOOL bMore = Process32First(hProcessSnapshot, &temp); 76 while (bMore) 77 { 78 //获得当前进程的内存量 79 int judge = GetMemoryInfo(temp.th32ProcessID); 80 if (judge) 81 { 82 //新进程的内容赋给新结点,接在双向链表最后 83 newnode = (SLinkList)malloc(sizeof(SLNode)); 84 newnode->memory = judge / 1024; 85 strcpy_s(newnode->name, temp.szExeFile); 86 newnode->duration = 0; 87 Fakehead->next = newnode; 88 newnode->next = NULL; 89 Fakehead = newnode; 90 } 91 bMore = Process32Next(hProcessSnapshot, &temp); 92 } 93 //清除hProcess句柄 94 CloseHandle(hProcessSnapshot); 95 return 1; 96 } 97 98 //根据PID,在储存结束时间的链表中查找该进程 99 void LocateOverList(DLinkList& D, char* key, DLinkList& p) 100 { 101 //在已结束进程中查找 102 p = D->next; 103 while (p != D) 104 { 105 if (strcmp(p->name, key)==0) 106 return; 107 p = p->next; 108 } 109 return ; 110 } 111 112 //创建已结束进程链表 113 int CreateEndedList(DLinkList& Finished, SLinkList Total) 114 { 115 //把总进程链表所有内容赋给记录已结束进程链表 116 Finished = (DLinkList)malloc(sizeof(DLNode)); 117 Finished->duration = 0;//总时间 118 Finished->endTime = 0;//结束时间 119 Finished->next = Finished; 120 Finished->prior = Finished; 121 SLinkList cur_S = Total->next; 122 DLinkList cur_D = Finished, newnode; 123 while (cur_S) 124 { 125 newnode = (DLinkList)malloc(sizeof(DLNode)); 126 strcpy_s(newnode->name, strlen(cur_S->name) + 1, cur_S->name); 127 newnode->duration = 0; 128 newnode->endTime = 0; 129 130 newnode->next = cur_D->next; 131 cur_D->next->prior = newnode; 132 cur_D->next = newnode; 133 newnode->prior = cur_D; 134 135 cur_D = cur_D->next; 136 cur_S = cur_S->next; 137 } 138 return 1; 139 } 140 141 //按持续时间给进程排序 142 int SortDList(DLinkList& D) 143 { 144 //统计结点数目 145 int statisticNum = 0; 146 DLinkList statistic = D->next; 147 while (statistic!=D) 148 { 149 statisticNum++; 150 statistic = statistic->next; 151 } 152 153 //冒泡排序 154 DLinkList q = D->next; 155 DLinkList t = (DLinkList)malloc(sizeof(DLNode)); 156 //标记排序是否发生交换 157 //若不发生交换 158 //则排序完成 159 int flag = 1; 160 161 while (flag == 1 && statisticNum-1> 0) 162 { 163 q = D->next; 164 //若没有发生交换 165 //flag为0,则不会发生下一趟排序 166 flag = 0; 167 for (int i = 1; i < statisticNum; i++) 168 { 169 if (q->duration > q->next->duration) 170 { 171 flag = 1; 172 strcpy_s(t->name, strlen(q->name) + 1, q->name); 173 t->endTime = q->endTime; 174 t->duration = q->duration; 175 strcpy_s(q->name, strlen(q->next->name) + 1, q->next->name); 176 q->endTime = q->next->endTime; 177 q->duration = q->next->duration; 178 strcpy_s(q->next->name, strlen(t->name) + 1, t->name); 179 q->next->endTime = t->endTime; 180 q->next->duration = t->duration; 181 } 182 q = q->next; 183 } 184 statisticNum--; 185 } 186 free(t); 187 return 1; 188 } 189 190 //按照内存大小排序 191 int SortSList(SLinkList& S) 192 { 193 //记录结点数目 194 int statisticNum = 0; 195 SLinkList statistic = S->next; 196 while (statistic) 197 { 198 statisticNum++; 199 statistic = statistic->next; 200 } 201 202 //冒泡排序 203 SLinkList q = S->next; 204 SLinkList t = (SLinkList)malloc(sizeof(SLNode)); 205 //标记排序是否发生交换 206 //若不发生交换 207 //则排序完成 208 int flag = 1; 209 210 while (flag == 1 && statisticNum - 1 > 0) 211 { 212 q = S->next; 213 //若没有发生交换 214 //flag为0,则不会发生下一趟排序 215 flag = 0; 216 for (int i = 1; i < statisticNum; i++) 217 { 218 if (q->memory < q->next->memory) 219 { 220 flag = 1; 221 strcpy_s(t->name, strlen(q->name) + 1, q->name); 222 t->memory = q->memory; 223 t->duration = q->duration; 224 strcpy_s(q->name, strlen(q->next->name) + 1, q->next->name); 225 q->memory = q->next->memory; 226 q->duration = q->next->duration; 227 strcpy_s(q->next->name, strlen(t->name) + 1, t->name); 228 q->next->memory = t->memory; 229 q->next->duration = t->duration; 230 } 231 q = q->next; 232 } 233 statisticNum--; 234 } 235 free(t); 236 return 1; 237 } 238 239 //统计已结束进程 240 int UpdateTime(SLinkList& Total, SLinkList& Current, DLinkList& Finished) 241 { 242 //判断有无找到未结束进程 243 int judge; 244 245 DLinkList p_Finished = Finished->next; 246 SLinkList p_Total = Total->next, p_Current; 247 248 //头结点用来记录调试时间 249 Finished->duration += 1; 250 251 while (p_Total) 252 { 253 //重置为1 254 judge = 1; 255 256 //寻找有无未结束进程 257 p_Current = Current->next; 258 while (p_Current) 259 { 260 //该进程未结束 261 if (strcmp(p_Current->name,p_Total->name)==0) 262 { 263 //找到,置为0 264 judge = 0; 265 break; 266 } 267 p_Current = p_Current->next; 268 } 269 270 //进程已结束 271 if (judge) 272 { 273 //获取该结束进程在已结束进程链表的位置 274 //更新结束时间 275 LocateOverList(Finished, p_Total->name,p_Finished); 276 277 //如果结束时间为0,更新结束时间 278 //如果结束时间不为0,更新结束的持续时间 279 if (p_Finished->endTime == 0) 280 p_Finished->endTime = Finished->duration; 281 else 282 p_Finished->duration += 1; 283 } 284 285 //进程未结束 286 //更新当前进程的运行的持续时间 287 else 288 { 289 p_Total->duration += 1; 290 p_Current->duration = p_Total->duration; 291 } 292 293 p_Total = p_Total->next; 294 } 295 return 1; 296 } 297 298 //刷新后更新进程 299 int UpdateProgarm(SLinkList& Total, SLinkList Current, DLinkList& Finished) 300 { 301 //判断有无找到新进程 302 int judge; 303 304 DLinkList p_Finished = Finished->next, q_Finished = Finished->next, temp_finished ; 305 306 SLinkList p_Total = Total->next, p_Current = Current->next, q_Total = Total->next, temp_Total; 307 308 //遍历当前进程表 309 while (p_Current) 310 { 311 judge = 1; 312 313 p_Total = Total->next; 314 while (p_Total) 315 { 316 //该进程已在进程表中 317 if (strcmp(p_Current->name,p_Total->name)==0) 318 { 319 judge = 0; 320 break; 321 } 322 p_Total = p_Total->next; 323 } 324 325 //进程不在total中,将其添加 326 if (judge) 327 { 328 while (q_Total->next) 329 { 330 q_Total = q_Total->next; 331 } 332 temp_Total = (SLinkList)malloc(sizeof(SLNode)); 333 temp_Total->memory = p_Current->memory; 334 temp_Total->duration = 0; 335 strcpy_s(temp_Total->name, p_Current->name); 336 q_Total->next = temp_Total; 337 temp_Total->next = NULL; 338 339 while (q_Finished->next != Finished) 340 { 341 q_Finished = q_Finished->next; 342 } 343 temp_finished = (DLinkList)malloc(sizeof(DLNode)); 344 temp_finished->duration = 0; 345 temp_finished->endTime = 0; 346 strcpy_s(temp_finished->name, p_Current->name); 347 q_Finished->next->prior = temp_finished; 348 temp_finished->next = q_Finished->next; 349 q_Finished->next = temp_finished; 350 temp_finished->prior = q_Finished; 351 } 352 else 353 { 354 p_Finished = Finished->next; 355 while (p_Finished!=Finished) 356 { 357 if (strcmp(p_Current->name ,p_Finished->name)==0 && p_Finished->endTime != 0) 358 { 359 //重新启用进程 360 p_Finished->endTime = 0; 361 362 p_Current->duration = p_Total->duration = 0; 363 break; 364 } 365 p_Finished = p_Finished->next; 366 } 367 } 368 p_Current = p_Current->next; 369 } 370 return 1; 371 } 372 373 //显示当前进程 374 void ShowArray_D(SLinkList SL, DLinkList DL) 375 { 376 cout.setf(ios::left); 377 cout << setw(20) << "当前系统进程名" << ' '; 378 cout.setf(ios::right, ios::left); 379 cout << ' ' << setw(17) << "内存使用情况" << ' ' << "持续时间" << ' ' << setw(20) << endl; 380 cout << "----------------------------------------------------------------" << endl; 381 382 DLinkList p = DL->next; 383 SLinkList s = SL->next; 384 385 //打印当前进程链表的内容 386 while (s) 387 { 388 char* nameSave = s->name; 389 for (int i = 0; i < 20; i++) 390 { 391 cout << nameSave[i]; 392 if (nameSave[i] == '\0') 393 { 394 for (int j = i; j < 20; j++) 395 cout << " "; 396 break; 397 } 398 } 399 400 cout.setf(ios::left); 401 cout << ' '; 402 403 cout.setf(ios::right, ios::left); 404 cout << ' ' << setw(15) << s->memory << "KB"; 405 if (s->duration < 60) 406 cout << ' ' << s->duration << "s" << endl; 407 if (s->duration >= 60) 408 cout << ' ' << s->duration / 60 << "m " << s->duration % 60 << "s" << endl; 409 410 s = s->next; 411 } 412 cout << endl; 413 414 if (p!=DL) 415 { 416 cout.setf(ios::left); 417 cout << setw(20) << "已结束进程名" << ' '; 418 cout.setf(ios::right, ios::left); 419 cout << ' ' << setw(17) << "持续时间" << ' ' << "结束时间" << ' ' << setw(20) << endl; 420 cout << "----------------------------------------------------------------" << endl; 421 } 422 423 //当链表未结束 424 //已结束进程链表的结点的endTime值不为0,打印 425 while (p!=DL) 426 { 427 if (p->endTime != 0) 428 { 429 char* nameSave1 = p->name; 430 for (int i = 0; i < 20; i++) 431 { 432 cout << nameSave1[i]; 433 if (nameSave1[i] == '\0') 434 { 435 for (int j = i; j < 20; j++) 436 cout << " "; 437 break; 438 } 439 } 440 441 cout.setf(ios::left); 442 cout << '\t'; 443 444 cout.setf(ios::right, ios::left); 445 if (p->duration < 60) 446 cout << ' ' << setw(15) << p->duration << "s"; 447 if (p->duration >= 60) 448 cout << ' ' << setw(12) << p->duration / 60 << "m " << p->duration % 60 << "s"; 449 450 451 cout.setf(ios::left, ios::right); 452 453 if (p->endTime < 60) 454 cout << ' ' << p->endTime << "s" << endl; 455 if (p->endTime >= 60) 456 cout << ' ' << p->endTime / 60 << "m " << p->endTime % 60 << "s" << endl; 457 } 458 459 p = p->next; 460 } 461 } 462 463 int main() 464 { 465 //Total为总进程表,cuttent为当前进程表 466 SLinkList Total; 467 SLinkList Current; 468 //Finished中存储已结束进程 469 DLinkList Finished; 470 //创建该程序执行时得到的最初的进程表,用于与当前进程比对,来获取已结束进程 471 CreateList(Total); 472 //创建结束进程表 473 CreateEndedList(Finished, Total); 474 //排序 475 SortSList(Total); 476 //打印 477 ShowArray_D(Total, Finished); 478 479 int times = 5;//次数 480 481 while (times) 482 { 483 Sleep(500); 484 //清屏 485 system("cls"); 486 //获取当前进程表 487 CreateList(Current); 488 //排序 489 SortSList(Current); 490 //调整结束时间及持续时间 491 UpdateTime(Total, Current, Finished); 492 //调整重新调用的程序及新调用的程序 493 UpdateProgarm(Total, Current, Finished); 494 //排序 495 SortDList(Finished); 496 //打印 497 ShowArray_D(Current, Finished); 498 times--; 499 //暂停一下 500 system("pause"); 501 } 502 system("pause"); 503 return 0; 504 }