Download presentation
Presentation is loading. Please wait.
1
ليست هاي پيوندي
2
تعريف ليست پيوندي Link List
تعريف : مجموعه ای از گره ها که هرگره حداقل شامل يک فيلد داده ويک فيلد اشاره گر است. اشاره گر هر گره از نوع خود گره است. هر گره به وسيله ی اشاره گر خود به گره بعدی اشاره می کند. B . . . A Z
3
نقايص کار با آرايه ها به صورت ترتيبی
بازگشت ناپذير بودن حافظه بعد از گرفتن آن لازم بودن پيش بينی بيشترين حافظه مورد نياز پر هزينه بودن اضافه کردن عنصر پر هزينه بودن حذف کردن عنصر
4
پر هزينه بودن اضافه کردن عنصر
می خواهيم C را به آن اضافه کنيم به طوری که ترتيب آن الفبايی بماند. A B D E F Shift
5
پر هزينه بودن اضافه کردن عنصر-ادامه
A B C D E F سوال:مرتبه الگوريتم بالا چيست؟ O(n)
6
پر هزينه بودن حذف کردن عنصر
اگر بخواهيم B را از آرايه ی قبلی حذف کنيم بايد تمام عناصر بعد از آن را يکی به عقب بياوريم A B C D E F shift مرتبه اين الگوریتم نيز (n)O است.
7
راه حل مشکلات ناشی از کار با آرايه به صورت ترتيبی
استفاده ازليست پيوندی مزايا: مجبور نيستيم داده ها را در فواصل مشخصی ازهم قرار دهيم. می توان حافظه ی بدون استفاده را به کامپيوتربرگرداند.
8
- عمليات ليست پيوندي - ايجاد ليست - درج گره در ليست - حذف گره از ليست
- جستجو در ليست - مرتب سازي ليست - معكوس كردن ليست - و ...
9
ساختمان داده مورد نياز جهت پياده سازي لينك ليست: استفاده از آرايه
استفاده از اشاره گر Pointer
10
پياده سازي ليست پيوندی به وسيله ی آرايه
برای ايجاد اين ليست بايد از دو آرايه استفاده کرد. آرايه ی اول برای داده ها : اين آرايه از نوع داده ی مورد نظر انتخاب می شود (مثلا يک structure) آرايه ی دوم برای اتصال ها : اين آرايه که از نوع int است.متناظر با داده هاست.که نشان دهنده ی آدرس داده بعدی است.
11
پياده سازي ليست پيوندی به وسيله ی آرايه-ادامه
A B C I H K -1 8 1 5 3 Link First = 4 Data K H A C I B [0] [1] [2] [3] [4] [5] [6] [7] [8] [9]
12
درج در ليست پيوندی Data Link A B C I H K -1 8 1 5 3 K H A C I B [0]
Data Link -1 8 1 5 3 K H A C I B First = 4 [0] [1] [2] [3] [4] [5] [6] [7] [8] [9]
13
درج در ليست پيوندی-ادامه
A B C I H K D First = 4 -1 8 1 5 3 K H A C D I B Data Link [0] [1] [2] [3] [4] [5] [6] [7] [8] [9]
14
درج در ليست پيوندی-ادامه
A B C I H K D -1 8 1 5 3 K H A C D I B Data Link First = 4 [0] [1] [2] [3] [4] [5] [6] [7] [8] [9]
15
درج در ليست پيوندی-ادامه
A B C I H K D -1 8 2 1 5 3 K H A C D I B Data Link First = 4 [0] [1] [2] [3] [4] [5] [6] [7] [8] [9]
16
درج در ليست پيوندی-ادامه
A B C I H K D -1 8 2 1 5 3 K H A C D I B Data Link First = 4 [0] [1] [2] [3] [4] [5] [6] [7] [8] [9]
17
مراحل درج در ليست پيوندی
1)قرار دادن داده ی لينک در آرايه ی داده ها 2)اشاره دادن عضو جديد به عضو بعد از خودش 3)اشاره دادن عضو قبل از عضو جديد به عضو جديد نکته : هميشه ابتدا عضوجديد را در ليست قرار می دهيم سپس عضوهايی را که بايد به عضو جديد اشاره کنند به آن اشاره می دهيم.
18
پياده سازي با اشاره گر تعريف يك نود class CharNode {
private : char data; CharNode *link; }; تعريف يك نود لازم است اين مسئله مشخص شود که فيلدهای ما چه نوع داده ای هستند.(به عنوان مثال می توان يک کاراکتر)
19
روش های طراحی ليست طرح اول:
متغير first را از نوع به عنوان متغير سراسری در نظر می گيريم. Node *first; اشاره گر link و کاراکتر data اعضای private هستند. خطاي زمان اجرا
20
روش های طراحی ليست طرح دوم:
data , link را به صورت public در بياوریم. (نقض اصل محصور سازي) از توابع set و get برای هر کدام استفاده نماييم.(نقض اصل مخفي سازي)
21
طراحی ليست به وسيله ی کلاس مدير
اصل مخفی سازی داده ها دسترسي ساده تر به اطلاعات يک کلاس دیگر تعريف می شود که حاوی کل ليست باشد (first).
22
طراحی ليست به وسيله ی کلاس مدير-ادامه
class List { public : //list manipulation operations private: Node * first; }; class Node friend class List; private : char data; Node * link;
23
رابطه ی بين کلاس مدير (List) و کلاس گره (Node)
first A B N . . . Node رابطه ی مفهومی بين کلاس ليست و کلاس نود List first ... A B N Node رابطه ی واقعی بين کلاس ليست و کلاس نود
24
دستکاری اشاره گرها در C++
تعريف يک اشاره گر: Node * pointer; گرفتن حافظه برای اشاره گر: pointer = new Node; آزاد کردن حافظه : delete pointer;
25
مثال – ايجاد ليست با دو گره
void List::Create2() { first = new Node (‘B’); first link = new Node (‘C’); } Node :: Node (char element =0) { data = element; link = 0 ; //null pointer B C first
26
مثال – درج گره در ابتداي ليست
void List :: InsertFirst () { Node *t = new Node(‘A’); t link = first; first = t; } A B C first A B C first A
27
يک کلاس ليست پيوندی با قابليت استفاده مجدد
بهتر نيست که يک بار يک ليست را طراحی کنيم و چندين بار از آن استفاده کنيم؟ برای اين که بتوانيم از يک ليست پيوندی برای چند بار استفاده کنيم بايد از کلاس های الگو(template) استفاده کنيم.
28
تعريف ليست های با قابليت استفاده ی مجدد
template <class Type> class List; //forward declaration template <class Type> class ListNode { friend class List<Type>; private : Type date; ListNode *link; }; class List public : List(){first = 0;} private: ListNode <Type> *first;
29
عملکردها روی ليست پيوندی
1) نمايش ليست پيوندی 2) اضافه کردن عنصری در ليست 3) حذف کردن عنصر و ...
30
نمایش ليست پيوندی(پيمايش)
Output : A temp first ِA ِB C ِD
31
نمايش ليست پيوندی(پيمايش)-ادامه
first temp ِA ِB C ِD Output : A B
32
نمايش ليست پيوندی(پيمايش)-ادامه
first temp ِA ِB C ِD Output : A B C
33
نمايش ليست پيوندی(پيمايش)-ادامه
first temp ِA ِB C ِD Output : A B C D
34
نمايش ليست پيوندی)پيمايش(-ادامه
void ListNode :: Print() { if( !first ) return; //no node Node *temp = first; while(temp) //traverse list cout << temp data; temp = temp link; //next node }
35
اضافه کردن عنصر جديد البته برای کاربردهای مختلف اضافه کردن فرق می کند.
ما در اينجا اضافه کردن عنصر جديد بعد از يک عنصر مشخص را نشان می دهيم. مراحل کار: 1) نصب عنصر جديد 2) تنظيم اشاره گرهای مربوط به عنصر جديد
36
اضافه کردن عنصر جديد curNode first newNode
37
اضافه کردن عنصر جديد-ادامه
curNode first A B D E newNode C newNode link = curNode link ;
38
اضافه کردن عنصر جديد-ادامه
curNode first A B D E newNode C curNode link = newNode ;
39
اضافه کردن عنصر جديد-ادامه
curNode first A B C D E newNode
40
اضافه کردن عنصر جديد-ادامه
template <class Type> void ListNode<Type> :: Insert (Node*curNode ,Node *newNode) { newNode --> link = curNode --> link ; //assign newNode curNode --> link = newNode ; //assign curNode }
41
اضافه کردن به ابتدای ليست
بدين دليل اين حالت خاص را بررسی می کنیم که بعد از اضافه کردن عنصر بايد اشاره گر first به ابتدای ليست اشاره کند. مراحل کار 1) نصب عنصر جديد 2) اشاره دادن اشاره گر first به عنصر جديد
42
اضافه کردن به ابتدای ليست
first newNode A B C D E
43
اضافه کردن به ابتدای ليست-ادامه
newNode A first B C D E newNode link = first;
44
اضافه کردن به ابتدای ليست-ادامه
first newNode E D C B A first = newNode;
45
اضافه کردن به ابتدای ليست-ادامه
first newNode A B C D E
46
اضافه کردن به ابتدای ليست-ادامه
template <class Type> void ListNode<Type> :: InsertFirst(Node *newNode) { if( !first ) //no node first = newNode; newNode --> link = NULL; return; } newNode --> link = first; //assign newNode
47
حذف عنصر از ليست پيوندی مراحل کار: 1) تنظيم اشاره گرها
2) حذف کردن گره (آزاد کردن حافظه)
48
حذف عنصر از ابتدای ليست پيوندی
curNode first ِA ِB C ِD ِE
49
حذف عنصر از ليست پيوندی-ادامه
curNode first ِA ِB C ِD ِE first = first link;
50
حذف عنصر از ابتدای ليست پيوندی-ادامه
first ِB C ِD ِE delete cur;
51
حذف عنصر از ليست پيوندی-ادامه
curNode first ِA ِB C ِD ِE temp Node *temp = first;
52
حذف عنصر از ليست پيوندی-ادامه
curNode first ِA ِB C ِD ِE temp while( temp link != cur) temp = temp link;
53
حذف عنصر از ليست پيوندی-ادامه
curNode first ِA ِB C ِD ِE temp while( temp link != cur) temp = temp link;
54
حذف عنصر از ليست پيوندی-ادامه
first curNode ِA ِB C ِD ِE temp temp link = cur link;
55
حذف عنصر از ليست پيوندی-ادامه
first ِA ِB ِD ِE temp delete cur;
56
حذف عنصر از ليست پيوندی-ادامه
template <class Type> void ListNode<Type> :: Delete( Node *cur) { if( cur == first ) first = first link; delete cur; return ; } Node *temp = first; while( temp link != cur) temp = temp link; temp link = cur link;
57
سوالات عناصر يك ليست را برعكس نماييد. سوال 3 از تمرينات بخش 4-3
دو زنجير (ليست پيوندي) را بهم متصل كنيد و يك زنجير توليد كنيد. عنصري را به انتهاي ليست اضافه كنيد.
58
ليست های حلقوی به وسيله ی اتصال آخرين گره به اولين گره می توان ليست حلقوی را توليد کرد. در اين گونه ليست ها به راحتی می توان از آخر ليست به اول ليست پرش کرد.
59
نمونه ای از ليست حلقوی first ِA ِB C ِD ِE
60
عملکردهای ليست حلقوی بيشتر کارهايی را که روی ليست معمولی انجام می داديم می توانيم روی ليست حلقوی انجام دهيم. بايد بعد از تغييرات ليست ، حلقوی بماند.
61
نمايش ليست حلقوی void ListNode :: Print() {
if( !first ) return; //no node Node *temp = first; while(temp link != first)//traverse list cout << temp data; temp = temp link; //next node }
62
اضافه کردن عنصر جديد تابعی که برای اضافه کردن عنصر جديد بعد از يک عنصر خاص برای ليست ساده گفته شد اين جا نيز کاربرد دارد. اما برای اضافه کردن عنصر به ابتدای ليست بايد تابعی جديد نوشته شود. يک اشاره گر جديد last به عنصر آخراشاره كند. ليست را برای پيدا کردن آخرين عنصر پيمايش کرد.
63
اضافه کردن به ابتدای ليست حلقوي
void InsertFirst(Node * newNode) { if( !last ) //no node last = first = newNode; first link = first; } else newNode link = first; last link = newNode; first = newNode;
64
اضافه کردن به ابتدای ليست حلقوی-ادامه
void InsertFirst(Node * newNode) { if( !first ) //no node first = newNode; first link = first; } else newNode link = first; Node *temp = first; while(temp link != first) temp = temp link; temp link = newNode;
65
پشته های پيوندی با استفاده از ليست پيوندی اين استراتژی را پياده سازی کنیم. همين طور که می دانید در پشته ورود و خروج داده ها از يک طرف انجام می شود. top
66
تعريف کلاس پشته class Stack { public : Stack() {top = 0;};
void Push( int ); int Pop(); private: StackNode *top; }; class StackNode friend class stack; int data; StackNode * link; StackNode(int d = 0,StackNode *li = 0):data(d),link(li){};
67
درج در پشته top void Push(int newElement) {
top = new StackNode(newElement , top); } top A E D C B
68
حذف از پشته temp top E D C B A temp = top;
69
حذف از پشته-ادامه top top top = temp link; temp E D C B A temp E D C
temp top E D C B A top = temp link;
70
حذف از پشته-ادامه top B A E D C temp delete temp;
71
حذف از پشته-ادامه int Stack :: Pop() {
if( !top ){cout << “empty stack”; return -1;} StackNode *temp = top; int retVal = temp data; top = top link; delete temp; return retVal; }
72
صف های پيوندی همان طور که می دانيد در استراتژی صف ورود اطلاعات از يک طرف و خروج اطلاعات از طرف ديگر است. به اين دليل به دو اشاره گر به نام های rear و front نياز داريم. front rear
73
تعريف کلاس صف پيوندی class QueueNode { friend class Queue; private :
int data; QueueNode * link; QueueNode(int d = 0,QueueNode *li = 0): data(d) , link(li){}; }; class Queue public : Queue() {front = rear = 0;} void AddQ( int ); int DelQ(); private: QueueNode *rear , *front;
74
اضافه کردن عنصر جديد به صف پيوندی- درج در انتها
void Queue :: AddQ( int newElement) { if( !front ) front = rear = new QueueNode( newElement , 0); else rear = rear link = new QueueNode( newElement, 0); } front rear A B C D E
75
حذف از يک صف پيوندی – حذف از ابتدا
int Queue :: DelQ() { if( !front ){cout << “empty queue.”; return;} QueueNode *temp = front; int retVal = front data; front = front link; delete temp; return retVal; }
76
پروژه برنامه نويسي سوال 10 [پروژه برنامه نويسي] تمرينات بخش 4-8
نكته: قسمت 4-8 بايستي به طور كامل خوانده شود.(ماتريس خلوت)
77
ليست های پيوندی دوگانه مشکل اساسی ليست های يک طرفه عدم دسترسي به گره قبلی ليست های دوگانه با اضافه کردن يک اشاره گر به گره ی قبلی اين مشكل را حل كرده است.
78
انواع ليست های پيوندی دوگانه
ليست دوطرفه ی ساده A B C D E first ليست دوطرفه ی حلقوی A B C D E first
79
تعريف کلاس ليست دوطرفه class DblListNode { friend class DblList;
private: int data; DblListNode * next, *pre; }; class DblList public : //operations DblListNode *first;
80
اضافه کردن عنصر به ليست دوطرفه ساده
A B D E first C cur newEle next pre
81
اضافه کردن عنصر به ليست دوطرفه ساده-ادامه
A B D E first C cur newEle newEle next = cur next;
82
اضافه کردن عنصر به ليست دوطرفه ساده-ادامه
A B D E first C cur newEle cur next = newEle;
83
اضافه کردن عنصر به ليست دوطرفه ساده-ادامه
A B D E first C cur newEle cur next = newEle;
84
اضافه کردن عنصر به ليست دوطرفه ساده-ادامه
A B D E first C cur newEle (newEle next) pre = newEle;
85
اضافه کردن عنصر به ليست دوطرفه ساده-ادامه
A B C D first E cur newEle
86
سوال اگر بخواهيم عنصر newEle را به ابتداي ليست اضافه كنيم؟
اگر ليست خالي باشد؟
87
اضافه کردن عنصر به لِست دوطرفه ساده
void DblList :: Insert(DblListNode *cur,DblListNode *newEle) { newEle next = cur next; newEle pre = cur; cur next = newEle; if(newEle next) (newEle next) pre = newEle; }
88
حذف از ليست دوطرفه ساده A B C D first E cur
89
حذف از ليست دوطرفه ساده -ادامه
cur A B C D E first ( cur next ) pre = cur pre;
90
حذف از ليست دوطرفه ساده-ادامه
A B C D first E cur ( cur pre ) next = cur next;
91
حذف از ليست دوطرفه ساده -ادامه
A next pre B D first E ( cur pre ) next = cur next;
92
حذف از لُيست دوطرفه ساده -ادامه
A next pre B D first E
93
سوال اگر بخواهيم عنصر ابتداي ليست را حذف كنيم؟ اگر ليست خالي باشد؟
94
حذف از ليست دوطرفه ساده void DblList :: Delete( Node * cur) {
if( cur next) ( cur next ) pre = cur pre; ( cur pre ) next = cur next; delete cur; return; } ( cur --> pre ) --> next = 0;
95
حذف از ابتدای ليست دوطرفه ساده
void DblList :: Delete(DblListNode *cur) { if( cur == first ) Node *temp = first ; if( !first --> next ) delete first; return; } first = first --> next; first --> pre = 0; delete temp;
96
مباحث بعدی ليست دو طرفه حلقوي ليستهاي تعميم يافته ص 216
97
سوالات الگوريتم درج عنصر در انتهای ليست دو طرفه ی حلقوی؟
الگوريتم معکوس کردن ليست دو طرفه ی ساده؟ الگوريتم معکوس کردن ليست دو طرفه ی حلقوی؟
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.