Presentation is loading. Please wait.

Presentation is loading. Please wait.

ليست هاي پيوندي.

Similar presentations


Presentation on theme: "ليست هاي پيوندي."— Presentation transcript:

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 سوالات الگوريتم درج عنصر در انتهای ليست دو طرفه ی حلقوی؟
الگوريتم معکوس کردن ليست دو طرفه ی ساده؟ الگوريتم معکوس کردن ليست دو طرفه ی حلقوی؟


Download ppt "ليست هاي پيوندي."

Similar presentations


Ads by Google