מבוא לתכנות בשפתC רשימה מקושרתTzachi (Isaac) Rosen
Cמבוא לתכנות בשפת
רשימה מקושרת
Tzachi (Isaac) Rosen
מגבלות של מערכים
מוגבלים בגודל•בזבזני–גדול מידי –
ההגדלה יקרה–קטן מידי –
הכנסה ומחיקה של אברים•יקרה ועלולה לגרום לבזבוז–
רשימות מקושרות: פתרון•מתגבר על כל הבעיות שמערך מציג–
יוצר בעיה חדשה–אין גישה ישירה•
Tzachi (Isaac) Rosen
רשימות מקושרות
חד כיוונית•
מעגלית•
דו כיוונית•
ואפשר להמציא עוד•
Tzachi (Isaac) Rosen
של רשימה מקושרת Link))חוליה
מורכבת משני שדות•
(data)נתונים –
(next)מצביע לחוליה הבאה –
NULLהמצביע יכול להיות גם •
Tzachi (Isaac) Rosen
רשימה מקושרת חד כיוונית
נייצג רשימה מקושרת באמצעות מצביע לחוליה •Linkמסוג
NULL–רשימה ריקה –
מצביע לחוליה הראשונה של –רשימה לא ריקה –
הרשימה
Tzachi (Isaac) Rosen
חוליה ברשימההוספה ומחיקה של
הוספה•
מחיקה•
Tzachi (Isaac) Rosen
Cמבנה חוליה בשפת
Tzachi (Isaac) Rosen
typedef struct link {
int data;
struct link * next;
} Link;
דוגמה מורחבת
Tzachi (Isaac) Rosen
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#define RAND(R) ((int) (((double) rand() / RAND_MAX) * R))
#define INT2BOOL(exp) ((exp) ? "true" : "false")
typedef struct link {
int data;
struct link * next;
} Link;
דוגמה מורחבת
Tzachi (Isaac) Rosen
Link * newLink(int data) {
Link *p = (Link *) malloc(sizeof(Link));
p->data = data;
p->next = NULL;
return p;
}
void insertAfter(Link * p, int data) { // assume p is not NULL
Link *q = newLink(data);
q->next = p->next;
p->next = q;
}
void deleteAfter(Link * p) { // assume p is not NULL
Link *q = p->next;
if (q != NULL) {
p->next = q->next;
free(q);
}
}
דוגמה מורחבת
Tzachi (Isaac) Rosen
Link * createRandomLinkedList() {
Link *head = NULL;
int length = RAND(10);
if (length > 0) {
head = newLink(RAND(100));
Link * p = head;
int i;
for (i = 1; i < length; ++i) {
insertAfter(p, RAND(100));
p = p->next;
}
}
return head;
}
void deleteLinkedList(Link * head) {
if (head != NULL) {
while (head->next != NULL)
deleteAfter(head);
free(head);
}
}
דוגמה מורחבת
Tzachi (Isaac) Rosen
Link * insertBefore(Link *p, int data) { // p could be NULL
Link * q = newLink(data);
q->next = p;
return q;
}
Link * mergeIntoLinkedList(Link * head, int data) {
if (head == NULL)
return newLink(data);
if (data < head->data)
return insertBefore(head, data);
Link *p = head;
while (p->next != NULL && p->next->data < data)
p = p->next;
insertAfter(p, data);
return head;
}
Link * createRandomSortedLinkedList() {
Link *head = NULL;
int length = RAND(10);
while (length > 0) {
head = mergeIntoLinkedList(head, RAND(100));
--length;
}
return head;
}
דוגמה מורחבת
Tzachi (Isaac) Rosen
int linkedListLength(Link * head) {
int n = 0;
while (head != NULL) {
++n;
head = head->next;
}
return n;
}
void printLinkedList(Link * head) {
printf("%2d: ", linkedListLength(head));
while (head != NULL) {
printf("(%2d)", head->data);
head = head->next;
}
printf("\n");
}
דוגמה מורחבת
Tzachi (Isaac) Rosen
int isMemInLinkedList(Link *head, int k) {
while (head != NULL) {
if (head->data == k)
return 1;
head = head->next;
}
return 0;
}
Link * reverseLinkedList(Link * head) {
Link * p = NULL;
while (head != NULL) {
Link *q = head;
head = head->next;
q->next = p;
p = q;
}
return p;
}
וברקורסיה
Tzachi (Isaac) Rosen
int isEmpty(Link *list) {
return list == NULL;
}
int head(Link *list) { // assume not an empty linked list
return list->data;
}
Link * tail(Link *list) { // assume not an empty linked list
return list->next;
}
וברקורסיה
Tzachi (Isaac) Rosen
int length(Link *list) {
if (isEmpty(list))
return 0;
return 1 + length(tail(list));
}
void print(Link * list) {
if (isEmpty(list))
printf("\n");
else {
printf("(%2d)", head(list));
print(tail(list));
}
}
int isMem(Link *list, int k) {
if (isEmpty(list))
return 0;
if (head(list) == k)
return 1;
return isMem(tail(list), k);
}
וברקורסיה
Tzachi (Isaac) Rosen
Link * reverse(Link *list) {
if (isEmpty(list) || isEmpty(tail(list)))
return list;
Link *p = reverse(tail(list));
list->next->next = list;
list->next = NULL;
return p;
}
Link * mergeInto (Link *list, int data) {
if (list == NULL || data < head(list))
return insertBefore(list, data);
list->next = mergeInto(tail(list), data);
return list;
}
שימוש
Tzachi (Isaac) Rosen
5: (33)(15)(66)(41)(37)false5: (37)(41)(66)(15)(33)5: (33)(15)(66)(41)(37)7: ( 0)(26)(26)(34)(53)(59)(68)8: ( 0)(26)(26)(34)(50)(53)(59)(68)
int main() {
Link *head;
srand(time(NULL));
head = createRandomLinkedList();
printLinkedList(head);
printf("%s\n", INT2BOOL(isMemInLinkedList(head, 3)));
head = reverseLinkedList(head);
printLinkedList(head);
head = reverse(head);
printf("%2d: ", length(head));
print(head);
deleteLinkedList(head);
head = createRandomSortedLinkedList();
printLinkedList(head);
head = mergeInto(head, 50);
printLinkedList(head);
deleteLinkedList(head);
return 0;
}