PDA

توجه ! این یک نسخه آرشیو شده می باشد و در این حالت شما عکسی را مشاهده نمی کنید برای مشاهده کامل متن و عکسها بر روی لینک مقابل کلیک کنید : نكاتي در مورد ساختمان داده(آرايه-صف-پشته-ليست-درخت-گراف)



Y@SiN
10-29-2009, 03:17 PM
سلام
چند وقتي بود ميخواستم يه تاپيك در مورد ساختمان داده بزنم و مطالب مفيد مربوط به ساختمان داده رو با كمك دوستان تو اون جمع كنيم تا يه تاپيك جالبي به وجود بياد. من خودم كه چيز زيادي بلد نيستم فقط الگوريتمها و ... تو دانشگاه گفتن رو بلدم كه اونارو هم يكي يكي ميذارم.http://www.pnu-club.com/imported/mising.jpg
از دوستان خواهش ميكنم اگه مطلبي دارن كه مفيد ميتونه باشه دريغ نكنند. با تشكر

Y@SiN
10-29-2009, 03:18 PM
اينم رئوس مطالب


1)آرائه

2)پشته

3)صف

4)لیست هاي پيوندي (يك طرفه خطي و ...)

5)درخت

6)گراف

Y@SiN
10-29-2009, 03:18 PM
اولين مطلب رو هم خودم ميذارم
اصلا ميگم اين ساختمان داده چيست؟
عبارت است از ساختارهای دادهای که درحافظهء اصلی کامپیوتر در نظرمی گیریم تا بتوانیم الگوریتمهای برنامه نویسی را بر روی آنها به شکل مناسب پیاده سازی نماییم.

Y@SiN
10-29-2009, 03:20 PM
آرایه:
مجموعه ای از داده ها هستند که نوعشان یکسان است به عنوان مثال:اگر 10 عدد صحیح را بخواهیم در حافظه اصلی قرار دهیم بجای انکه 10 متغیر (int) تعریف بکنیم یک آرایه (int) تعریف می کنیم که 10 خانه داشته باشد .




[Int b [3][4 = آرایه 2 بعدی : مثال






آرایه های 2 بعدی را ماتریس نیز می گویند .

در آرایه های 2 بعد به بالا برای اینکه بتوانیم عناصر را به صورت صحیح از خانه هایی که ذخیره شده اند بازیابی نماییم بایستی مشخص گردد که اگر ذخیرهء عناصر به شکل سطری است بازیابی آنها نیز به شکل سطری باشد و اگر ستونی است بازیابی انها به صورت ستونی باشد.




روش سطری پیمایش و ذخیرهء آرایه ها :





b11 , b12 , b13 , b14 , b21 , b22 , b23 , b24 , b31 , b32 , b33 , b34

در پیمایش سطری آرایه ها اندیسهای خانه های آرایه از سمت راست تغییر می کنند بطوریکه اندیس سمت چپ به صورت ثابت باقی می ماند و یک واحد یک واحد به اندیس سمت راست اضافه می شود تا زمانیکه به ماکسیمم مقدار خود برسد که در این لحظه یک واحد به اندیس سمت چپ اضافه می شود و دوباره اندیس سمت راست شروع به افزایش می یابد واین کار تا زمانی ادامه پیدا می کند که هر 2 اندیس به ماکسیمم مقدار خود برسد.
مثال : ماتریس 3 بعدی زیر را به صورت سطری پیمایش کنید:



[Int a [3][4][3


نقل قول:

a111 , a211 , a311 , a121 , a221 , a321 , a131 , a231 , a331 , a141 , a241 , a341 , a112 , a212 , a312 , a122 , a222 , a322 , a132 , a232 , a332 , a142 , a242 , a342 , a113 , a213 , a313 , a123 , a223 , a323 , a133 , a233 , a333 , a143 , a243 , a343





روش ستونی پیمایش ذخیره ها :

در روش ستونی اندیسهای آرایه از سمت چپ شروع به افزایش می کنند یعنی اندیسهای سمت چپ یک واحد یک واحد اضافه می شوند تا زمانی که به ماکسیمم مقدار خود برسند که در این لحظه یک واحد اندیس سمت راست اضافه می شود و دوباره اندیس سمت چپ از 1 شروع به افزایش می کند و این کار تا زمانی انجام می گیرد که تمامی اندیسها به ماکسیمم مقدار خود برسند .



b11 , b21, b31 , b12 , b22 , b32 , b13 , b23 , b33 , b14 , b24 , b34

نقل قول:



a111 , a211 , a311 , a121 , a221 , a321 , a131 , a231 , a331 , a141 , a241 , a341 , a112 , a212 , a312 , a122 , a222 , a322 , a132 , a232 , a332 , a142 , a242 , a342 , a113 , a213 , a313 , a123 , a223 , a323 , a133 , a233 , a333 , a143 , a243 , a343

دوستان تا اينجا رو داشته باشين بقيش رو هم ميذارم

Y@SiN
10-29-2009, 03:22 PM
ماتریس اسپارس (خلوت - پراکنده) :
ماتریسی است که اکثریت عناصر ان مقدار ثابت و غیر قابل محاسبه ( معمولا صفر) می باشد و تنها تعداد کمی از خانه های ان داده ها به درد بخور می باشند بنابراین فضای بسیار زیادی از حافظه اصلی را برای ذخیره کردن این تعداد کم داده ها تلف می کنیم .



مثال :




0 0 0 2 0
0 0 3 0 1
0 0 0 0 0
0 18 0 0 0

به عنوان مثال در ماتریس فوق برای ذخیره کردن چهار عنصر غیر صفر یک ماتریس ( 5 * 4 ) و 20 خانه از حافظه را تلف کرده ایم روشی که برای ذخیرهء بهینهء این نوع ماتریسها استفاده می شود بدین صورت است که یک ماتریس در نظر می گیریم که همیشه 3 ستون خواهد داشت و به تعداد عناصر غیر صفر سطر خواهد داشت که در هر سطر در ستون اول شمارهء سطر مربوط به عنصر غیر صفر ودر ستون دوم شمارء مربوط به ستون عنصر غیر صفر ودر ستون سوم مقدار عنصر غیر صفر را ذخیره خواهیم کرد
که کاهش قابل توجهی در میزان حافظه مصرفی خواهیم داشت.
نقل قول:


i j value
2 2 1
1 1 2
3 3 2
18 4 4



__________________

Y@SiN
10-29-2009, 03:25 PM
الگوريتمهاي مربوط به پيمايش هاي سطري و ستوني


[A [n][m

پیمایش سطری:
کد:

for i: =1 to n do
for j: =1 to m do
write (a [i,j] ) ;
پیمایش ستونی :
کد:

for j: =1 to m do
for i: =1 to n do
write (a[i,j] ) ;

مثال : با استفاده ازfor های تو در تو یک ماتریس 3 بعدی


( 2* 3 * 4 ) به 2 روش سطری و ستونی پیمایش کنید:



پیمایش سطری:
کد:

for i: =1 to 4 do
for j: =1 to 3 do
for k: =1 to 2 do
write ( a [i,j,k] ) ;
پیمایش ستونی :
کد:

for k: =1 to 2 do
for j: =1 to 3 do
for i: =1 to 4 do
write (a[i,j,k]) ;
مثال : با استفاده از for های تو در تو الگوريتمي بنویسید که 2 ماتریس (2 * 3 * 4) رابا یکدیگر جمع کرده ودر ماتریس سوم قرار دهد:

پیمایش سطری:
کد:

for i: =1 to 4 do
for j: =1 to 3 do
for k: =1 to 2 do
c [i,j,k] = b [ i,j,k] + a [i,j,k]
write (c [i,j,k]) ;

__________________

Y@SiN
10-29-2009, 03:25 PM
پشته چیست؟
پشته به لیست مرتبی گفته می شود که عملیات درج و حذف از اون از یک طرف صورت بگیره. عملکرد اون به صورت LIFO هست. (Last In First Out(. یعنی آخرین عنصر وردی، اولین عنصر خروجی هستش. مثل قرار دادن یک سری بشقاب روی هم دیگه که آخرین بشقاب قرار داده شده، اولین بشقابی هست که می شه اونو برداشت.
اما مهمترین کاربرد پشته ذخیره آدرس های بازگشت تو برنامه نویسی و ساخت متغیرهای محلی در صدا زدن توابع است. یکی دیگه از کاربرد های مهم پشته اجرای عملیات undo و redo هست که همه باهاش کار کردیم.

Y@SiN
10-29-2009, 03:28 PM
نمایش پشته
ساده ترین روش برای نمایش پشته استفاده از یک آرایه 1 بعدی به طول n می باشد. در کنار آرایه متغیری به نام top وجود دارد که به عنصر بالایی اشاره دارد. top در ابتدای کار صفر است و از 0 تا n تغییر می کند.
شرط خالی بودن پشته عبارت است از : if top=0
شرط پر بودن پشته عبارت است از : if top= n
زیر برنامه های حذف از پشته (pop) و اضافه کردن به پشته یا نوشتن در آن (push) در زبان C به صورت زیر است:
کد:

void push (item k)
{ if (top ==n-1)
stackfull ();
else
;stack[++top]=k }
کد:

items pop()
} if (top==-1)
stackempty();
else
return stack [top--]; {

Y@SiN
10-29-2009, 03:30 PM
پشته چندگانه:
اگر فقط نیاز به دو پشته در برنامه داشته باشیم راه حل ساده است. برای این منظور از یک آرایه n خانه ای استفاده می کنیم. s[1] ابتدای پشته اول و s[n] ابتدای پشته دوم را نشان می دهد و پشته ها به سمت همدیگر می توانند رشد کنند. بدین ترتیب از حافظه موجد به صورت بهینه استفاده می شود.
ولی اگر بخواهیم بیش از دو پشته داشته باشیم، روش فوق قابل استفاده نیست. در این حال برای نمایش n پشته حافظه s[1..n] را به n قسمت تقسیم می کنیم. تقسیم بندی آرایه ها متناسب با نیازها باشد. در این حالت مقادیر به صورت زیر خواهد بود:
کد:

b[i]=t[i]=[m/n](i-1)+1
که در آن n تعداد پشته ها و m حد بالای آرایه است.
مثال: اگر در آرایه s[1..495] بخواهیم 4 پشته به وجود آوریمآدرس ابتدای هرپشته را بدست آورید. اندازه پشته ها یکسان است.

پاسخ:

m=495 , m=4
b[1]=1
b[2] [495/4](2-1)+1=124
b[3]= [495/4](3-1)+1=247
b[4]=[495/4](4-1)+1=370

در حالت پشته های چندگانه (n>2) ممکن است یکی از پشته ها سریع تر از بقیه پر شود و به همین دلیل استفاده از حافظه بهینه نخواهد بود. برای رفع این مشکل باید عناصر شیفت داده شوند تا در انتهای پشته پشته پر شده فضای خالی تولید شود و این عمل در بدترین حالت o(m) خواهد بود. در پشته های چند گانه (n=2) استفاده از حافظه بهینه است و زمان پردازش نیز از مرتبه o(1) است.

از همه کسانی که این مطلب رو خوندند می پرسم چرا این مرتبه o(1) است؟ لطفاً جواب رو مکتوب تو سایت قرار بدید!!!!!!!!!
زیر برنامه های اضافه و حذف از پشته های چند گانه و صف ها رو در پست بعدی قرار می دهم. فعلاً خداحافظ!

Y@SiN
10-29-2009, 03:33 PM
زیر برنامه های اضافه کردن و حذف کردن از پشته i ام در پشته های چندگانه:

کد:


procedure pop (i:integer,var k:items);
begin
if t[i]=b[i] then stackempty(i)
else begin
k:=s[t[i]];
t[i]:=t[i]-1;
end;
end;
کد:



procedure push (i:integer,var k:items);
begin
if t[i]=b[i+1] then stackfull(i)
else begin
k:=t[i]+1;
s[t[i]]:=k;
end;
end;

__________________

Y@SiN
10-29-2009, 03:34 PM
صف (queue):

صف لیست مرتبی است که عمل اضافه کردن (نوشتن) از یک طرف آن به نام انتهای صف (rear) و عمل خواندن (حذف کردن) از طرف دیگر صف به نام ابتدای صف (Front) می شود. ساختار صف به صورت FIFO است. (First In First Out). یکی از کاربردهای مهم صف در زمانبدی برنامه ها در سیستم عامل هستش. ساده ترین راه نمایش صف استفاده از یک آرایه یک بعدی به طول n می باشد.
برای کار با صف معمولی به دو اشاره گر نیاز داریم: یکی Front که همیشه به یک عنصر قبل از عنصر ابتدایی اشاره می کنه و rear که همیشه به آخرین عنصر اشاره داره.
دامنه تغییرات front و rear از 0 تا n هست و مقادیر اولیه اونها 0 قرار می گیره.
شرط خال بودن صف عبارت است از :
if front = rear
و شرط پر بودن صف عبارت است از :
if rear = n

Y@SiN
10-29-2009, 03:36 PM
زیر برنامه های اضافه کردن و حذف کردن از پشته i ام در پشته های چندگانه:

کد:



{
if (front==rear)
queuempty();
else {
front=(front+1)%n;
reaturn q[front];
}


کد:


void addq(items k)
{
if (front==(rear+1)%n)
queufull();
else {
rear=(rear+1)%n;
q[rear]=k;
}
مشکل اصلی صف ها در این است که صف در یک لحظه می تونه پر و خالی (همزمان) باشه. مثلاً اگر n=5 داده را در یک صف 5 خانه ای ریخته و سپس آنها را بخوانیم در حالتی که r=f=5 داریم:
صف خالی است چون: r=f
صف پر است چون: r=n=5

Y@SiN
10-29-2009, 03:37 PM
مفهوم لیست پیوندی:
غالباً برای ذخیره تعداد زیادی داده ها از آرایه استفاده می کنند. ولی به دلیل ایستا بودن ساختار آرایه و محدودیت کار با آن از ساختار دیگه ای استفاده می شه به نام linked list یا همون لیست پیوندی.
عناصر لیست پیوندی از نوع پویا بوده و عناصر اون الزاماً در کنارهم نمی باشند. (بر عکس آرایه) . به همین دلیل اعمال درج و حذف در اون به راحتی و سریعتر از آرایه است. در مقابل برخی از اعمال مثل جستجو یا مرتب سازی در آرایه سریع تر از لیست پیوندی است.
هر عنصر یا گره (node) حداقل از دو فیلد داده (Data)و اشاره گری به گره بعدی (Link) تشکیل شده است.

Y@SiN
10-29-2009, 03:39 PM
فرم کلی گره ها در زبان c:
کد:


typedef struct NODE *p_node;
typedef struct NODE{
char name[21];
int num;
p_node link;
}
ایجاد زنجیر و دستیابی به فیلدها:

در تکه کد زیر مفهوم زنجیر و طرز ایجاد آنرا بیان می کنیم:
کد:


var
x,y,z:p_node;
begin
new(x);
x^.name:='ali';
x^.num:=123;
x^link:=nil;

z:=x;

new (y);
y^.name:='mohsen';
y^.num:=456;
y^link:=nil;
x^.link=y;
end.
با دستور new می توان یک نود جدید را در زنجیر ساخت.


با دستور new می توان یک نود جدید را در زنجیر ساخت.
در انتهای برنامه دو نود داریم . نود اول با نام ali و نود دوم با نام mohsen.
لیست ها را از 3 من ظر می توان تقسیم کرد:
1- یا یکطرفه هستند یا دو طرفه.
2- یا خطی هستند یا حلقوی.
3- یا بدون Head هستند یا Head دارند.
در قسمت بعدی آنها را توضیح خواهیم داد.

Y@SiN
10-29-2009, 03:40 PM
ادامه مبحث
انواع ليست پيوندي
1)ليست پيوندي يك طرفه خطي
2)ليست پيوندي يك طرفه حلقوي
3)ليست پيوندي دوطرفه خطي
4) ليست پيوندي دوطرفه حلقوي

Y@SiN
10-29-2009, 03:42 PM
هر لیست پیوندی با اشاره گر سر لیست مشخص می شود که معمولا آن رابا (First) یا (Head) مشخص می کنند .(First) یا (Head) اشاره گری است که آدرس گره اول لیست پیوندی را مشخص می کند ، همچنین آخرین گره از لیست پیوندی بخش اشاره گرش (Link) مقدار تهی خواهد داشت که در زبان پاسکال با (Nil) ودر زبان C با (Null) مشخص می شود. (شكل 1 رو ببينيد بزرگه)
به مثال زير توجه كنيد.( شكل 2 رو ببينيد كوچيكه)

کد:




Data (X) = ? (70)
Link (X) = ? (Y)
Data ( Link (x) ) = ? (60)
Link ( Link (w) ) = ? (Y)
Link (Z) = ? (Null)
Data ( First ) = ? (50)
Link ( First ) = ? (X)
Link ( Data (y) ) = ? (بی معنی)

Y@SiN
10-29-2009, 03:48 PM
براي دوستاني كه مي خوان همزمان با پيشروي تاپيك مطالعاتي هم داشته باشند، يه سري اسلايد اينجا قرار ميدم.

Ds-1: مبناها
ds-2: آرايه - مرتب سازي - جستجو
ds-3: پشته و صف و كاربرد آنها
ds-4: ليست پيوندي و انواع آن
ds-5: درخت و گراف و كاربرد آنها

sedigheh 69
11-19-2011, 01:52 PM
سلام
چند وقتي بود ميخواستم يه تاپيك در مورد ساختمان داده بزنم و مطالب مفيد مربوط به ساختمان داده رو با كمك دوستان تو اون جمع كنيم تا يه تاپيك جالبي به وجود بياد. من خودم كه چيز زيادي بلد نيستم فقط الگوريتمها و ... تو دانشگاه گفتن رو بلدم كه اونارو هم يكي يكي ميذارم.http://www.pnu-club.com/imported/mising.jpg
از دوستان خواهش ميكنم اگه مطلبي دارن كه مفيد ميتونه باشه دريغ نكنند. با تشكر:46:
اطلاعاتی راجعه به شرط پر یا خالی بودن پشته میخوام؟

Borna66
11-19-2011, 02:46 PM
:46:
اطلاعاتی راجعه به شرط پر یا خالی بودن پشته میخوام؟

اده ترین روش برای نمایش پشته استفاده از یک آرایه 1 بعدی به طول n می باشد. در کنار آرایه متغیری به نام top وجود دارد که به عنصر بالایی اشاره دارد. top در ابتدای کار صفر است و از 0 تا n تغییر می کند.
شرط خالی بودن پشته عبارت است از : if top=0
شرط پر بودن پشته عبارت است از : if top= n
زیر برنامه های حذف از پشته (pop) و اضافه کردن به پشته یا نوشتن در آن (push) در زبان C به صورت زیر است:
کد:


void push (item k)
{
if (top ==n-1)
stackfull ();
else
;stack[++top]=k
}


items pop()
}
if (top==-1)
stackempty();
else return stack [top--];
{


اما اگر فقط نیاز به دو پشته در برنامه داشته باشیم راه حل ساده است. برای این منظور از یک آرایه n خانه ای استفاده می کنیم. [ s[1 ابتدای پشته اول و [ s[n ابتدای پشته دوم را نشان می دهد و پشته ها به سمت همدیگر می توانند رشد کنند. بدین ترتیب از حافظه موجد به صورت بهینه استفاده می شود.
ولی اگر بخواهیم بیش از دو پشته داشته باشیم، روش فوق قابل استفاده نیست. در این حال برای نمایش n پشته حافظه [ s[1..n را به n قسمت تقسیم می کنیم. تقسیم بندی آرایه ها متناسب با نیازها باشد. در این حالت مقادیر به صورت زیر خواهد بود:

b=t=[m/n](i-1)+1

که در آن n تعداد پشته ها و m حد بالای آرایه است.در اینجا میبینید که دیگر نیازی به استفاده از top نیست.