├── README.md ├── app.py └── ساختمان داده.pdf /README.md: -------------------------------------------------------------------------------- 1 | 2 | ## تمام کد های ساختمان داده 👇 3 | 4 | ### Source code 5 | 6 | ## جزوه ساختمان داده 👇 7 | 8 | Download PDF 9 | 10 |
11 | 12 | ### با تشکر از تیم پژوهشی تورینگ turinglogo 13 | 14 | ### پیروز و سربلند باشید :rose::heart: 15 | 16 | -------------------------------------------------------------------------------- /app.py: -------------------------------------------------------------------------------- 1 | ################################################################################################################################################ 2 | 3 | # O(1) 4 | 5 | def worker(arr, index): 6 | return arr[index] 7 | 8 | ################################################################################################################################################ 9 | 10 | # O(n) 11 | 12 | def sum(arr): 13 | total = 0 14 | for element in arr: 15 | total += element 16 | return total 17 | 18 | ################################################################################################################################################ 19 | 20 | # O(log(n)) 21 | 22 | def binary_search(arr, target): 23 | low = 0 24 | high = len(arr) - 1 25 | 26 | while low <= high: 27 | mid = (low + high) // 2 28 | if arr[mid] == target: 29 | return mid 30 | elif arr[mid] < target: 31 | low = mid + 1 32 | else: 33 | high = mid - 1 34 | 35 | return -1 36 | 37 | ################################################################################################################################################ 38 | 39 | # O(nlog(n)) 40 | 41 | def merge_sort(arr): 42 | if len(arr) > 1: 43 | mid = len(arr) // 2 44 | 45 | left_half = arr[:mid] 46 | right_half = arr[mid:] 47 | 48 | merge_sort(left_half) 49 | merge_sort(right_half) 50 | 51 | i = j = k = 0 52 | 53 | while i < len(left_half) and j < len(right_half): 54 | if left_half[i] < right_half[j]: 55 | arr[k] = left_half[i] 56 | i += 1 57 | else: 58 | arr[k] = right_half[j] 59 | j += 1 60 | k += 1 61 | 62 | while i < len(left_half): 63 | arr[k] = left_half[i] 64 | i += 1 65 | k += 1 66 | 67 | while j < len(right_half): 68 | arr[k] = right_half[j] 69 | j += 1 70 | k += 1 71 | 72 | ################################################################################################################################################ 73 | 74 | # کلاس استک 75 | 76 | class Stack: 77 | def __init__(self, limit=10): 78 | self.stack = [] 79 | self.limit = limit 80 | 81 | def peek(self): 82 | if len(self.stack) != 0: 83 | return -1 84 | else: 85 | return self.stack[-1] 86 | 87 | def push(self, data): 88 | if len(self.stack) > self.limit: 89 | return -1 90 | else: 91 | self.stack.append(data) 92 | 93 | def pop(self): 94 | 95 | if len(self.stack) >= 0: 96 | return self.stack.pop() 97 | else: 98 | return -1 99 | 100 | def find(self, data): 101 | if len(self.stack) <= 0: 102 | return -1 103 | for i in range(1, len(self.stack)): 104 | if self.stack[i] == data: 105 | return i 106 | return -1 107 | def replace(self, data, new_data): 108 | if len(self.stack) <= 0: 109 | return -1 110 | else: 111 | if data in self.stack: 112 | self.stack[self.stack.index(data)] = new_data 113 | else: 114 | return -1 115 | 116 | def show(self): 117 | for i in self.stack: 118 | print(i) 119 | 120 | def is_empty(self): 121 | return len(self.stack) == 0 122 | 123 | def __len__(self): 124 | return len(self.stack) 125 | 126 | ################################################################################################################################################ 127 | 128 | # تبدیل دسیمال به باینری 129 | 130 | def d2b(number): 131 | my_stack = Stack() 132 | while number !=0: 133 | my_stack.push(number % 2) 134 | number //= 2 135 | while not(my_stack.is_empty()): 136 | print(my_stack.pop(), end='') 137 | 138 | ################################################################################################################################################ 139 | 140 | # کلاس صف 141 | 142 | class Queue: 143 | def __init__(self, limit=100): 144 | self.Q = [None] * limit 145 | self.limit = limit 146 | self.front = -1 147 | self.rear = -1 148 | 149 | def enqueue(self, data): 150 | if self.rear >= self.limit-1: 151 | return -1 152 | elif self.front == -1: 153 | self.front= 0 154 | self.rear = 0 155 | self.Q[0] = data 156 | else: 157 | self.rear += 1 158 | self.Q[self.rear] = data 159 | 160 | def dequeue(self): 161 | if self.front == -1: 162 | return -1 163 | elif self.rear < self.front: 164 | return -1 165 | else: 166 | self.front += 1 167 | 168 | def show(self): 169 | for i in range(self.front, self.rear+1): 170 | print(self.Q[i]) 171 | 172 | def replace(self, data, place): 173 | if self.place > self.front and self.place < self.rear: 174 | self.Q[place] = data 175 | 176 | ################################################################################################################################################ 177 | 178 | # کلاس صف حلقوی 179 | 180 | class Cqueue: 181 | def __init__(self, limit=10) -> None: 182 | self.Q = [None] * limit 183 | self.limit = limit 184 | self.rear = -1 185 | self.front = -1 186 | 187 | def insert_queue(self, data): 188 | if (self.rear+1) % self.limit == self.front: 189 | print('full') 190 | return -1 191 | 192 | elif self.front == -1: 193 | self.front += 1 194 | self.rear += 1 195 | self.Q[0] = data 196 | 197 | else: 198 | self.rear = (self.rear+1) % self.limit 199 | self.Q[self.rear] = data 200 | 201 | def delete_queue(self): 202 | if self.front == -1: 203 | # print("empty") 204 | return None 205 | 206 | elif self.front == self.rear: 207 | a = self.front 208 | self.front= -1 209 | self.rear = -1 210 | return self.Q[a] 211 | 212 | else: 213 | b = self.front 214 | self.front = (self.front+1) % self.limit 215 | return self.Q[b] 216 | 217 | def display(self): 218 | if self.rear == -1 and self.front == -1: 219 | print("empty") 220 | return -1 221 | elif self.front <= self.rear: 222 | for i in range(self.front, self.rear+1): 223 | print(self.Q[i]) 224 | else: 225 | for i in range(self.front, self.limit): 226 | print(self.Q[i]) 227 | 228 | for i in range(0, self.rear + 1): 229 | print(self.Q[i]) 230 | 231 | 232 | 233 | def replace(self, data, new_data): 234 | flag = False 235 | if self.rear == -1 and self.front == -1: 236 | print("empty") 237 | else: 238 | if self.front< self.rear: 239 | for i in range(self.front, self.rear + 1): 240 | if self.Q[i] == data: 241 | self.Q[i] = new_data 242 | flag = True 243 | elif self.front == self.rear: 244 | if self.Q[self.front] == data: 245 | self.Q[self.front] = new_data 246 | flag = True 247 | elif self.front > self.rear: 248 | for i in range(self.front, self.limit): 249 | if self.Q[i] == data: 250 | self.Q[i] = new_data 251 | flag = True 252 | for i in range(0, self.rear+1): 253 | if self.Q[i] == data: 254 | self.Q[i] = new_data 255 | flag = True 256 | if not(flag): 257 | print("Your data not found") 258 | 259 | ################################################################################################################################################ 260 | 261 | # برعکس کردن استک بوسیله صف 262 | 263 | class Stack: 264 | def __init__(self, limit=10): 265 | self.stack = [] 266 | self.limit = limit 267 | 268 | def peek(self): 269 | if len(self.stack) != 0: 270 | return -1 271 | else: 272 | return self.stack[-1] 273 | 274 | def push(self, data): 275 | if len(self.stack) > self.limit: 276 | return -1 277 | else: 278 | self.stack.append(data) 279 | 280 | def pop(self): 281 | 282 | if len(self.stack) >= 0: 283 | return self.stack.pop() 284 | else: 285 | return -1 286 | 287 | def find(self, data): 288 | if len(self.stack) <= 0: 289 | return -1 290 | for i in range(1, len(self.stack)): 291 | if self.stack[i] == data: 292 | return i 293 | return -1 294 | def replace(self, data, new_data): 295 | if len(self.stack) <= 0: 296 | return -1 297 | else: 298 | if data in self.stack: 299 | self.stack[self.stack.index(data)] = new_data 300 | else: 301 | return -1 302 | 303 | def show(self): 304 | for i in self.stack[::-1]: 305 | print(i) 306 | 307 | def is_empty(self): 308 | return len(self.stack) == 0 309 | 310 | def __len__(self): 311 | return len(self.stack) 312 | 313 | class Cqueue: 314 | def __init__(self, limit=10) -> None: 315 | self.Q = [None] * limit 316 | self.limit = limit 317 | self.rear = -1 318 | self.front = -1 319 | 320 | def insert_queue(self, data): 321 | if (self.rear+1) % self.limit == self.front: 322 | print('full') 323 | return -1 324 | 325 | elif self.front == -1: 326 | self.front += 1 327 | self.rear += 1 328 | self.Q[0] = data 329 | 330 | else: 331 | self.rear = (self.rear+1) % self.limit 332 | self.Q[self.rear] = data 333 | 334 | def delete_queue(self): 335 | if self.front == -1: 336 | # print("empty") 337 | return None 338 | 339 | elif self.front == self.rear: 340 | a = self.front 341 | self.front= -1 342 | self.rear = -1 343 | return self.Q[a] 344 | else: 345 | b = self.front 346 | self.front = (self.front+1) % self.limit 347 | return self.Q[b] 348 | 349 | def display(self): 350 | if self.rear == -1 and self.front == -1: 351 | print("empty") 352 | return -1 353 | elif self.front <= self.rear: 354 | for i in range(self.front, self.rear+1): 355 | print(self.Q[i]) 356 | else: 357 | for i in range(self.front, self.limit): 358 | print(self.Q[i]) 359 | 360 | for i in range(0, self.rear + 1): 361 | print(self.Q[i]) 362 | 363 | def replace(self, data, new_data): 364 | flag = False 365 | if self.rear == -1 and self.front == -1: 366 | print("empty") 367 | else: 368 | if self.front< self.rear: 369 | for i in range(self.front, self.rear + 1): 370 | if self.Q[i] == data: 371 | self.Q[i] = new_data 372 | flag = True 373 | elif self.front == self.rear: 374 | if self.Q[self.front] == data: 375 | self.Q[self.front] = new_data 376 | flag = True 377 | elif self.front > self.rear: 378 | for i in range(self.front, self.limit): 379 | if self.Q[i] == data: 380 | self.Q[i] = new_data 381 | flag = True 382 | for i in range(0, self.rear+1): 383 | if self.Q[i] == data: 384 | self.Q[i] = new_data 385 | flag = True 386 | if not(flag): 387 | print("Your data not found") 388 | 389 | def reverse_data(stack: Stack): 390 | Q = Cqueue() 391 | n_stack = Stack() 392 | while not (stack.is_empty()): 393 | Q.insert_queue(stack.pop()) 394 | 395 | while Q.front != -1: 396 | n_stack.push(Q.delete_queue()) 397 | 398 | n_stack.show() 399 | 400 | ################################################################################################################################################ 401 | 402 | # برعکس کردن صف بوسیله استک 403 | 404 | class Stack: 405 | def __init__(self, limit=10): 406 | self.stack = [] 407 | self.limit = limit 408 | 409 | def peek(self): 410 | if len(self.stack) != 0: 411 | return -1 412 | else: 413 | return self.stack[-1] 414 | 415 | def push(self, data): 416 | if len(self.stack) > self.limit: 417 | return -1 418 | else: 419 | self.stack.append(data) 420 | 421 | def pop(self): 422 | 423 | if len(self.stack) >= 0: 424 | return self.stack.pop() 425 | else: 426 | return -1 427 | 428 | def find(self, data): 429 | if len(self.stack) <= 0: 430 | return -1 431 | for i in range(1, len(self.stack)): 432 | if self.stack[i] == data: 433 | return i 434 | return -1 435 | def replace(self, data, new_data): 436 | if len(self.stack) <= 0: 437 | return -1 438 | else: 439 | if data in self.stack: 440 | self.stack[self.stack.index(data)] = new_data 441 | else: 442 | return -1 443 | 444 | def show(self): 445 | for i in self.stack: 446 | print(i) 447 | 448 | def is_empty(self): 449 | return len(self.stack) == 0 450 | 451 | def __len__(self): 452 | return len(self.stack) 453 | 454 | class Cqueue: 455 | def __init__(self, limit=10) -> None: 456 | self.Q = [None] * limit 457 | self.limit = limit 458 | self.rear = -1 459 | self.front = -1 460 | 461 | def insert_queue(self, data): 462 | if (self.rear+1) % self.limit == self.front: 463 | print('full') 464 | return -1 465 | 466 | elif self.front == -1: 467 | self.front += 1 468 | self.rear += 1 469 | self.Q[0] = data 470 | 471 | else: 472 | self.rear = (self.rear+1) % self.limit 473 | self.Q[self.rear] = data 474 | 475 | def delete_queue(self): 476 | if self.front == -1: 477 | # print("empty") 478 | return None 479 | 480 | elif self.front == self.rear: 481 | a = self.front 482 | self.front= -1 483 | self.rear = -1 484 | return self.Q[a] 485 | 486 | else: 487 | b = self.front 488 | self.front = (self.front+1) % self.limit 489 | return self.Q[b] 490 | 491 | def display(self): 492 | if self.rear == -1 and self.front == -1: 493 | print("empty") 494 | return -1 495 | elif self.front <= self.rear: 496 | for i in range(self.front, self.rear+1): 497 | print(self.Q[i]) 498 | else: 499 | for i in range(self.front, self.limit): 500 | print(self.Q[i]) 501 | 502 | for i in range(0, self.rear + 1): 503 | print(self.Q[i]) 504 | 505 | def replace(self, data, new_data): 506 | flag = False 507 | if self.rear == -1 and self.front == -1: 508 | print("empty") 509 | else: 510 | if self.front< self.rear: 511 | for i in range(self.front, self.rear + 1): 512 | if self.Q[i] == data: 513 | self.Q[i] = new_data 514 | flag = True 515 | elif self.front == self.rear: 516 | if self.Q[self.front] == data: 517 | self.Q[self.front] = new_data 518 | flag = True 519 | elif self.front > self.rear: 520 | for i in range(self.front, self.limit): 521 | if self.Q[i] == data: 522 | self.Q[i] = new_data 523 | flag = True 524 | for i in range(0, self.rear+1): 525 | if self.Q[i] == data: 526 | self.Q[i] = new_data 527 | flag = True 528 | if not(flag): 529 | print("Your data not found") 530 | 531 | def reverse_data(Q:Cqueue): 532 | new_Q = Cqueue() 533 | stack = Stack() 534 | 535 | while Q.front != -1: 536 | stack.push(Q.delete_queue()) 537 | 538 | while not(stack.is_empty()): 539 | new_Q.insert_queue(stack.pop()) 540 | new_Q.display() 541 | 542 | ################################################################################################################################################ 543 | 544 | # توابع بازگشتی 545 | 546 | # محسبه فاکتوریل 547 | def calc_fac(n): 548 | pass 549 | if n == 1: 550 | return 1 551 | else: 552 | return n * calc_fac(n-1) 553 | 554 | 555 | def fibo(n): 556 | if n < 2: 557 | return n 558 | 559 | else: 560 | return fibo(n-1) + fibo(n-2) 561 | 562 | 563 | def sum_num(a, b): 564 | if b == 0: 565 | return a 566 | else: 567 | return sum_num(a, b-1) + 1 568 | 569 | 570 | def multi_num(a, b): 571 | if b == 0: 572 | return 0 573 | else: 574 | return multi_num(a, b-1) + a 575 | 576 | 577 | def divi(a, b): 578 | if a < b: 579 | return 0 580 | else: 581 | return divi(a-b, b) + 1 582 | 583 | 584 | # Hannoi Tower 585 | def Hannoi(n, A, B, C): 586 | if n == (1): 587 | print(A, 'to', C) 588 | else: 589 | Hannoi(n-1, A, C, B) 590 | print(A, 'to', C) 591 | Hannoi(n-1, B, A, C) 592 | 593 | # palidrome 594 | def palindrome( string ): 595 | if len(string) <= 1 : 596 | return True 597 | if string[0] != string[-1]: 598 | return False 599 | return palindrome (string[1:-1]) 600 | 601 | ################################################################################################################################################ 602 | 603 | # لیست پیوندی 604 | 605 | class Node: 606 | def __init__(self, data): 607 | self.data = data 608 | self.next = None 609 | 610 | class Linkedlist: 611 | def __init__(self): 612 | self.head = None 613 | 614 | def insert_first(self, x): 615 | a = Node(x) 616 | a.next = self.head 617 | self.head = a 618 | 619 | def insert_last(self, x): 620 | a = Node(x) 621 | if self.head == None: 622 | self.head = a 623 | return 624 | temp = self.head 625 | while temp.next: 626 | temp = temp.next 627 | temp.next = a 628 | 629 | def insert_after(self, x, data): # insert after x 630 | if self.head is None: 631 | return 632 | elif self.head.next is None: 633 | if self.head.data == x: 634 | a = Node(data) 635 | self.head.next = a 636 | else: 637 | return None 638 | temp = self.head 639 | a = Node(data) 640 | while temp.data != x: 641 | if temp.next is None: 642 | print("not found") 643 | return 644 | temp = temp.next 645 | a.next = temp.next 646 | temp.next = a 647 | 648 | def delete_first(self): 649 | if self.head is None: 650 | print("empty") 651 | return 652 | self.head = self.head.next 653 | 654 | def delete_last(self): 655 | if self.head is None: 656 | print("empty") 657 | return 658 | elif self.head.next is None: 659 | self.head = None 660 | return 661 | 662 | temp = self.head 663 | while temp.next.next != None: 664 | temp = temp.next 665 | temp.next = None 666 | 667 | def delete_after(self, x): 668 | if self.head is None: # check if empty 669 | print("empty") 670 | return 671 | elif not (self.head.next): # check if only one object 672 | return 673 | temp = self.head 674 | while temp.data != x: 675 | if temp.next is None: # check if x is not available 676 | return 677 | temp = temp.next 678 | if temp.next: # check if x is the last object 679 | temp.next = temp.next.next 680 | 681 | def delete(self, x): 682 | if self.head is None: # check if empty 683 | print("empty") 684 | return 685 | 686 | elif self.head.data == x: 687 | self.head = self.head.next 688 | print("done") 689 | return None 690 | 691 | elif self.head.next is None: 692 | return 693 | 694 | temp = self.head 695 | while temp.next.data != x: 696 | if temp.next.next is None: 697 | return 698 | temp = temp.next 699 | temp.next = temp.next.next 700 | 701 | # add replace method to class 702 | def replace(self, old_data, new_data): 703 | if self.head is None: 704 | print("empty") 705 | return 706 | 707 | elif self.head.data == old_data: 708 | self.head.data = new_data 709 | 710 | temp = self.head 711 | while temp.data != old_data: 712 | if temp.next is None: 713 | print("your data not found!") 714 | return 715 | temp = temp.next 716 | temp.data = new_data 717 | 718 | ################################################################################################################################################ 719 | 720 | # لیست پیوندی حلقوی 721 | 722 | class Node: 723 | def __init__(self, data): 724 | self.data = data 725 | self.next = None 726 | 727 | class CLinkedList: 728 | def __init__(self): 729 | self.head = None 730 | 731 | def insert_first(self, data): 732 | a = Node(data) 733 | if self.head is None: 734 | self.head = a 735 | a.next = self.head 736 | return 737 | 738 | a.next = self.head 739 | temp = self.head 740 | while temp.next != self.head: 741 | temp = temp.next 742 | temp.next = a 743 | self.head = a 744 | 745 | def insert_last(self, data): 746 | a = Node(data) 747 | 748 | if self.head is None: 749 | self.head = a 750 | a.next = self.head 751 | return 752 | 753 | temp = self.head 754 | while temp.next != self.head: 755 | temp = temp.next 756 | temp.next = a 757 | a.next = self.head 758 | 759 | def insert_after(self, x, data): 760 | if self.head is None: 761 | print("empty") 762 | return 763 | 764 | temp = self.head 765 | while temp.data != x: 766 | if temp.next == self.head: 767 | print("your data not found") 768 | return 769 | temp = temp.next 770 | 771 | a = Node(data) 772 | a.next = temp.next 773 | temp.next = a 774 | 775 | def delete_first(self): 776 | if self.head is None: 777 | print("empty") 778 | return None 779 | 780 | elif self.head.next == self.head: 781 | del (self.head) 782 | self.head = None 783 | return 784 | 785 | temp = self.head 786 | while temp.next != self.head: 787 | temp = temp.next 788 | 789 | temp.next = temp.next.next 790 | del(self.head) 791 | self.head = temp.next 792 | 793 | def delete_last(self): 794 | if self.head is None: 795 | print("empty") 796 | return None 797 | 798 | elif self.head.next == self.head: 799 | del(self.head) 800 | self.head = None 801 | return None 802 | 803 | temp = self.head 804 | while temp.next.next != self.head: 805 | temp = temp.next 806 | del(temp.next) 807 | temp.next = self.head 808 | 809 | def delete_after(self, x): 810 | if self.head is None: 811 | print("empty") 812 | return None 813 | 814 | temp = self.head 815 | while temp.data != x: 816 | if temp.next == self.head: 817 | print("your data not found") 818 | return 819 | temp = temp.next 820 | t = temp.next 821 | temp.next = t.next 822 | del(t) 823 | 824 | def delete(self, x): 825 | if self.head is None: 826 | print("empty") 827 | return None 828 | 829 | elif self.head.next == self.head: 830 | if self.head.data == x: 831 | del(self.head) 832 | self.head = None 833 | return 834 | else: 835 | print("your data not found") 836 | return 837 | 838 | temp = self.head 839 | while temp.next.data != x: 840 | if temp.next == self.head: 841 | print("your data not found") 842 | return None 843 | temp = temp.next 844 | 845 | t = temp.next 846 | temp.next = t.next 847 | del(t) 848 | 849 | # write replace method 850 | def replace(self, old_data, new_data): 851 | if self.head is None: 852 | print("empty") 853 | return None 854 | temp = self.head 855 | while temp.data != old_data: 856 | if temp.next == self.head: 857 | print("your data not found") 858 | return None 859 | temp = temp.next 860 | temp.data = new_data 861 | 862 | ################################################################################################################################################ 863 | 864 | # لیست پیوندی دو طرفه 865 | 866 | class dNode: 867 | def __init__(self, data): 868 | self.back = None 869 | self.data = data 870 | self.next = None 871 | 872 | class dLinkedList: 873 | def __init__(self): 874 | self.head = None 875 | 876 | def insert_first(self, data): 877 | a = dNode(data) 878 | if self.head is None: 879 | self.head = a 880 | return 881 | 882 | a.next = self.head 883 | a.next.back = a 884 | self.head = a 885 | 886 | def insert_last(self, data): 887 | a = dNode(data) 888 | if self.head is None: 889 | self.head = a 890 | return 891 | 892 | temp = self.head 893 | while temp.next != None: 894 | temp = temp.next 895 | temp.next = a 896 | a.back = temp 897 | 898 | def insert_after(self, x, data): 899 | if self.head is None: 900 | print("empty") 901 | return None 902 | 903 | temp = self.head 904 | while temp.data != x: 905 | if temp.next is None: 906 | print("your data not found") 907 | return None 908 | temp = temp.next 909 | 910 | a = dNode(data) 911 | if temp.next: 912 | a.next = temp.next 913 | temp.next = a 914 | a.back = temp 915 | a.next.back = a 916 | else: 917 | temp.next = a 918 | a.back = temp 919 | 920 | def delete_first(self): 921 | if self.head is None: 922 | print("empty") 923 | return None 924 | 925 | elif self.head.next is None: 926 | del(self.head) 927 | self.head = None 928 | return None 929 | 930 | temp = self.head 931 | self.head = self.head.next 932 | self.head.back = None 933 | del(temp) 934 | 935 | def delete_last(self): 936 | if self.head is None: 937 | print("empty") 938 | return None 939 | 940 | temp = self.head 941 | while temp.next != None: 942 | temp = temp.next 943 | 944 | temp.back.next = None 945 | del(temp) 946 | 947 | def delete_after(self, x): 948 | if self.head is None: 949 | print("empty") 950 | return None 951 | 952 | elif self.head.next is None: 953 | return 954 | 955 | temp = self.head 956 | while temp.data != x: 957 | if temp.next is None: 958 | print("your data not found") 959 | return None 960 | temp = temp.next 961 | 962 | temp.next = temp.next.next 963 | a = temp.next.back 964 | temp.next.back = temp 965 | del(a) 966 | 967 | def delete(self, x): 968 | if self.head is None: 969 | print("empty") 970 | return None 971 | 972 | elif self.head.data == x: 973 | a = self.head 974 | self.head = a.next 975 | self.head.back = None 976 | del(a) 977 | return None 978 | 979 | temp = self.head 980 | while temp.data != x: 981 | if temp.next is None: 982 | print("your data not found") 983 | return None 984 | temp = temp.next 985 | 986 | if temp.next is None: 987 | temp.back.next = None 988 | del(temp) 989 | else: 990 | temp.back.next = temp.next 991 | temp.next.back = temp.back 992 | del(temp) 993 | 994 | def show(self): 995 | if self.head is None: 996 | print("empty") 997 | return None 998 | elif self.head.next == self.head: 999 | print(self.head.data) 1000 | return 1001 | else: 1002 | temp = self.head 1003 | while temp.next != self.head: 1004 | print(temp.data) 1005 | temp = temp.next 1006 | 1007 | ################################################################################################################################################ 1008 | 1009 | # لیست پیوندی دو طرفه حلقوی 1010 | 1011 | class dNode: 1012 | def __init__(self, data): 1013 | self.data = data 1014 | self.next = None 1015 | self.back = None 1016 | 1017 | class CdLinekd_list: 1018 | def __init__(self): 1019 | self.head = None 1020 | 1021 | def insert_first(self, data): 1022 | a = dNode(data) 1023 | if self.head is None: 1024 | self.head = a 1025 | self.head.next = self.head 1026 | self.head.back = self.head 1027 | else: 1028 | temp = self.head 1029 | while temp.next != self.head: 1030 | temp = temp.next 1031 | a.next = temp.next 1032 | temp.next.back = a 1033 | temp.next = a 1034 | a.back = temp 1035 | self.head = a 1036 | 1037 | def insert_last(self, data): 1038 | a = dNode(data) 1039 | if self.head is None: 1040 | self.head = a 1041 | self.head.next = self.head 1042 | self.head.back = self.head 1043 | else: 1044 | temp = self.head 1045 | while temp.next != self.head: 1046 | temp = temp.next 1047 | a.next = self.head 1048 | self.head.back = a 1049 | temp.next = a 1050 | a.back = temp 1051 | 1052 | def insert_after(self, x, data): 1053 | if self.head is None: 1054 | print("empty") 1055 | return None 1056 | else: 1057 | temp = self.head 1058 | while temp.data != x: 1059 | if temp.next == self.head: 1060 | print("your data not found") 1061 | return None 1062 | else: 1063 | temp = temp.next 1064 | a = dNode(data) 1065 | a.next = temp.next 1066 | temp.next.back = a 1067 | temp.next = a 1068 | a.back = temp 1069 | 1070 | def delete_first(self): 1071 | if self.head is None: 1072 | print("empty") 1073 | return None 1074 | elif self.head.next == self.head: 1075 | del(self.head) 1076 | self.head = None 1077 | return None 1078 | else: 1079 | temp = self.head 1080 | while temp.next != self.head: 1081 | temp = temp.next 1082 | temp.next = temp.next.next 1083 | temp.next.back = temp 1084 | del(self.head) 1085 | self.head = temp.next 1086 | 1087 | 1088 | def delete_last(self): 1089 | if self.head is None: 1090 | print("empty") 1091 | return None 1092 | elif self.head.next == self.head: 1093 | del(self.head) 1094 | self.head = None 1095 | return 1096 | else: 1097 | temp = self.head 1098 | 1099 | while temp.next.next != self.head: 1100 | temp = temp.next 1101 | del(temp.next) 1102 | temp.next = self.head 1103 | self.head.back = temp 1104 | 1105 | 1106 | def delete_after(self, x): 1107 | if self.head is None: 1108 | print("empty") 1109 | return None 1110 | temp = self.head 1111 | while temp.data != x: 1112 | if temp.next == self.head: 1113 | print("your data not found") 1114 | return 1115 | temp = temp.next 1116 | t = temp.next 1117 | temp.next = t.next 1118 | t.next.back = temp 1119 | del(t) 1120 | 1121 | def delete(self, x): 1122 | if self.head is None: 1123 | print("empty") 1124 | return None 1125 | 1126 | elif self.head.next == self.head: 1127 | if self.head.data == x: 1128 | del(self.head) 1129 | self.head = None 1130 | return 1131 | else: 1132 | temp = self.head 1133 | while temp.next.data != x: 1134 | if temp.next == self.head: 1135 | print("your data not found") 1136 | return None 1137 | temp = temp.next 1138 | t = temp.next 1139 | temp.next = t.next 1140 | t.next.back = temp 1141 | del(t) 1142 | 1143 | def show(self): 1144 | if self.head is None: 1145 | print("empty") 1146 | return None 1147 | else: 1148 | temp = self.head 1149 | while temp.next != self.head: 1150 | print(temp.daat) 1151 | temp = temp.next 1152 | 1153 | ################################################################################################################################################ 1154 | 1155 | # کلاس درخت باینری 1156 | 1157 | class bnode: 1158 | def __init__(self,d): 1159 | self.Lchild = None 1160 | self.data = d 1161 | self.Rchild = None 1162 | 1163 | class btree: 1164 | def __init__(self): 1165 | self.root = None 1166 | 1167 | def insLeft(self,d): 1168 | if self.root is None: #شرط خالی بودن 1169 | self.root = bnode(d) #در نظر گرفتن به عنوان ریشه در صورت خالی بودن 1170 | else: 1171 | temp = self.root # کپی از ریشه 1172 | while temp.Lchild: #حرکت تا چپ ترین خانه 1173 | temp = temp.Lchild 1174 | temp.Lchild = bnode(d) # اضافه کردن فرزند چپ به چپ ترین خانه 1175 | 1176 | def insRight(self,d): 1177 | if self.root: #شرط خالی نبودن 1178 | temp = self.root 1179 | while temp.Rchild: #حرکت تا راست ترین خانه 1180 | temp = temp.Rchild 1181 | temp.Rchild = bnode(d) # اضافه کردن فرزند راست به راست ترین خانه 1182 | else: 1183 | self.root = bnode(d) #در نظر گرفتن به عنوان ریشه در صورت خالی بودن 1184 | 1185 | def displayNLR(self): # Node-Left-Right نمایش با ترتیب 1186 | self.showNLR(self.root) #صدا زدن متد کمکی 1187 | 1188 | def showNLR(self,root): 1189 | if root: #شرط خالی نبودن 1190 | print(root.data,end=" ") #چاپ ریشه 1191 | 1192 | self.showLNR(root.Lchild) #تابع بازگشتی با در نظر گرفتن 1193 | #فرزند چپ به عنوان ریشه 1194 | 1195 | self.showLNR(root.Rchild) #تابع بازگشتی با در نظر گرفتن 1196 | #فرزند راست به عنوان ریشه 1197 | 1198 | 1199 | def displayLNR(self): #Left-Node-Right نمایش با ترتیب 1200 | self.showLNR(self.root) #صدا زدن متد کمکی 1201 | 1202 | def showLNR(self,root): #متد کمکی 1203 | if root: #شرط خالی نبودن 1204 | self.showLNR(root.Lchild) #تابع بازگشتی با در نظر گرفتن 1205 | #فرزند چپ به عنوان ریشه 1206 | 1207 | print(root.data,end=" ") #چاپ ریشه 1208 | 1209 | self.showLNR(root.Rchild) #تابع بازگشتی با در نظر گرفتن 1210 | #فرزند راست به عنوان ریشه 1211 | 1212 | 1213 | def displayLRN(self): #Left-Right_Node نمایش با ترتیب 1214 | self.showLRN(self.root) #صدا زدن متد کمکی 1215 | 1216 | def showLRN(self,node): #متد کمکی 1217 | if node: #شرط خالی نبودن 1218 | self.showLRN(node.Lchild) #تابع بازگشتی با در نظر گرفتن 1219 | #فرزند چپ به عنوان ریشه 1220 | 1221 | self.showLRN(node.Rchild) #تابع بازگشتی با در نظر گرفتن 1222 | #فرزند راست به عنوان ریشه 1223 | print(node.data,end = ' ') #چاپ ریشه 1224 | 1225 | def levelOrder(self): #Level نمایش با ترتیب 1226 | list = [] # ایجاد لیست 1227 | temp = self.root # کپی از ریشه 1228 | if temp is None: # شرط خالی بودن 1229 | return 1230 | list.append(temp) #اضافه کردن ریشه به لیست 1231 | while list: #شرط خالی نبودن لیست 1232 | k = list.pop(0) #برداشتن اولین ایتم لیست 1233 | print(k.data,end = ' ') #چاپ ایتم 1234 | 1235 | if k.Lchild: #شرط وجود داشتن فرزند چپ 1236 | list.append(k.Lchild) #اضافه کردن فرزند چپ به لیست 1237 | if k.Rchild: #شرط وجود داشتن فرزند راست 1238 | list.append(k.Rchild) #اضافه کردن فرزند راست به لیست 1239 | 1240 | 1241 | def insAfterL(self,x,d): #افزودن فرزند چپ به نود مورد نظر 1242 | self.pinsAfterL(self.root,x,d) # صدا زدن متد کمکی 1243 | 1244 | def pinsAfterL(self,node,x,d): #متد کمکی 1245 | if node: #شرط خالی نبودن 1246 | if node.data == x: #تطابق نود فعلی با نود مورد نظر 1247 | temp = node.Lchild #کپی از فرزند چپ فعلی 1248 | node.Lchild = bnode(d) #قرار دادن داده جدید به عنوان فرزند چپ جدید 1249 | node.Lchild.Lchild = temp # قرار دادن فرزند چپ قبلی به عنوان نوه چپ 1250 | self.pinsAfterL(node.Lchild,x,d) #جستجوی در فرزند های چپ برای رسیدن به نود مورد نظر 1251 | self.pinsAfterL(node.Rchild,x,d) #جستجوی در فرزند های راست برای رسیدن به نود مورد نظر 1252 | 1253 | def insAfterR(self,x,d): #افزودن فرزند راست به نود مورد نظر 1254 | self.pinsAfterR(self.root,x,d) # صدا زدن متد کمکی 1255 | 1256 | def pinsAfterR(self,node,x,d): #متد کمکی 1257 | if node: #شرط خالی نبودن 1258 | if node.data == x: #تطابق نود فعلی با نود مورد نظر 1259 | temp = node.Rchild #کپی از فرزند راست فعلی 1260 | node.Rchild = bnode(d) #قرار دادن داده جدید به عنوان فرزند راست جدید 1261 | node.Rchild.Rchild = temp # قرار دادن فرزند راست قبلی به عنوان نوه راست 1262 | self.pinsAfterR(node.Rchild,x,d) #جستجوی در فرزند های راست برای رسیدن به نود مورد نظر 1263 | self.pinsAfterR(node.Lchild,x,d) #جستجوی در فرزند های راست برای رسیدن به نود مورد نظر 1264 | 1265 | 1266 | 1267 | def delLeft(self): #حذف چپ ترین نود 1268 | if self.root is None: #شرط خالی بودن 1269 | return print("empty") 1270 | if self.root.Lchild is None: #شرط عدم وجود فرزند چپ 1271 | temp = self.root.Rchild # کپی از فرزند راست 1272 | del self.root #حذف ریشه 1273 | self.root = temp #قرار دادن فرزند راست به عنوان ریشه جدید 1274 | return 1275 | temp = self.root #کپی از ریشه 1276 | while temp.Lchild.Lchild: #حرکت تا یک خانه قبل از چپ ترین نود 1277 | temp = temp.Lchild 1278 | temp1 = temp.Lchild #کپی از چپ ترین نود 1279 | temp.Lchild = None #حذف چپ ترین نود 1280 | del temp1 1281 | 1282 | def delRight(self): #حذف راست ترین نود 1283 | if self.root is None: #شرط خالی بودن 1284 | return print("empty") 1285 | if self.root.Rchild is None: #شرط عدم وجود فرزند راست 1286 | temp = self.root.Lchild # کپی از فرزند چپ 1287 | del self.root #حذف ریشه 1288 | self.root = temp #قرار دادن فرزند راست به عنوان ریشه جدید 1289 | return 1290 | temp = self.root #کپی از ریشه 1291 | while temp.Rchild.Rchild: #حرکت تا یک خانه قبل از راست ترین نود 1292 | temp = temp.Rchild 1293 | temp1 = temp.Rchild #کپی از راست ترین نود 1294 | temp.Rchild = None #حذف راست ترین نود 1295 | del temp1 1296 | 1297 | def delete_x(self, x): 1298 | if self.root is None: 1299 | print('empty') 1300 | return None 1301 | else: 1302 | self.pdelete(self.root, x) 1303 | def pdelete(self, node, x): 1304 | if node != None: 1305 | if node.Lchild: 1306 | if node.Lchild.data == x: 1307 | del(node.Lchild) 1308 | node.Lchild = None 1309 | return None 1310 | self.pdelete(node.Lchild, x) 1311 | self.pdelete(node.Rchild, x) 1312 | 1313 | if node.Rchild: 1314 | if node.Rchild.data == x: 1315 | del(node.Rchild) 1316 | node.Rchild = None 1317 | return None 1318 | self.pdelete(node.Lchild, x) 1319 | self.pdelete(node.Rchild, x) 1320 | 1321 | if node.data == x: 1322 | node = None 1323 | return 1324 | 1325 | ################################################################################################################################################ 1326 | 1327 | # کلاس جستجوی درخت باینری 1328 | 1329 | class bnode: 1330 | def __init__(self,d): 1331 | self.Lchild = None 1332 | self.data = d 1333 | self.Rchild = None 1334 | 1335 | class BST: 1336 | def __init__(self): 1337 | self.root = None 1338 | self.list = [] 1339 | 1340 | def add(self , x): 1341 | if self.root is None: #empty 1342 | self.root = bnode(x) 1343 | self.list.append(x) 1344 | else: 1345 | self.padd(self.root , x) #صدا زدن متد کمکی 1346 | def padd(self , root , x): 1347 | if x > root.data: #اگر دیتای جدید از ریشه بزرگتر باشد 1348 | if root.Rchild == None: #چک کردن فرزند راست 1349 | root.Rchild = bnode(x) 1350 | self.list.append(x) 1351 | 1352 | else: 1353 | self.padd(root.Rchild,x) #اگر پدر فرزند راست داشته باشد بوسیله 1354 | #تابع بازگشتی فرزند راستش به عنوان ریشه در 1355 | # نظر گرفته میشود و شروط دوباره چک مبشوند 1356 | 1357 | if x < root.data: #اگر دیتای جدید از ریشه کوچکتر باشد 1358 | if root.Lchild is None: #چک کردن فرزند راست 1359 | root.Lchild = bnode(x) 1360 | self.list.append(x) 1361 | 1362 | else: 1363 | self.padd(root.Lchild,x)#اگر پدر فرزند چپ داشته باشد بوسیله 1364 | #تابع بازگشتی فرزند چپش به عنوان ریشه در 1365 | # نظر گرفته میشود و شروط دوباره چک مبشوند 1366 | return 1367 | 1368 | 1369 | def show(self): 1370 | return self.pshow(self.root) #صدا زدن متد کمکی 1371 | def pshow(self,root): 1372 | if root: #شرط خالی نبودن 1373 | self.pshow(root.Rchild) #تابع بازگشتی با ورودی فرزند راست به عنوان ریشه 1374 | print(root.data, end=' ')#چاپ ریشه فعلی 1375 | self.pshow(root.Lchild) #تابع بازگشتی با ورودی فرزند چپ به عنوان ریشه 1376 | return 1377 | 1378 | 1379 | # کوییز 1380 | # تابعی بنویسید که یک 1381 | # BST 1382 | # را از ورودی گرفته و لیست مربوط به آن را بازگرداند 1383 | def CreateList(Tree): 1384 | print(Tree.list) 1385 | 1386 | 1387 | # کوییز 1388 | # برعکس تابع قبل 1389 | def createTree(A): 1390 | Tree = BST() 1391 | for i in A: 1392 | Tree.add(i) 1393 | return Tree 1394 | 1395 | ################################################################################################################################################ 1396 | 1397 | # Max Heap کلاس 1398 | 1399 | class MaxHeap: 1400 | def __init__(self): 1401 | self.list = [] # ایجاد یک لیست برای ذخیره عناصر هیپ 1402 | 1403 | def insert(self, x): 1404 | """افزودن عنصر به هیپ.""" 1405 | self.list.append(x) # افزودن عنصر به انتهای لیست 1406 | self.Heapifydu(len(self.list) - 1) # متعادل کردن هیپ به سمت بالا 1407 | 1408 | def Heapifydu(self, n): 1409 | """متعادل کردن هیپ به سمت بالا.""" 1410 | p = (n - 1) // 2 # محاسبه اندیس والد 1411 | if p != n: # چک کردن اینکه والد با خود عنصر متفاوت باشد 1412 | if self.list[n] > self.list[p]: # اگر مقدار عنصر بزرگ‌تر از والد باشد 1413 | self.list[n], self.list[p] = self.list[p], self.list[n] # جابجایی عنصر با والد 1414 | self.Heapifydu(p) # ادامه متعادل‌سازی از موقعیت والد 1415 | 1416 | def Heapifyud(self, n): 1417 | """متعادل کردن هیپ به سمت پایین.""" 1418 | e = 2 * n + 1 # محاسبه اندیس فرزند چپ 1419 | r = 2 * n + 2 # محاسبه اندیس فرزند راست 1420 | if e < len(self.list): # بررسی اینکه فرزند چپ در محدوده باشد 1421 | if r < len(self.list): # بررسی اینکه فرزند راست در محدوده باشد 1422 | if self.list[n] < self.list[e] and self.list[r] < self.list[e]: # چک کردن بزرگ‌ترین فرزند 1423 | self.list[e], self.list[n] = self.list[n], self.list[e] # جابجایی با فرزند چپ 1424 | self.Heapifyud(e) # ادامه متعادل‌سازی از موقعیت فرزند چپ 1425 | elif self.list[n] < self.list[r] and self.list[r] > self.list[e]: # بررسی فرزند راست 1426 | self.list[r], self.list[n] = self.list[n], self.list[r] # جابجایی با فرزند راست 1427 | self.Heapifyud(r) # ادامه متعادل‌سازی از موقعیت فرزند راست 1428 | else: 1429 | return # اگر نیازی به جابجایی نبود 1430 | else: 1431 | if self.list[e] > self.list[n]: # بررسی تنها فرزند چپ 1432 | self.list[n], self.list[e] = self.list[e], self.list[n] # جابجایی با فرزند چپ 1433 | return 1434 | else: 1435 | return 1436 | 1437 | def delRoot(self): 1438 | """حذف عنصر ریشه از هیپ.""" 1439 | if len(self.list) == 0: # اگر هیپ خالی باشد 1440 | return 1441 | if len(self.list) == 1: # اگر هیپ تنها یک عنصر داشته باشد 1442 | self.list.pop() # حذف تنها عنصر موجود 1443 | return 1444 | e = len(self.list) - 1 # محاسبه اندیس آخرین عنصر 1445 | self.list[e], self.list[0] = self.list[0], self.list[e] # جابجایی ریشه با آخرین عنصر 1446 | self.list.pop() # حذف آخرین عنصر که اکنون ریشه است 1447 | self.Heapifyud(0) # متعادل‌سازی هیپ به سمت پایین از ریشه 1448 | 1449 | def display(self): 1450 | """نمایش عناصر هیپ.""" 1451 | print("عناصر هیپ:", self.list) 1452 | 1453 | def delete(self, value): 1454 | """حذف عنصر مشخص شده از هیپ.""" 1455 | try: 1456 | index = self.list.index(value) # پیدا کردن اندیس عنصر 1457 | self.list[index] = self.list[-1] # جایگزینی عنصر با آخرین عنصر 1458 | self.list.pop() # حذف آخرین عنصر 1459 | if index < len(self.list): 1460 | self.Heapifyud(index) # متعادل‌سازی به سمت پایین 1461 | self.Heapifydu(index) # متعادل‌سازی به سمت بالا 1462 | except ValueError: 1463 | print(f"مقدار {value} در هیپ پیدا نشد.") 1464 | 1465 | ################################################################################################################################################ 1466 | 1467 | # Min Heap کلاس 1468 | 1469 | class MinHeap: 1470 | def __init__(self): 1471 | self.list = [] # ایجاد یک لیست برای ذخیره عناصر هیپ 1472 | 1473 | def insert(self, x): 1474 | """افزودن عنصر به هیپ.""" 1475 | self.list.append(x) # افزودن عنصر به انتهای لیست 1476 | self.Heapifydu(len(self.list) - 1) # متعادل کردن هیپ به سمت بالا 1477 | 1478 | def Heapifydu(self, n): 1479 | """متعادل کردن هیپ به سمت بالا.""" 1480 | p = (n - 1) // 2 # محاسبه اندیس والد 1481 | if p != n: # چک کردن اینکه والد با خود عنصر متفاوت باشد 1482 | while n > 0 and self.list[n] < self.list[p]: 1483 | self.list[n], self.list[p] = self.list[p], self.list[n] # جابجایی عنصر با والد 1484 | self.Heapifydu(p) # ادامه متعادل‌سازی از موقعیت والد 1485 | 1486 | def Heapifyud(self, n): 1487 | """متعادل کردن هیپ به سمت پایین.""" 1488 | e = 2 * n + 1 # محاسبه اندیس فرزند چپ 1489 | r = 2 * n + 2 # محاسبه اندیس فرزند راست 1490 | if e < len(self.list): # بررسی اینکه فرزند چپ در محدوده باشد 1491 | if r < len(self.list): # بررسی اینکه فرزند راست در محدوده باشد 1492 | if self.list[n] > self.list[e] and self.list[r] > self.list[e]: # چک کردن کوچک‌ترین فرزند 1493 | self.list[e], self.list[n] = self.list[n], self.list[e] # جابجایی با فرزند چپ 1494 | self.Heapifyud(e) # ادامه متعادل‌سازی از موقعیت فرزند چپ 1495 | elif self.list[n] > self.list[r] and self.list[r] < self.list[e]: # بررسی فرزند راست 1496 | self.list[r], self.list[n] = self.list[n], self.list[r] # جابجایی با فرزند راست 1497 | self.Heapifyud(r) # ادامه متعادل‌سازی از موقعیت فرزند راست 1498 | else: 1499 | return # اگر نیازی به جابجایی نبود 1500 | else: 1501 | if self.list[e] < self.list[n]: # بررسی تنها فرزند چپ 1502 | self.list[n], self.list[e] = self.list[e], self.list[n] # جابجایی با فرزند چپ 1503 | return 1504 | else: 1505 | return 1506 | 1507 | def delRoot(self): 1508 | """حذف عنصر ریشه از هیپ.""" 1509 | if len(self.list) == 0: # اگر هیپ خالی باشد 1510 | return 1511 | if len(self.list) == 1: # اگر هیپ تنها یک عنصر داشته باشد 1512 | self.list.pop() # حذف تنها عنصر موجود 1513 | return 1514 | e = len(self.list) - 1 # محاسبه اندیس آخرین عنصر 1515 | self.list[e], self.list[0] = self.list[0], self.list[e] # جابجایی ریشه با آخرین عنصر 1516 | self.list.pop() # حذف آخرین عنصر که اکنون ریشه است 1517 | self.Heapifyud(0) # متعادل‌سازی هیپ به سمت پایین از ریشه 1518 | 1519 | def display(self): 1520 | """نمایش عناصر هیپ.""" 1521 | print("عناصر هیپ:", self.list) 1522 | 1523 | def delete(self, value): 1524 | """حذف عنصر مشخص شده از هیپ.""" 1525 | try: 1526 | index = self.list.index(value) # پیدا کردن اندیس عنصر 1527 | self.list[index] = self.list[-1] # جایگزینی عنصر با آخرین عنصر 1528 | self.list.pop() # حذف آخرین عنصر 1529 | if index < len(self.list): 1530 | self.Heapifyud(index) # متعادل‌سازی به سمت پایین 1531 | self.Heapifydu(index) # متعادل‌سازی به سمت بالا 1532 | except ValueError: 1533 | print(f"مقدار {value} در هیپ پیدا نشد.") 1534 | 1535 | ################################################################################################################################################ 1536 | 1537 | # کلاس گراف 1538 | 1539 | class Graph: 1540 | def __init__(self, n): 1541 | self.M = [[0] * n for _ in range(n)] # ایجاد ماتریس n*n برای نگهداری گراف 1542 | 1543 | def insertEdge(self, s, t): 1544 | """افزودن یال به گراف غیر جهت دار.""" 1545 | if s < len(self.M[0]) and t < len(self.M[0]): # بررسی اینکه ایندکس‌ها معتبر هستند 1546 | self.M[s][t] = 1 # ایجاد یال از گره s به گره t 1547 | self.M[t][s] = 1 # گراف غیرجهت‌دار: ایجاد یال از گره t به گره s 1548 | 1549 | def delEdge(self, s, t): 1550 | """حذف یال از گراف غیر جهت دار.""" 1551 | if s < len(self.M[0]) and t < len(self.M[0]): # بررسی اینکه ایندکس‌ها معتبر هستند 1552 | self.M[s][t] = 0 # حذف یال از گره s به گره t 1553 | self.M[t][s] = 0 # حذف یال از گره t به گره s 1554 | 1555 | def countEdge(self): 1556 | """شمارش تعداد یال‌ها در گراف.""" 1557 | c = 0 # شمارنده تعداد یال‌ها 1558 | for i in range(len(self.M[0])): # بررسی هر گره 1559 | c = sum(self.M[i]) + c # جمع کردن یال‌های مربوط به گره‌ها 1560 | c = c / 2 # چون گراف غیر جهت‌دار است، باید تعداد یال‌ها را نصف کنیم 1561 | print(c) # نمایش تعداد یال‌ها 1562 | 1563 | def bfs(self, start): 1564 | """جستجوی عرضی (BFS) در گراف از راس شروع.""" 1565 | visited = [False] * len(self.M) # لیستی برای نشان دادن بازدید شدن گره‌ها 1566 | queue = [start] # صف برای ذخیره گره‌ها در طی جستجو 1567 | visited[start] = True # علامت‌گذاری گره شروع به عنوان بازدید شده 1568 | print("مسیر BFS:", end=" ") # نمایش عنوان مسیر 1569 | while queue: # تا زمانی که صف خالی نباشد 1570 | node = queue.pop(0) # گره اول صف را بردار 1571 | print(node, end=" ") # نمایش گره فعلی 1572 | for i in range(len(self.M[node])): # بررسی تمام گره‌های متصل به گره فعلی 1573 | if self.M[node][i] == 1 and not visited[i]: # اگر یالی بین گره‌ها باشد و گره هنوز بازدید نشده باشد 1574 | queue.append(i) # افزودن گره به صف 1575 | visited[i] = True # علامت‌گذاری گره به عنوان بازدید شده 1576 | print() # خط جدید پس از اتمام جستجو 1577 | 1578 | def dfs(self, start): 1579 | """جستجوی عمقی (DFS) در گراف از راس شروع.""" 1580 | print(start, end=" ") # نمایش گره فعلی 1581 | # تغییر مقدار گره به 2 برای نشان دادن اینکه بازدید شده 1582 | self.M[start][start] = 2 1583 | for i in range(len(self.M[start])): # بررسی تمام گره‌های متصل به گره فعلی 1584 | if self.M[start][i] == 1 and self.M[i][i] != 2: # اگر یالی بین گره‌ها باشد و گره هنوز بازدید نشده باشد 1585 | self.dfs(i) # فراخوانی تابع DFS برای گره بعدی 1586 | 1587 | def display(self): 1588 | """نمایش گراف به صورت ماتریس adjacency.""" 1589 | print("ماتریس گراف غیر جهت دار:") 1590 | for row in self.M: 1591 | print(row) 1592 | 1593 | ################################################################################################################################################ 1594 | 1595 | # کلاس گراف جهت دار 1596 | 1597 | class GraphD: # گراف جهت دار 1598 | def __init__(self, n): 1599 | self.M = [[0] * n for _ in range(n)] # ایجاد ماتریس n*n برای نگهداری گراف جهت دار 1600 | 1601 | def insertEdge(self, s, t): 1602 | """افزودن یال به گراف جهت دار.""" 1603 | if s < len(self.M[0]) and t < len(self.M[0]): # بررسی اینکه ایندکس‌ها معتبر هستند 1604 | self.M[s][t] = 1 # ایجاد یال از گره s به گره t 1605 | 1606 | def delEdge(self, s, t): 1607 | """حذف یال از گراف جهت دار.""" 1608 | if s < len(self.M[0]) and t < len(self.M[0]): # بررسی اینکه ایندکس‌ها معتبر هستند 1609 | self.M[s][t] = 0 # حذف یال از گره s به گره t 1610 | 1611 | def bfs(self, start): 1612 | """جستجوی عرضی (BFS) در گراف جهت دار.""" 1613 | visited = [False] * len(self.M) # لیستی برای نشان دادن بازدید شدن گره‌ها 1614 | queue = [start] # صف برای ذخیره گره‌ها در طی جستجو 1615 | visited[start] = True # علامت‌گذاری گره شروع به عنوان بازدید شده 1616 | print("مسیر BFS:", end=" ") # نمایش عنوان مسیر 1617 | while queue: # تا زمانی که صف خالی نباشد 1618 | node = queue.pop(0) # گره اول صف را بردار 1619 | print(node, end=" ") # نمایش گره فعلی 1620 | for i in range(len(self.M[node])): # بررسی تمام گره‌های متصل به گره فعلی 1621 | if self.M[node][i] == 1 and not visited[i]: # اگر یالی بین گره‌ها باشد و گره هنوز بازدید نشده باشد 1622 | queue.append(i) # افزودن گره به صف 1623 | visited[i] = True # علامت‌گذاری گره به عنوان بازدید شده 1624 | print() # خط جدید پس از اتمام جستجو 1625 | 1626 | def dfs(self, start): 1627 | """جستجوی عمقی (DFS) در گراف جهت دار.""" 1628 | print(start, end=" ") # نمایش گره فعلی 1629 | # تغییر مقدار گره به 2 برای نشان دادن اینکه بازدید شده 1630 | self.M[start][start] = 2 1631 | for i in range(len(self.M[start])): # بررسی تمام گره‌های متصل به گره فعلی 1632 | if self.M[start][i] == 1 and self.M[i][i] != 2: # اگر یالی بین گره‌ها باشد و گره هنوز بازدید نشده باشد 1633 | self.dfs(i) # فراخوانی تابع DFS برای گره بعدی 1634 | 1635 | def display(self): 1636 | """نمایش گراف به صورت ماتریس adjacency.""" 1637 | print("ماتریس گراف جهت دار:") 1638 | for row in self.M: 1639 | print(row) 1640 | 1641 | ################################################################################################################################################ 1642 | 1643 | # کلاس گراف وزن دار 1644 | 1645 | class GraphW: # گراف وزن دار 1646 | def __init__(self, n): 1647 | self.M = [[0] * n for _ in range(n)] # ایجاد ماتریس n*n برای نگهداری گراف وزن دار 1648 | 1649 | def insertEdge(self, s, t, w): 1650 | """افزودن یال وزن دار به گراف.""" 1651 | if s < len(self.M[0]) and t < len(self.M[0]): # بررسی اینکه ایندکس‌ها معتبر هستند 1652 | self.M[s][t] = w # قرار دادن وزن یال در خانه مربوطه 1653 | 1654 | def delEdge(self, s, t): 1655 | """حذف یال از گراف وزن دار.""" 1656 | if s < len(self.M[0]) and t < len(self.M[0]): # بررسی اینکه ایندکس‌ها معتبر هستند 1657 | self.M[s][t] = 0 # حذف یال از گره s به گره t 1658 | self.M[t][s] = 0 # حذف یال از گره t به گره s (برای گراف غیرجهت‌دار) 1659 | 1660 | def bfs(self, start): 1661 | """جستجوی عرضی (BFS) در گراف وزن دار.""" 1662 | visited = [False] * len(self.M) # لیستی برای نشان دادن بازدید شدن گره‌ها 1663 | queue = [start] # صف برای ذخیره گره‌ها در طی جستجو 1664 | visited[start] = True # علامت‌گذاری گره شروع به عنوان بازدید شده 1665 | print("مسیر BFS:", end=" ") # نمایش عنوان مسیر 1666 | while queue: # تا زمانی که صف خالی نباشد 1667 | node = queue.pop(0) # گره اول صف را بردار 1668 | print(node, end=" ") # نمایش گره فعلی 1669 | for i in range(len(self.M[node])): # بررسی تمام گره‌های متصل به گره فعلی 1670 | if self.M[node][i] > 0 and not visited[i]: # اگر وزن یال مثبت باشد و گره هنوز بازدید نشده باشد 1671 | queue.append(i) # افزودن گره به صف 1672 | visited[i] = True # علامت‌گذاری گره به عنوان بازدید شده 1673 | print() # خط جدید پس از اتمام جستجو 1674 | 1675 | def dfs(self, start): 1676 | """جستجوی عمقی (DFS) در گراف وزن دار.""" 1677 | print(start, end=" ") # نمایش گره فعلی 1678 | # تغییر مقدار گره به 2 برای نشان دادن اینکه بازدید شده 1679 | self.M[start][start] = 2 1680 | for i in range(len(self.M[start])): # بررسی تمام گره‌های متصل به گره فعلی 1681 | if self.M[start][i] > 0 and self.M[i][i] != 2: # اگر وزن یال مثبت باشد و گره هنوز بازدید نشده باشد 1682 | self.dfs(i) # فراخوانی تابع DFS برای گره بعدی 1683 | 1684 | def display(self): 1685 | """نمایش گراف به صورت ماتریس adjacency (وزن‌دار).""" 1686 | print("ماتریس گراف وزن دار:") 1687 | for row in self.M: 1688 | print(row) 1689 | 1690 | ################################################################################################################################################ 1691 | 1692 | # کلاس گراف جهت دار و وزن دار 1693 | 1694 | class GraphDW: 1695 | def __init__(self, n): 1696 | # ایجاد ماتریس adjacency برای گراف جهت‌دار و وزن‌دار با ابعاد n*n 1697 | self.M = [[0] * n for _ in range(n)] 1698 | 1699 | def insertEdge(self, s, t, w=1): 1700 | """افزودن یال وزن‌دار به گراف جهت‌دار.""" 1701 | if s < len(self.M) and t < len(self.M): 1702 | self.M[s][t] = w # اضافه کردن وزن یال از گره s به گره t 1703 | 1704 | def delEdge(self, s, t): 1705 | """حذف یال از گراف جهت‌دار.""" 1706 | if s < len(self.M) and t < len(self.M): 1707 | self.M[s][t] = 0 # حذف یال از گره s به گره t 1708 | 1709 | def bfs(self, start): 1710 | """جستجوی عرضی (BFS) در گراف جهت‌دار از راس شروع.""" 1711 | visited = [False] * len(self.M) 1712 | queue = [start] 1713 | visited[start] = True 1714 | print("مسیر BFS:", end=" ") 1715 | 1716 | while queue: 1717 | node = queue.pop(0) # گره اول صف را خارج می‌کنیم 1718 | print(node, end=" ") # نمایش گره فعلی 1719 | for i in range(len(self.M[node])): # بررسی تمام گره‌های متصل به گره فعلی 1720 | if self.M[node][i] > 0 and not visited[i]: # اگر یالی وجود داشته باشد و گره بازدید نشده باشد 1721 | queue.append(i) # اضافه کردن گره به صف 1722 | visited[i] = True # نشان دادن اینکه گره بازدید شده است 1723 | print() 1724 | 1725 | def dfs(self, start): 1726 | """جستجوی عمقی (DFS) در گراف جهت‌دار از راس شروع بدون استفاده از visited.""" 1727 | print(start, end=" ") # نمایش گره فعلی 1728 | # تغییر مقدار گره به 2 برای نشان دادن اینکه بازدید شده 1729 | self.M[start][start] = 2 1730 | for i in range(len(self.M[start])): # بررسی تمام گره‌های متصل به گره فعلی 1731 | if self.M[start][i] > 0 and self.M[i][i] != 2: # اگر یالی بین گره‌ها باشد و گره هنوز بازدید نشده باشد 1732 | self.dfs(i) # فراخوانی تابع DFS برای گره بعدی 1733 | 1734 | def display(self): 1735 | """نمایش گراف به صورت ماتریس adjacency (وزن‌دار).""" 1736 | print("ماتریس گراف جهت‌دار و وزن‌دار:") 1737 | for row in self.M: 1738 | print(row) 1739 | 1740 | 1741 | ################################################################################################################################################ 1742 | 1743 | # کلاس گراف جهت دار با لیست های مجاورت حلقوی 1744 | 1745 | class GraphD: 1746 | def __init__(self, n): 1747 | """ایجاد گراف با n گره و لیست‌های مجاورت حلقوی.""" 1748 | self.n = n # تعداد گره‌ها 1749 | # لیست مجاورت برای هر گره (لیست‌های حلقوی) 1750 | self.adj_list = [[] for _ in range(n)] 1751 | 1752 | def insertEdge(self, s, t, w=1): 1753 | """افزودن یال از گره s به گره t با وزن w به گراف جهت‌دار.""" 1754 | if 0 <= s < self.n and 0 <= t < self.n: # بررسی اینکه گره‌ها در محدوده باشند 1755 | self.adj_list[s].append((t, w)) # افزودن یال از گره s به گره t با وزن w 1756 | 1757 | def delEdge(self, s, t): 1758 | """حذف یال از گره s به گره t از گراف جهت‌دار.""" 1759 | if 0 <= s < self.n and 0 <= t < self.n: # بررسی اینکه گره‌ها در محدوده باشند 1760 | # حذف یال از لیست مجاورت گره s که به گره t اشاره می‌کند 1761 | self.adj_list[s] = [x for x in self.adj_list[s] if x[0] != t] 1762 | 1763 | def bfs(self, start): 1764 | """جستجوی عرضی (BFS) از گره start.""" 1765 | visited = [False] * self.n # آرایه visited برای پیگیری گره‌های بازدید شده 1766 | queue = [start] # صف برای مدیریت گره‌ها 1767 | visited[start] = True # علامت‌گذاری گره شروع به عنوان بازدید شده 1768 | print("مسیر BFS:", end=" ") 1769 | 1770 | # اجرای الگوریتم BFS 1771 | while queue: 1772 | node = queue.pop(0) # خارج کردن گره اول صف 1773 | print(node, end=" ") # نمایش گره فعلی 1774 | # بررسی همسایگان گره و افزودن آنها به صف 1775 | for neighbor, weight in self.adj_list[node]: 1776 | if not visited[neighbor]: # اگر گره همسایه بازدید نشده باشد 1777 | visited[neighbor] = True # علامت‌گذاری به عنوان بازدید شده 1778 | queue.append(neighbor) # افزودن گره همسایه به صف 1779 | print() # برای چاپ در خط جدید 1780 | 1781 | def dfs(self, start, visited=None): 1782 | """جستجوی عمقی (DFS) از گره start.""" 1783 | if visited is None: 1784 | visited = [False] * self.n # آرایه visited برای پیگیری گره‌های بازدید شده 1785 | visited[start] = True # علامت‌گذاری گره شروع به عنوان بازدید شده 1786 | print(start, end=" ") # نمایش گره فعلی 1787 | 1788 | # بررسی همسایگان گره و بازگشت به آنها در صورت بازدید نشدن 1789 | for neighbor, weight in self.adj_list[start]: 1790 | if not visited[neighbor]: # اگر گره همسایه بازدید نشده باشد 1791 | self.dfs(neighbor, visited) # فراخوانی بازگشتی برای گره همسایه 1792 | 1793 | def display(self): 1794 | """نمایش گراف به صورت لیست‌های مجاورت حلقوی.""" 1795 | print("لیست‌های مجاورت حلقوی گراف:") 1796 | # نمایش لیست مجاورت برای هر گره 1797 | for i in range(self.n): 1798 | # لیست همسایگان هر گره به همراه وزن یال‌ها 1799 | neighbors = [f"{neighbor} (وزن: {weight})" for neighbor, weight in self.adj_list[i]] 1800 | # چاپ گره و همسایگانش 1801 | print(f"گره {i}: {', '.join(neighbors) if neighbors else 'هیچ یالی ندارد'}") 1802 | 1803 | 1804 | ################################################################################################################################################ 1805 | 1806 | # کلاس گراف جهت دار و وزن دار با لیست های پیوندی حلقوی 1807 | 1808 | class Node: 1809 | def __init__(self, data, weight): 1810 | """ایجاد یک گره جدید با داده و وزن مشخص.""" 1811 | self.data = data # داده (گره همسایه) 1812 | self.weight = weight # وزن یال 1813 | self.next = None # پیوند به گره بعدی (که در ابتدا None است) 1814 | 1815 | class GraphDW: 1816 | def __init__(self, n): 1817 | """ایجاد گراف جهت‌دار و وزن‌دار با n گره و لیست‌های پیوندی حلقوی.""" 1818 | self.n = n # تعداد گره‌ها 1819 | self.adj_list = [None] * n # لیست پیوندی برای هر گره (لیست حلقوی) 1820 | 1821 | def insertEdge(self, s, t, w=1): 1822 | """افزودن یال از گره s به گره t با وزن w به گراف جهت‌دار و وزن‌دار.""" 1823 | if 0 <= s < self.n and 0 <= t < self.n: # بررسی اینکه گره‌ها در محدوده باشند 1824 | new_node = Node(t, w) # ایجاد یک گره جدید برای همسایه t با وزن w 1825 | if self.adj_list[s] is None: 1826 | # اگر گره s لیست همسایگان ندارد، گره جدید به لیست اضافه می‌شود 1827 | self.adj_list[s] = new_node 1828 | new_node.next = new_node # گره جدید خود به خود اشاره کند (حلقوی) 1829 | else: 1830 | # در غیر این صورت، گره جدید به انتهای لیست پیوندی اضافه می‌شود 1831 | current = self.adj_list[s] 1832 | while current.next != self.adj_list[s]: # پیدا کردن آخرین گره 1833 | current = current.next 1834 | current.next = new_node 1835 | new_node.next = self.adj_list[s] # پیوند حلقوی 1836 | 1837 | def delEdge(self, s, t): 1838 | """حذف یال از گره s به گره t از گراف جهت‌دار و وزن‌دار.""" 1839 | if 0 <= s < self.n and 0 <= t < self.n: # بررسی اینکه گره‌ها در محدوده باشند 1840 | current = self.adj_list[s] 1841 | if current is None: 1842 | return # اگر گره s هیچ همسایه‌ای نداشته باشد، کاری انجام نمی‌دهیم 1843 | prev = None 1844 | # پیمایش لیست پیوندی تا گره مورد نظر پیدا شود 1845 | while current.data != t: 1846 | prev = current 1847 | current = current.next 1848 | if current == self.adj_list[s]: # به حلقه رسیدیم و یال پیدا نشد 1849 | return 1850 | if prev is None: 1851 | # اگر گره اول باشد (همسایه اول) 1852 | if current.next == self.adj_list[s]: 1853 | # اگر فقط یک گره وجود داشته باشد 1854 | self.adj_list[s] = None 1855 | else: 1856 | # اگر چند گره در لیست باشند 1857 | last = self.adj_list[s] 1858 | while last.next != self.adj_list[s]: # پیدا کردن آخرین گره 1859 | last = last.next 1860 | self.adj_list[s] = current.next 1861 | last.next = self.adj_list[s] 1862 | else: 1863 | prev.next = current.next # حذف یال از لیست پیوندی 1864 | 1865 | def bfs(self, start): 1866 | """جستجوی عرضی (BFS) از گره start.""" 1867 | visited = [False] * self.n # آرایه visited برای پیگیری گره‌های بازدید شده 1868 | queue = [start] # صف برای مدیریت گره‌ها 1869 | visited[start] = True # علامت‌گذاری گره شروع به عنوان بازدید شده 1870 | print("مسیر BFS:", end=" ") 1871 | 1872 | # اجرای الگوریتم BFS 1873 | while queue: 1874 | node = queue.pop(0) # خارج کردن گره اول صف 1875 | print(node, end=" ") # نمایش گره فعلی 1876 | current = self.adj_list[node] 1877 | if current: # اگر گره همسایگان دارد 1878 | while True: 1879 | if not visited[current.data]: # اگر گره همسایه بازدید نشده باشد 1880 | visited[current.data] = True # علامت‌گذاری به عنوان بازدید شده 1881 | queue.append(current.data) # افزودن گره همسایه به صف 1882 | current = current.next 1883 | if current == self.adj_list[node]: # بازگشت به گره شروع (حلقوی) 1884 | break 1885 | print() # برای چاپ در خط جدید 1886 | 1887 | def dfs(self, start, visited=None): 1888 | """جستجوی عمقی (DFS) از گره start.""" 1889 | if visited is None: 1890 | visited = [False] * self.n # آرایه visited برای پیگیری گره‌های بازدید شده 1891 | visited[start] = True # علامت‌گذاری گره شروع به عنوان بازدید شده 1892 | print(start, end=" ") # نمایش گره فعلی 1893 | 1894 | # پیمایش همسایگان و فراخوانی بازگشتی برای هر همسایه 1895 | current = self.adj_list[start] 1896 | while current: 1897 | if not visited[current.data]: # اگر گره همسایه بازدید نشده باشد 1898 | self.dfs(current.data, visited) # فراخوانی بازگشتی برای گره همسایه 1899 | current = current.next 1900 | if current == self.adj_list[start]: # بازگشت به گره شروع (حلقوی) 1901 | break 1902 | 1903 | def display(self): 1904 | """نمایش گراف به صورت لیست‌های پیوندی حلقوی.""" 1905 | print("لیست‌های پیوندی حلقوی گراف:") 1906 | # نمایش لیست پیوندی برای هر گره 1907 | for i in range(self.n): 1908 | current = self.adj_list[i] 1909 | neighbors = [] 1910 | if current: 1911 | while True: 1912 | neighbors.append(f"{current.data} (وزن: {current.weight})") 1913 | current = current.next 1914 | if current == self.adj_list[i]: # به حلقه رسیدیم 1915 | break 1916 | print(f"گره {i}: {', '.join(neighbors) if neighbors else 'هیچ یالی ندارد'}") 1917 | 1918 | 1919 | ################################################################################################################################################ 1920 | -------------------------------------------------------------------------------- /ساختمان داده.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kourosh07/SD_py/99b873965cce958705b6fffdb82f18d1e4682bda/ساختمان داده.pdf --------------------------------------------------------------------------------