├── README.md
├── app.py
└── ساختمان داده.pdf
/README.md:
--------------------------------------------------------------------------------
1 |
2 | ## تمام کد های ساختمان داده 👇
3 |
4 | ### Source code
5 |
6 | ## جزوه ساختمان داده 👇
7 |
8 | Download PDF
9 |
10 |
11 |
12 | ### با تشکر از تیم پژوهشی تورینگ
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
--------------------------------------------------------------------------------