نحوه راه اندازی گوشی های هوشمند و رایانه های شخصی پرتال اطلاعاتی

مفهوم کلی ساختار داده ساختارهای داده چیست؟

داده های ذخیره شده در حافظه کامپیوتر مجموعه ای از صفر و یک (بیت) است. بیت ها به ترتیب ترکیب می شوند: بایت ها، کلمات و غیره. به هر بخشی از RAM که می تواند یک بایت یا کلمه را در خود جای دهد یک شماره دنباله (آدرس) اختصاص داده می شود.

معنای داده ها چیست، چه نمادهایی بیان می شود - الفبایی یا عددی، این یا آن عدد به چه معناست - همه اینها توسط برنامه پردازش تعیین می شود. تمام داده های لازم برای حل مسائل عملی به چندین نوع مختلف و مفهوم تقسیم می شوند یک نوعنه تنها با نمایش داده ها در فضای آدرس، بلکه با نحوه پردازش آنها.

هر داده را می توان به یکی از دو نوع طبقه بندی کرد: پایه (ساده)، که شکل آن توسط معماری کامپیوتر تعیین می شود، یا پیچیده، طراحی شده توسط کاربر برای حل مشکلات خاص.

انواع داده های ساده نمادها، اعداد و غیره هستند. عناصری که خرد کردن بیشتر آنها منطقی نیست. ساختارهای داده (انواع پیچیده) از داده های ابتدایی تشکیل می شوند.

برخی از سازه ها:

· آرایه(تابع با دامنه محدود) - مجموعه ای ساده از اقلام داده از همان نوع، وسیله ای برای کار با گروهی از داده های همان نوع. یک عنصر واحد از آرایه توسط یک شاخص مشخص می شود. یک آرایه می تواند یک بعدی، دو بعدی و غیره باشد. انواع آرایه های تک بعدی با طول متغیر ساختارهایی از نوع هستند حلقه، پشته، صف و دک.

· در حال ضبط(محصول دکارتی) - مجموعه ای از عناصر داده از انواع مختلف. در ساده ترین حالت، رکورد حاوی تعداد ثابتی از عناصر است که نامیده می شوند حاشیه ها... مجموعه ای از رکوردهای یک ساختار نامیده می شود فایل... (به یک فایل مجموعه داده در حافظه خارجی مانند دیسک مغناطیسی نیز گفته می شود). برای اینکه بتوان رکوردهای فردی را از فایل استخراج کرد، به هر رکورد یک نام یا شماره منحصر به فرد اختصاص داده می شود که به عنوان شناسه آن عمل می کند و در یک فیلد جداگانه قرار دارد. این شناسه نامیده می شود کلید.

ساختارهای داده مانند یک آرایه یا یک رکورد حجم ثابتی را در حافظه کامپیوتر اشغال می کنند، بنابراین به آنها ساختارهای ایستا می گویند. ساختارهای استاتیک نیز شامل یک دسته از.

تعدادی از ساختارها وجود دارد که می توانند طول آنها را تغییر دهند - به اصطلاح ساختارهای پویا... اینها شامل درخت، فهرست، پیوند است.

یک ساختار مهم برای قرار دادن آیتم هایی که نیاز به فضای آدرس غیر خطی دارد می باشد درخت... ساختارهای داده زیادی وجود دارد که می توان آنها را به صورت درختی نشان داد. اینها، به عنوان مثال، ساختارهای طبقه بندی، سلسله مراتبی، بازگشتی و سایر ساختارها هستند. برای اطلاعات بیشتر در مورد درختان، به بخش 1.2.1 مراجعه کنید.

برنج. 1.1. طبقه بندی نوع داده ها

1.1.2 ساختارها یا مدل های داده تعمیم یافته.

در بالا، ما چندین نوع ساختار را در نظر گرفتیم که مجموعه‌ای از عناصر داده هستند: آرایه، درخت، رکورد. یک نوع داده پیچیده تر می تواند شامل این ساختارها به عنوان اعضا باشد. به عنوان مثال، عناصر یک رکورد می تواند یک آرایه، یک پشته، یک درخت و غیره باشد.

انواع پیچیده ای از داده ها وجود دارد، اما مطالعات انجام شده بر روی یک ماده کاربردی بزرگ نشان داده است که در بین آنها، چندین مورد از رایج ترین آنها قابل تشخیص است. ساختارهای تعمیم یافته نیز نامیده می شوند مدل های دادهاز آنجا که آنها دیدگاه کاربر را نسبت به داده های دنیای واقعی منعکس می کنند.

هر مدل داده باید شامل سه جزء باشد:

1. ساختار داده ها - دیدگاه کاربر را در مورد ارائه داده ها توصیف می کند.

2. مجموعه ای از عملیات مجاز بر روی ساختار داده اجرا می شود. مدل داده، حداقل، حضور یک زبان تعریف داده (DLS)، که ساختار ذخیره‌سازی آن‌ها را توصیف می‌کند، و یک زبان دستکاری داده (MDL)، که شامل عملیات استخراج و اصلاح داده‌ها است، فرض می‌کند.

3. محدودیت های یکپارچگی - مکانیزمی برای حفظ انطباق با داده های حوزه موضوعی بر اساس قوانین رسمی توصیف شده.

در فرآیند توسعه تاریخی، از مدل‌های داده زیر در DBMS استفاده شد:

· بر اساس سلسله مراتب،

· شبکه،

· رابطه ای

اخیراً رویکرد شی گرا برای ارائه داده ها اهمیت بیشتری پیدا کرده است.

1.2 روش های دسترسی به داده ها

مسائل ارائه داده ها ارتباط نزدیکی با عملیاتی دارد که این داده ها توسط آنها پردازش می شود. این عملیات عبارتند از: واکشی، تغییر، فعال کردنو یک استثناداده ها. تمام عملیات فوق بر اساس عملیات است دسترسی داشته باشید، که بدون توجه به نحوه ارائه آن قابل بررسی نیست.

در مشکلات جستجو، فرض بر این است که تمام داده ها با یک شناسایی خاص در حافظه ذخیره می شوند و، صحبت از دسترسی، اول از همه، دسترسی به داده ها (به نام کلید) است که به طور منحصر به فرد مجموعه داده های مرتبط را شناسایی می کند.

فرض کنید باید دسترسی به یک فایل حاوی مجموعه‌ای از رکوردهای یکسان را سازماندهی کنیم که هر کدام دارای یک مقدار فیلد کلیدی منحصر به فرد هستند. ساده ترین راه برای جستجو این است که هر رکورد را به صورت متوالی در فایل اسکن کنید تا زمانی که رکوردی را پیدا کنید که مقدار کلید آن با معیارهای جستجو مطابقت دارد. بدیهی است که این روش کاملاً ناکارآمد است، زیرا رکوردهای موجود در فایل بر اساس مقدار فیلد کلید مرتب نمی شوند. مرتب سازی رکوردها در یک فایل نیز قابل اجرا نیست زیرا زمان بیشتری نیز می برد و باید پس از افزودن هر رکورد انجام شود. بنابراین، آنها به شرح زیر عمل می کنند - کلیدها، همراه با اشاره گرها به رکوردهای مربوطه در فایل، در ساختار دیگری کپی می شوند، که به شما امکان می دهد به سرعت عملیات مرتب سازی و جستجو را انجام دهید. هنگام دسترسی به داده ها ابتدا در این ساختار مقدار کلید مربوطه پیدا می شود و سپس یک رکورد از فایل از اشاره گر ذخیره شده با آن به دست می آید.

دو دسته از روش‌ها وجود دارند که دسترسی به داده‌های کلیدی را پیاده‌سازی می‌کنند:

· روش های جستجوی درخت،

· روش های هش کردن

1.2.1 روش های جستجوی درخت

تعریف: درخت مجموعه ای متناهی است که از یک یا چند عنصر تشکیل شده است که گره نامیده می شود، به طوری که:

1. بین گره ها رابطه ای از نوع "منبع - تولید شده" وجود دارد.

2. تنها یک گره وجود دارد که گره منبع ندارد. آن را ریشه گویند;

3. همه گره ها به جز ریشه فقط یک منبع دارند. هر گره می تواند چندین گره فرزند داشته باشد.

4. رابطه "اصلی - زاده شده" فقط در یک جهت عمل می کند، یعنی هیچ نسلی از یک گره نمی تواند اجداد آن شود.

به تعداد گره های منفرد تخم ریزی شده (تعداد زیردرخت های یک ریشه داده شده) آن می گویند درجه... گره با درجه صفر را گره برگ یا انتهایی می گویند. حداکثر مقدار درجه تمام گره های یک درخت داده شده نامیده می شود با درجه درخت.

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

درخت مرتب شده ای که درجه آن حداکثر 2 باشد نامیده می شود دودوییدرخت درخت باینری مخصوصاً هنگام جستجو در RAM استفاده می شود. الگوریتم جستجو: ابتدا آرگومان جستجو با کلید در ریشه مقایسه می شود. اگر آرگومان با کلید مطابقت داشته باشد، جستجو تمام می شود، اگر مطابقت نداشته باشد، در صورتی که آرگومان کمتر از کلید باشد، جستجو در زیردرخت سمت چپ ادامه می یابد و در مواردی که بیشتر از کلید وجود داشته باشد. در زیر درخت سمت راست با افزایش سطح 1، مقایسه را تکرار کنید و گره فعلی را به عنوان ریشه در نظر بگیرید.

مثال: اجازه دهید فهرستی از دانش‌آموزان حاوی نام و میانگین نمره آنها ارائه شود (جدول 1.1 را ببینید). از نام دانش آموز به عنوان کلید استفاده می شود. با فرض اینکه تمام رکوردها دارای طول ثابت هستند، می توان از شماره رکورد به عنوان اشاره گر استفاده کرد. در این صورت افست رکورد موجود در فایل به صورت محاسبه می شود ([record_number] -1) * [record_length] ... اجازه دهید استدلال جستجو "پتروف" باشد. شکل 1.2 یک درخت جستجوی باینری و مسیر جستجوی احتمالی برای این مجموعه داده را نشان می دهد.

جدول 1.1

واسیلیف

کوزنتسوف

تیخومیروف

برنج. 1.2. جستجوی درخت دودویی

توجه داشته باشید که قانون زیر برای مقایسه متغیرهای رشته در اینجا استفاده می شود: مقدار یک کاراکتر مطابق با عدد ترتیبی آن در حروف الفبا در نظر گرفته می شود. بنابراین، «من» از «ک»، و «ک» کمتر از «ج» است. اگر کاراکترهای فعلی در رشته های مقایسه شده مطابقت داشته باشند، کاراکترهای موجود در موقعیت های زیر با هم مقایسه می شوند.

درخت‌های دودویی به‌ویژه زمانی مؤثر هستند که مجموعه کلیدها از قبل شناخته نشده باشند، یا زمانی که این مجموعه به سرعت در حال تغییر است. بدیهی است که با مجموعه متغیر کلیدها بهتر است داشته باشید درخت متعادل.

تعریف: اگر ارتفاع زیردرخت سمت چپ هر گره با ارتفاع زیردرخت سمت راست حداکثر 1 تفاوت داشته باشد، درخت دودویی متعادل نامیده می شود.

هنگام جستجوی داده در حافظه خارجی، کاهش تعداد انتقال داده ها از حافظه خارجی به حافظه اصلی بسیار مهم است. بنابراین، در این صورت، در مقایسه با درختان دوتایی، درختان با شاخه های قوی سود بیشتری خواهند داشت. ارتفاع آنها کمتر است، سپس جستجو به تماس های کمتری با حافظه خارجی نیاز دارد. در این مورد، درختان B (B - متعادل)

تعریف: درخت B از مرتبه n یک درخت به شدت منشعب با درجه 2n + 1 با ویژگی های زیر است:

  1. هر گره، به جز ریشه، دارای حداقل n و حداکثر 2n کلید است.
  2. ریشه شامل حداقل یک و حداکثر 2n کلید است.
  3. همه برگها در یک سطح قرار دارند.
  4. هر گره میانی شامل دو لیست است: یک لیست صعودی از کلیدها و یک لیست مربوطه از اشاره گرها (لیستی از اشاره گرها برای گره های برگ وجود ندارد).

برای چنین درختی:

· دسترسی متوالی را می توان نسبتاً آسان سازماندهی کرد، زیرا همه برگها در یک سطح هستند.

· هنگام افزودن و تغییر کلیدها، همه تغییرات معمولاً به یک گره محدود می شود.

برنج. 1.3 درخت متعادل

Vدرختی که مقادیر واقعی آن فقط در برگها (گره های برگ) وجود دارد نامیده می شود V +- درخت... گره های داخلی چنین درختی حاوی کلیدهای جداکننده هستند که محدوده تغییرات کلید را برای زیردرخت ها مشخص می کنند.

شما می توانید در مورد انواع درختان متعادل و همچنین روش های اجرای آنها در ادبیات اطلاعات بیشتر بخوانید که لیستی از آنها در انتهای صفحه آورده شده است. لازم به ذکر است که ب- درختان فقط برای سازماندهی دسترسی به ساختارهای داده نسبتاً ساده (یک بعدی) مناسب هستند. برای دسترسی به ساختارهای پیچیده تر، مانند، به عنوان مثال، داده های فضایی (چند بعدی)، در سال های اخیر، آنها به طور فزاینده ای استفاده می کنند. آر-درختان.

آر-درخت ( آر-Tree) یک ساختار شاخص برای دسترسی به داده های مکانی است که توسط A. Guttman (دانشگاه کالیفرنیا، برکلی) پیشنهاد شده است. R-tree امکان اجرای دلخواه عملیات افزودن، حذف و جستجوی داده ها را بدون فهرست بندی مجدد دوره ای می دهد.

برای نمایش داده ها از رکوردهایی استفاده می شود که هر کدام دارای یک شناسه منحصر به فرد (Tuple-identifier) ​​هستند. هر گره برگ (برگ) درخت حاوی یک رکورد از شکل ( I، تاپل-شناسه)، جایی که من - n-جعبه بعدی حاوی نشانگرهای داده های مکانی (که مستطیل محدود حداقلی MBR نیز نامیده می شود) و هر عنصر در شناسه چندگانهشامل مرزهای بالایی و پایینی جعبه در ابعاد مربوطه است.

گره های غیر پایانی حاوی رکوردهایی از فرم هستند (I, نشانگر کودک)، جایی که منحداقل کادر محدود برای MBR تمام گره های مشتق شده از این یکی. Childnode-pointerیک اشاره گر به گره های مشتق شده است.

اجازه دهید مو متر <= M/2 به ترتیب، حداکثر و حداقل تعداد عناصری که می توان در یک گره قرار داد. سپس خواص درخت R را می توان به صورت زیر توصیف کرد:

· R-Tree یک درخت بسیار متعادل است، یعنی. همه برگها در یک سطح هستند.

· گره ریشه حداقل دو فرزند دارد.

· برای هر عنصر (I, نشانگر کودک)در گره غیر پایانی منهست یک کوچکترین ممکنیک متوازی الاضلاع، یعنی. شامل تمام متوازی الاضلاع گره های مشتق شده است.

· هر گره انتهایی (ورق) شامل از مترقبل از مرکوردهای شاخص

· برای هر ورودی شاخص (I, شناسه چندگانه)در گره انتهایی منمتوازی الاضلاع است که شامل nشی داده های بعدی به آن اشاره کرد شناسه چندگانه .

هش کردن 1.2.2

این روش زمانی مورد استفاده قرار می گیرد که کل مجموعه کلیدها از قبل شناخته شده باشد و بتوان برای مدت زمان پردازش در RAM قرار گرفت. در این مورد، یک تابع ویژه ساخته شده است که به طور منحصر به فرد مجموعه ای از کلیدها را به مجموعه ای از نشانگرها، به نام تابع هش (از کلمه انگلیسی "to hash" - cut, grind) نگاشت می کند. با داشتن چنین تابعی می توان آدرس رکورد موجود در فایل را با توجه به کلید جستجوی داده شده محاسبه کرد. به طور کلی، داده های کلیدی مورد استفاده برای تعیین آدرس یک رکورد در جدولی به نام جدول هش سازماندهی می شوند.

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

مفهوم ساختار داده به قدری اساسی است که ارائه یک تعریف ساده برای آن دشوار است. اگر بخواهید این مفهوم را در رابطه با انواع داده ها و متغیرها فرموله کنید، کار ساده می شود. همانطور که می دانید، یک برنامه وحدتی از یک الگوریتم (رویه ها، توابع) و داده های پردازش شده توسط آنها است. داده ها به نوبه خود با انواع داده های پایه و مشتق شده تعریف می شوند - نمایش های "ایده آل" متغیرهای ابعاد ثابت با مجموعه ای از عملیات های شناخته شده روی آنها و اجزای آنها. متغیرها مناطقی از حافظه نامگذاری می شوند که انواع داده های ساخته شده در آنها "نقشه برداری" می شوند.
در یک برنامه، همیشه می‌توانید گروه‌هایی از متغیرهای مرتبط غیرمستقیم (با استفاده از داده‌ها در همان رویه‌ها و توابع) و مرتبط مستقیم (با وجود روابط از طریق اشاره‌گر) را تشخیص دهید. به عنوان اولین تقریب، می توان آنها را ساختار داده در نظر گرفت.

بین ساختارهای داده SIMPLE (اساسی، اولیه) (انواع) و INTEGRATED (ساختار یافته، مرکب، پیچیده) تمایز قائل شوید. ساختارهای داده ساده آنهایی هستند که نمی توانند به اجزای بزرگتر از بیت ها تجزیه شوند. از نقطه نظر ساختار فیزیکی، مهم است که در یک معماری ماشین معین، در یک سیستم برنامه نویسی معین، همیشه بتوانیم از قبل بگوییم اندازه یک نوع ساده معین چقدر خواهد بود و ساختار قرارگیری آن در آن چگونه است. حافظه از نقطه نظر منطقی، داده های ساده واحدهای تقسیم ناپذیر هستند. ساختارهای داده یکپارچه آنهایی هستند که اجزای تشکیل دهنده آنها ساختارهای داده دیگری هستند - ساده یا به نوبه خود یکپارچه. ساختارهای داده یکپارچه توسط برنامه نویس با استفاده از ابزارهای یکپارچه سازی داده ارائه شده توسط زبان های برنامه نویسی ساخته می شوند.

بسته به عدم وجود یا وجود روابط مشخص شده بین عناصر داده، باید بین ساختارهای UNCONNECTED (بردارها، آرایه ها، رشته ها، پشته ها، صف ها) و ساختارهای متصل (لیست های پیوندی) تمایز قائل شد.

یک ویژگی بسیار مهم ساختار داده، تغییرپذیری آن است - تغییر در تعداد عناصر و (یا) اتصالات بین عناصر ساختار. تعریف تغییرپذیری ساختار نشان دهنده این واقعیت نیست که مقادیر عناصر داده تغییر کرده است، زیرا در این مورد تمام ساختارهای داده دارای ویژگی تغییرپذیری خواهند بود. بر اساس تنوع، سازه ها متمایز می شوند: STATIC، SEMI-STATIC، DYNAMIC. طبقه بندی ساختارهای داده بر اساس تنوع در شکل 1 نشان داده شده است. 1.1. ساختارهای داده پایه، ایستا، نیمه استاتیک و پویا، مختص RAM هستند و اغلب به عنوان ساختارهای آنلاین نامیده می شوند. ساختار فایل مربوط به ساختار داده برای حافظه خارجی است.



برنج. 1.1. طبقه بندی ساختارهای داده

یکی از ویژگی های مهم ساختار داده، ماهیت ترتیب عناصر آن است. بر این اساس سازه ها را می توان به دو دسته LINEAR و NON-LINEAR تقسیم کرد.

بسته به ماهیت آرایش متقابل عناصر در حافظه، ساختارهای خطی را می‌توان به ساختارهایی با توزیع متوالی عناصر در حافظه (بردارها، رشته‌ها، آرایه‌ها، پشته‌ها، صف‌ها) و ساختارهایی با توزیع ARBITRARY CONNECTED عناصر در حافظه تقسیم کرد. (فهرست های پیوندی، دوتایی). نمونه ای از ساختارهای غیرخطی لیست های چند پیوندی، درختان، نمودارها است.

در زبان های برنامه نویسی، مفهوم «ساختارهای داده» ارتباط نزدیکی با مفهوم «انواع داده» دارد. هر گونه داده، به عنوان مثال ثابت ها، متغیرها، مقادیر تابع یا عبارات با انواع آنها مشخص می شوند.

اطلاعات برای هر نوع به طور منحصر به فرد شناسایی می کند:

1) یک ساختار ذخیره سازی داده از نوع مشخص شده، به عنوان مثال. تخصیص حافظه و نمایش داده در آن، از یک سو، و تفسیر نمایش باینری، از سوی دیگر.

· 2) مجموعه مقادیر قابل قبولی که یک یا شیء دیگر از نوع توصیف شده می تواند داشته باشد.

· 3) مجموعه ای از عملیات معتبر که برای یک شی از نوع توصیف شده قابل اعمال است.

ساختار داده - مجموعه ای از متغیرهای مرتبط فیزیکی (انواع داده) و منطقی (الگوریتم، توابع) و مقادیر آنها.

توجه داشته باشید که مفهوم ساختار داده نه تنها به متغیرهایی که آن را تشکیل می‌دهند، بلکه به الگوریتم‌هایی (توابع) اشاره دارد که نه تنها متغیرها را به‌طور منطقی به یکدیگر پیوند می‌دهند، بلکه مقادیر داخلی را نیز تعریف می‌کنند که باید ذاتی آن نیز باشد. ساختار داده ها. به عنوان مثال، دنباله ای از مقادیر مثبت که در یک آرایه قرار دارند و دارای یک بعد متغیر (ساختار داده) هستند ممکن است یک پایان دهنده تهی داشته باشند. تمام عملیات برای تشکیل و تأیید این محدود کننده توسط توابع اجرا می شود. بنابراین، می توان گفت که بخش قابل توجهی از ساختار داده ها در الگوریتم های پردازش آن "هاردکد" شده است.
روش شناخته شده تعریف متغیرها از طریق انواع داده با این واقعیت مشخص می شود که اولاً تعداد متغیرها در برنامه ثابت است و ثانیاً نمی توان ابعاد آنها را در حین اجرای برنامه تغییر داد. اگر روابط بین این متغیرها کم و بیش دائمی باشد، آنگاه چنین ساختارهای داده ای را می توان استاتیک نامید.

ساختار داده ایستا - مجموعه ای از تعداد ثابتی از متغیرها با ابعاد ثابت با ماهیت بدون تغییر روابط بین آنها
و بالعکس، اگر یکی از پارامترهای یک ساختار داده، تعداد متغیرها باشد، ابعاد آنها یا رابطه بین آنها در طول اجرای برنامه تغییر کند، به چنین ساختارهای داده ای پویا می گویند.

ساختار داده پویا - مجموعه ای از متغیرها، تعداد، ابعاد یا ماهیت رابطه بین آنها در طول اجرای برنامه ها تغییر می کند.

ساختارهای داده پویا بر اساس دو عنصر از زبان برنامه نویسی است:

· متغیرهای پویا که تعداد آنها می تواند تغییر کند و در نهایت توسط خود برنامه تعیین می شود. علاوه بر این، توانایی ایجاد آرایه های پویا به شما امکان می دهد در مورد داده هایی با ابعاد متغیر صحبت کنید.

· اشاره گرها، که ارتباط مستقیم داده ها و توانایی تغییر این روابط را فراهم می کنند.

بنابراین، این تعریف به حقیقت نزدیک است: ساختارهای داده پویا، متغیرها و آرایه های پویا هستند که توسط اشاره گر به هم مرتبط شده اند.
در مورد ساختار داده ها، نباید فراموش کنیم که متغیرهای معمولی در RAM (حافظه داخلی رایانه) قرار دارند. بنابراین، ساختارهای داده معمولاً با حافظه ارتباط دارند. با این حال، حافظه خارجی نیز وجود دارد که در زبان به طور غیر مستقیم از طریق عملگرها (Pascal) یا توابع (C) که با فایل ها کار می کنند در دسترس است. در حالت فایل دسترسی تصادفی باینری، هر فایلی آنالوگ یک ناحیه حافظه نامحدود با آدرس دهی مستقیم است، یعنی از نظر برنامه، دقیقاً مانند حافظه معمولی به نظر می رسد. به طور طبیعی، برنامه می تواند متغیرها را از حافظه به یک مکان دلخواه در فایل و بالعکس کپی کند و بنابراین هر گونه ساختار داده (از جمله پویا) را در فایل سازماندهی کند.
ساختار داده، مجری است که کار را با داده ها سازماندهی می کند، از جمله ذخیره، افزودن و حذف، اصلاح، جستجو و غیره. ساختار داده ها نظم خاصی از دسترسی به آنها را حفظ می کند. ساختار داده را می توان نوعی انبار یا کتابخانه در نظر گرفت. هنگام توصیف یک ساختار داده، باید مجموعه اقداماتی را که برای آن امکان پذیر است فهرست کنید و نتیجه هر عمل را به وضوح توصیف کنید. ما چنین اقداماتی را نسخه می نامیم. از دیدگاه برنامه نویسی، یک سیستم تجویزی ساختار داده مربوط به مجموعه ای از توابع است که بر روی متغیرهای مشترک کار می کنند.
ساختارهای داده به راحتی در زبان های شی گرا پیاده سازی می شوند. در آنها، کلاس با ساختار داده مطابقت دارد، خود داده ها در متغیرهای عضو کلاس ذخیره می شوند (یا داده ها از طریق متغیرهای عضو قابل دسترسی هستند) و مجموعه روش های کلاس مربوط به سیستم تجویزی است. به عنوان یک قاعده، در زبان های شی گرا، ساختارهای داده به عنوان یک کتابخانه از کلاس های استاندارد پیاده سازی می شوند: این ها به اصطلاح کلاس های کانتینری زبان C ++ هستند که در کتابخانه کلاس استاندارد STL گنجانده شده اند، یا کلاس هایی که انواع مختلفی را پیاده سازی می کنند. ساختارهای داده از کتابخانه Java Developer Kit زبان جاوا.
با این حال، ساختارهای داده را می توان به همان اندازه با موفقیت در زبان های برنامه نویسی سنتی مانند Fortran یا C پیاده سازی کرد. در این مورد، باید به سبک برنامه نویسی شی گرا پایبند بود: مجموعه توابعی که با ساختار داده کار می کنند را به وضوح شناسایی کنید و دسترسی به داده ها را فقط با این مجموعه از توابع محدود کنید. خود داده ها به عنوان متغیرهای ثابت (نه سراسری) پیاده سازی می شوند. هنگام برنامه نویسی به زبان C، ساختار داده با دو فایل منبع مطابقت دارد:
1.header یا h-file که رابط ساختار داده را توصیف می کند. مجموعه ای از نمونه های اولیه تابع مربوط به سیستم تجویزی ساختار داده.
فایل پیاده‌سازی یا C-file که متغیرهای ثابتی را تعریف می‌کند که داده‌ها را ذخیره می‌کنند و به داده‌ها دسترسی دارند، و همچنین توابعی را پیاده‌سازی می‌کند که با سیستم نسخه‌های ساختار داده مطابقت دارد.
ساختار داده معمولاً بر اساس یک ساختار ساده‌تر ساده‌تر که قبلاً پیاده‌سازی شده است، یا بر اساس یک آرایه و مجموعه‌ای از متغیرهای ساده پیاده‌سازی می‌شود. لازم است به وضوح بین شرح ساختار داده از نقطه نظر منطقی و شرح اجرای آن تمایز قائل شد. پیاده سازی های مختلفی می تواند وجود داشته باشد، اما از نقطه نظر منطقی (یعنی از دیدگاه یک کاربر خارجی) همه آنها معادل هستند و شاید فقط در سرعت اجرای نسخه ها متفاوت باشند.

آزمون علوم کامپیوتر

اطلاعات به عنوان یک منبع روشهای ذخیره و پردازش اطلاعات

اطلاعات از لات. «اطلاعات» به معنای شفاف سازی، اطلاعات، ارائه است.

به معنای وسیع اطلاعات -این یک مفهوم علمی کلی است که شامل تبادل اطلاعات بین افراد، تبادل سیگنال بین طبیعت جاندار و بی جان، افراد و وسایل است.
اطلاعات -اطلاعاتی در مورد اشیاء و پدیده های محیطی، پارامترها، ویژگی ها و شرایط آنهاست که میزان عدم قطعیت موجود در مورد آنها، ناقص بودن دانش را کاهش می دهد.

علوم کامپیوتر اطلاعات را در نظر می گیردبه عنوان اطلاعات، داده ها، مفاهیم مفهومی مرتبط که ایده های ما را در مورد پدیده یا شیء دنیای اطراف تغییر می دهند.

منابع اطلاعاتی -اینها اسناد جداگانه و آرایه های جداگانه اسناد، اسناد و آرایه های اسناد در سیستم های اطلاعاتی (کتابخانه ها، بایگانی ها، صندوق ها، بانک ها) هستند.
برای اینکه اطلاعات مورد استفاده قرار گیرد، علاوه بر این، بارها باید ذخیره شود.

ذخیره سازی داده ها -روشی برای انتشار اطلاعات در مکان و زمان است. نحوه ذخیره اطلاعات به رسانه آن بستگی دارد (کتاب کتابخانه است، عکس موزه است، عکس آلبوم است). کامپیوتر برای ذخیره سازی فشرده اطلاعات با قابلیت دسترسی سریع به آن طراحی شده است.
پردازش داده هاتبدیل اطلاعات از نوعی به نوع دیگر است.
پردازش اطلاعات - فرآیند انتقال از داده های اولیه به نتیجه، فرآیند پردازش است. شی یا موضوعی که پردازش را انجام می دهد، مجری پردازش است.
نوع اول پردازش:پردازش مرتبط با به دست آوردن اطلاعات جدید، محتوای جدید دانش.
نوع دوم پردازش:پردازش مرتبط با تغییر فرم، اما عدم تغییر محتوا (به عنوان مثال،
ترجمه متن از زبانی به زبان دیگر).

یک نوع پردازش مهم است کد نویسی- تبدیل اطلاعات به شکل نمادین،
مناسب برای ذخیره سازی، انتقال، پردازش آن. نوع دیگری از پردازش اطلاعات، ساختاردهی داده ها است (اعمال نظم خاصی در ذخیره سازی اطلاعات، طبقه بندی، فهرست نویسی داده ها).
نوع دیگری از پردازش اطلاعات، جستجو در یک ذخیره سازی اطلاعات خاص برای داده های ضروری است که شرایط جستجوی خاصی را برآورده می کند (پرس و جو).



مفهوم داده های ساخت یافته تعریف و هدف پایگاه داده

هنگام ایجاد پایگاه داده، کاربر به دنبال سازماندهی اطلاعات بر اساس ویژگی های مختلف و بازیابی سریع نمونه با ترکیب دلخواه از ویژگی ها است. این تنها در صورتی امکان پذیر است که داده ها ساختاری داشته باشند.

ساختار -این معرفی قراردادهایی در مورد نحوه ارائه داده ها است.

داده های ساخت یافته -داده های سفارش داده شده است.

داده های بدون ساختار -اینها داده هایی هستند که به عنوان مثال در یک فایل متنی ثبت شده اند: پرونده شخصی شماره 1 اولگ ایوانوویچ سیدوروف، تاریخ تولد. 92/11/14، پرونده شخصی شماره 2 پترووا آنا ویکتورونا، تاریخ تولد. 91/03/15.

برای خودکارسازی جستجو و سازماندهی این داده ها، لازم است توافقات خاصی در مورد نحوه ارائه داده ها ایجاد شود، به عنوان مثال. تاریخ تولد باید برای هر دانش آموز یکسان ثبت شود، باید طول و تعریف یکسانی داشته باشد. در میان بقیه اطلاعات قرار دهید. همین نکات در مورد بقیه داده ها نیز صادق است (شماره پرونده شخصی، F.، I.، O.) پس از یک ساختاربندی ساده با اطلاعات، به صورت زیر خواهد بود:

نمونه ای از داده های ساخت یافته:شماره نام کامل تاریخ تولد.

1 سیدوروف اولگ ایوانوویچ 92/11/14

عناصر داده های ساخت یافته:

1) الف - فیلد (ستون) یک واحد غیر قابل تقسیم ابتدایی سازمان اطلاعات است

2) ب - رکورد (خط) مجموعه ای از فیلدهای منطقی مرتبط است

3) ب - جدول (فایل) مجموعه ای از نمونه های رکوردهای یک ساختار است.

پایگاه داده -مجموعه ای از داده های ساختار یافته به هم پیوسته است که بر روی یک رسانه ماشینی سازماندهی شده و حاوی اطلاعاتی در مورد موجودیت های مختلف یک حوزه موضوعی خاص (اشیاء، فرآیندها، رویدادها، پدیده ها) است.

در معنای وسیع کلمه، پایگاه داده مجموعه ای از اطلاعات در مورد اشیاء خاص دنیای واقعی در هر حوزه موضوعی است.

زیر حوزه موضوعیبخشی از دنیای واقعی برای سازماندهی مدیریت، اتوماسیون، به عنوان مثال، یک شرکت، یک دانشگاه و غیره قابل مطالعه است.

هدف پایگاه داده:

1) کنترل بر افزونگی داده ها. همانطور که قبلاً بحث شد، سیستم های فایل سنتی حافظه خارجی را با ذخیره داده های مشابه در چندین فایل هدر می دهند. در مقابل، یک پایگاه داده تلاش می‌کند تا با یکپارچه‌سازی فایل‌ها، افزونگی داده‌ها را حذف کند تا از ذخیره کپی‌های متعدد از یک قطعه اطلاعات جلوگیری کند.

2) سازگاری داده ها. حذف یا کنترل افزونگی داده ها می تواند به کاهش خطر وضعیت های ناسازگار کمک کند. اگر یک آیتم داده تنها در یک نمونه در پایگاه داده ذخیره شود، برای تغییر مقدار آن، تنها باید یک عملیات به روز رسانی انجام دهید و مقدار جدید به طور همزمان در دسترس همه کاربران پایگاه داده قرار می گیرد. و اگر این عنصر داده با آگاهی از سیستم در چندین نسخه در پایگاه داده ذخیره شود، چنین سیستمی قادر خواهد بود از عدم مغایرت نسخه ها با یکدیگر اطمینان حاصل کند.

3) به اشتراک گذاری داده ها فایل ها معمولاً متعلق به افراد یا کل بخش هایی هستند که از آنها در کار خود استفاده می کنند. در عین حال، پایگاه داده متعلق به کل سازمان به عنوان یک کل است و می تواند توسط همه کاربران ثبت نام شده به اشتراک گذاشته شود. با این سازماندهی کار، تعداد بیشتری از کاربران می توانند با حجم زیادی از داده ها کار کنند. علاوه بر این، در این حالت، می توانید برنامه های جدید را بر اساس اطلاعات موجود در پایگاه داده ایجاد کنید و تنها داده هایی را که در حال حاضر در آن ذخیره نشده اند را به آن اضافه کنید و الزامات همه داده های مورد نیاز برنامه جدید را دوباره تعریف نکنید.

4) یکپارچگی داده ها را حفظ کنید. یکپارچگی پایگاه داده به معنای صحت و سازگاری داده های ذخیره شده در آن است. یکپارچگی معمولاً بر حسب محدودیت ها توصیف می شود، به عنوان مثال. قوانینی برای حفظ ثبات، که نباید در پایگاه داده نقض شوند. محدودیت ها را می توان برای اقلام داده در یک رکورد واحد یا برای روابط بین رکوردها اعمال کرد. به عنوان مثال، یک محدودیت یکپارچگی ممکن است بیان کند که حقوق یک کارمند نباید از 40000 روبل در سال تجاوز کند، یا اینکه در یک رکورد حاوی اطلاعات مربوط به یک کارمند، تعداد بخشی که در آن کار می کند باید با بخش واقعی شرکت مطابقت داشته باشد. .

5) افزایش امنیت امنیت پایگاه داده در مورد محافظت از پایگاه داده در برابر دسترسی غیرمجاز توسط کاربران است. بدون اقدامات امنیتی مناسب، داده های یکپارچه آسیب پذیرتر از داده های موجود در سیستم فایل می شوند. با این حال، یکپارچه سازی به شما امکان می دهد سیستم امنیتی پایگاه داده مورد نیاز را تعریف کنید و DBMS آن را به مرحله اجرا درآورد. سیستم امنیتی را می توان در قالب اعتبار و رمز عبور برای شناسایی کاربرانی که در این پایگاه داده ثبت نام کرده اند بیان کرد. دسترسی به داده ها توسط یک کاربر ثبت نام شده می تواند تنها به عملیات خاصی محدود شود (استخراج، درج، به روز رسانی و حذف).

  • ترجمه

البته، شما می توانید بدون دانش مقدس از ساختارهای داده یک برنامه نویس موفق باشید، اما آنها در برخی از برنامه ها کاملا غیر قابل جایگزین هستند. برای مثال، زمانی که باید کوتاه‌ترین مسیر را بین دو نقطه روی نقشه محاسبه کنید، یا نامی را در دفترچه تلفنی که مثلاً حاوی یک میلیون ورودی است، بیابید. ناگفته نماند که ساختارهای داده به طور مداوم در برنامه نویسی ورزشی استفاده می شود. بیایید برخی از آنها را با جزئیات بیشتر در نظر بگیریم.

صف

پس به لوپی سلام کنید!

لوپی عاشق بازی هاکی با خانواده اش است. و منظور من از "بازی" است:

وقتی لاک پشت ها به سمت دروازه پرواز می کنند، به بالای شمع پرتاب می شوند. توجه داشته باشید که اولین لاک پشت اضافه شده به پشته اولین لاک پشتی است که ترک می کند. نامیده می شود صف... درست مانند آن صف هایی که در زندگی روزمره می بینیم، اولین موردی که به لیست اضافه می شود اولین موردی است که آن را ترک می کند. این ساختار نیز نامیده می شود FIFO(اولین ورودی اولین خروجی).

در مورد عملیات درج و حذف چطور؟

Q = def insert (elem): q.append (elem) # اضافه کردن یک آیتم به انتهای صف چاپ q def delete (): q.pop (0) # حذف آیتم صفر از صف چاپ q

پشته

پس از چنین بازی سرگرم کننده هاکی، لوپی برای همه پنکیک درست می کند. او آنها را در یک توده قرار می دهد.

وقتی همه پنکیک ها آماده شدند، لوپی آن ها را یکی یکی برای تمام خانواده سرو می کند.

توجه داشته باشید که اولین پن کیکی که او درست می کند در آخر سرو می شود. نامیده می شود پشته... آخرین موردی که به لیست اضافه می شود اولین موردی است که از لیست خارج می شود. همچنین این ساختار داده نامیده می شود LIFO(آخرین در اولین خروجی).

افزودن و حذف موارد؟

S = def push (elem): # افزودن یک آیتم به پشته - Push s.append (elem) print s def customPop (): # حذف یک مورد از پشته - Pop s.pop (len (s) -1) چاپ s

پشته

آیا تا به حال برج تراکم را دیده اید؟

همه عناصر از بالا به پایین با توجه به تراکم در مکان های خود قرار می گیرند. اگر جسم جدیدی را داخل آن بیندازید چه اتفاقی می‌افتد؟

بسته به چگالی آن انجام خواهد شد.

اینجوری کار میکند پشته.

پشته یک درخت دوتایی است. یعنی هر یک از والدین دو فرزند دارند. و اگرچه ما این ساختار داده را یک پشته می نامیم، اما در قالب یک آرایه منظم بیان می شود.
همچنین پشته همیشه logn بالا است، جایی که n تعداد عناصر است

شکل یک max-heap را بر اساس قانون زیر نشان می دهد: کودکان کمتروالدین. همچنین مین هیپ هایی وجود دارد که بچه ها همیشه در آنجا هستند بیشتروالدین.

چند کارکرد ساده برای کار با پشته ها:

Heap global currSize def والد (i): # دریافت شاخص والد عنصر i-امین بازگشت i / 2 def left (i): # دریافت فرزند سمت چپ عنصر i-امین بازگشت 2 * i def right (i ): # دریافت فرزند مناسب با بازگشت i-ام (2 * i + 1)

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

الگوریتم:

  1. مورد را به انتهای پشته اضافه کنید.
  2. عنصر اضافه شده را با والد مقایسه کنید. اگر دستور درست باشد، متوقف می‌شویم.
  3. اگر نه، عناصر را عوض می کنیم و به نقطه قبلی باز می گردیم.
کد:

دف swap (a, b): # تعویض عنصر با شاخص a به عنصر با شاخص b temp = heap [a] heap [a] = heap [b] heap [b] = temp def insert (elem): global currSize index = len (heap) heap.append (elem) currSize + = 1 par = parent (index) flag = 0 while flag! = 1: if index == 1: # به عنصر ریشه رسید flag = 1 elif heap> elem: # اگر شاخص عنصر ریشه بزرگتر از شاخص عنصر ما باشد - عنصر ما در جای خود است پرچم = 1 دیگری: # عنصر والد را با شاخص مبادله (par, index) ما تعویض کنید = par par = چاپ والد (شاخص) پشته
حداکثر تعداد پاس های حلقه while برابر با ارتفاع درخت یا logn است، بنابراین پیچیدگی الگوریتم O (logn) است.

بازیابی عنصر حداکثر هیپ
اولین عنصر در پشته همیشه حداکثر است، بنابراین ما فقط آن را حذف می کنیم (از قبل آن را به خاطر بسپاریم) و آن را با کمترین عنصر جایگزین می کنیم. سپس با استفاده از یک تابع، پشته را به ترتیب صحیح قرار می دهیم:

MaxHeapify ().

الگوریتم:

  1. عنصر ریشه را با کمترین عنصر جایگزین کنید.
  2. عنصر ریشه جدید را با کودکان مقایسه کنید. اگر ترتیب درستی دارند، متوقف شوید.
  3. اگر نه، عنصر ریشه را با یکی از فرزندان جایگزین کنید (کوچکتر برای min-heap، بزرگتر برای max-heap)، و مرحله 2 را تکرار کنید.

Def extractMax (): currSize جهانی اگر currSize! = 0: maxElem = heap heap = heap # عنصر ریشه را با جدیدترین heap.pop (currSize) جایگزین کنید # آخرین عنصر را حذف کنید currSize - = 1 # اندازه پشته را کاهش دهید maxHeapify ( 1) return maxElem def maxHeapify (index): global currSize lar = index l = left (index) r = right (index) # محاسبه کنید کدام فرزند بزرگتر است. اگر بزرگتر از والد است، اگر l را عوض کنید<= currSize and heap[l] >heap: lar = l اگر r<= currSize and heap[r] >heap: lar = r if lar! = index: swap (index, lar) maxHeapify (lar)
و باز هم حداکثر تعداد فراخوانی تابع maxHeapify برابر با ارتفاع درخت یا logn است که به این معنی است که پیچیدگی الگوریتم O (logn) است.

ساخت یک دسته از هر آرایه تصادفی
خوب، دو راه برای انجام این کار وجود دارد. اولین مورد این است که هر عنصر را یکی یکی در پشته قرار دهید. این ساده است، اما کاملا بی اثر است. پیچیدگی الگوریتم در این مورد O (nlogn) خواهد بود، زیرا تابع O (logn) n بار اجرا خواهد شد.

یک راه کارآمدتر استفاده از تابع maxHeapify برای " توده های فرعی'، از (currSize / 2) تا عنصر اول.

پیچیدگی O (n) خواهد بود و متأسفانه اثبات این گفته خارج از حوصله این مقاله است. فقط درک کنید که موارد موجود در قسمت currSize / 2 تا currSize هیپ فاقد فرزند هستند و بیشتر «هیپ‌های فرعی» که به این ترتیب شکل می‌گیرند کمتر از logn ارتفاع خواهند داشت.

Def buildHeap (): currSize جهانی برای i در محدوده (currSize / 2, 0, -1): # آرگومان سوم در محدوده () مرحله تکرار است، در این مورد جهت را تعیین می کند. print heap maxHeapify (i) currSize = len (heap) -1

راستی این همه چرا؟

برای اجرای نوع خاصی از مرتب‌سازی به هپ‌هایی نیاز است که به‌طور عجیبی به نام « دسته بندی". بر خلاف «مرتب‌سازی درج» و «مرتب‌سازی حبابی» کمتر کارآمد، با پیچیدگی وحشتناک O (n 2)، «مرتب‌سازی پشته» دارای پیچیدگی O (nlogn) است.

پیاده سازی بسیار ساده است. فقط به طور متوالی حداکثر عنصر (ریشه) را از پشته واکشی کنید و آن را در آرایه بنویسید تا زمانی که پشته خالی شود.

Def heapSort (): برای i در محدوده (1, len (heap)): print heap heap.insert (len (heap) -i, extractMax ()) # حداکثر عنصر را در انتهای آرایه وارد کنید currSize = len ( پشته) -1
برای خلاصه کردن همه موارد بالا، من چند خط کد حاوی توابع برای کار با هیپ نوشتم و برای طرفداران OOP همه چیز را در قالب یک کلاس طراحی کردم.

آسان است، اینطور نیست؟ و اینجاست که لوپی را جشن می گیرد!

هش

لوپی می خواهد به بچه هایش یاد بدهد که اشکال و رنگ ها را تشخیص دهند. برای انجام این کار، او تعداد زیادی از چهره های چند رنگ را به خانه آورد.

بعد از مدتی بالاخره لاک پشت ها گیج شدند.

بنابراین او یک اسباب‌بازی دیگر بیرون آورد تا کار را کمی آسان‌تر کند.

خیلی ساده تر شد، زیرا لاک پشت ها از قبل می دانستند که اشکال بر اساس شکل مرتب شده اند. اگر هر پست را علامت گذاری کنیم چه؟

اکنون لاک‌پشت‌ها باید ستونی را با یک عدد مشخص بررسی کنند و از تعداد بسیار کمتری از ارقام مورد نیاز خود را انتخاب کنند. و اگر برای هر ترکیب شکل و رنگ یک ستون جداگانه هم داشته باشیم؟

فرض کنید شماره پست به صورت زیر محاسبه می شود:

نام و نام خانوادگیتابستان سهمربع
ph + u + o + t + p + e = 22 + 10 + 16 + 20 + 18 + 6 = ستون 92

کراخواب آلود سر راستمستطیل
k + p + a + n + p + i = 12 + 18 + 1 + 17 + 18 + 33 = ستون 99

ما می دانیم که 6 * 33 = 198 ترکیب ممکن است، به این معنی که ما به 198 ستون نیاز داریم.

بیایید این فرمول را برای محاسبه شماره ستون صدا کنیم - تابع هش.

کد:
def hashFunc (piece): words = piece.split ("") # رشته را به کلمات تقسیم کنید color = شکل کلمات = کلمات poleNum = 0 برای i در محدوده (0، 3): poleNum + = ord (رنگ [i]) - 96 poleNum + = ord (شکل [i]) - 96 برگشت poleNum
(سیریلیک کمی پیچیده تر است، اما من برای سادگی آن را به این صورت رها کردم. - تقریبا)

حالا اگر بخواهیم بفهمیم مربع صورتی کجا ذخیره شده است، می توانیم محاسبه کنیم:
hashFunc ("مربع صورتی")

این نمونه ای از جدول هش است که در آن مکان عناصر توسط یک تابع هش تعیین می شود.
با این رویکرد، زمان صرف شده برای جستجوی هر عنصر به تعداد عناصر بستگی ندارد، یعنی. O (1). به عبارت دیگر، زمان جستجو در جدول هش یک مقدار ثابت است.

خوب، اما بیایید بگوییم که ما به دنبال " ماشینراحت سر راست moangle "(البته اگر رنگ" کارامل "وجود داشته باشد).

HashFunc ("مستطیل کاراملی")
به ما 99 برمی‌گرداند که همان عدد مستطیل قرمز است. نام دارد " برخورد". برای رفع تصادم، از « روش زنجیر زنی” به این معنی که هر ستون حاوی لیستی است که در آن رکورد مورد نیاز خود را جستجو می کنیم.

بنابراین ما فقط مستطیل کاراملی را روی یک مستطیل قرمز قرار می دهیم و زمانی که تابع هش به آن ستون اشاره می کند یکی از آنها را انتخاب می کنیم.

کلید یک جدول هش خوب، انتخاب تابع هش مناسب است. این بدون شک مهمترین چیز در ایجاد جدول هش است و افراد زمان زیادی را صرف توسعه عملکردهای هش با کیفیت می کنند.
در جداول خوب، هیچ موقعیتی حاوی بیش از 2-3 عنصر نیست، در غیر این صورت، هش کردن ضعیف عمل می کند و باید تابع هش را تغییر دهید.

یک بار دیگر، جستجوی مستقل از آیتم! ما می توانیم از جداول هش برای هر چیزی که غول پیکر است استفاده کنیم.

جداول هش همچنین برای یافتن رشته ها و زیر رشته ها در تکه های بزرگ متن با استفاده از الگوریتم استفاده می شود. رابین-کارپیا الگوریتم کنات-موریس-پرات، که برای مثال برای شناسایی سرقت ادبی در مقالات علمی مفید است.

در این مورد، من فکر می کنم، ما می توانیم پایان دهیم. برای مثال، در آینده قصد دارم به ساختارهای داده پیچیده تری نگاه کنم پشته فیبوناچیو درخت قطعه... امیدوارم این راهنمای غیررسمی جالب و مفید باشد.

ترجمه شده برای Habr locked on

  • ترجمه

البته، شما می توانید بدون دانش مقدس از ساختارهای داده یک برنامه نویس موفق باشید، اما آنها در برخی از برنامه ها کاملا غیر قابل جایگزین هستند. برای مثال، زمانی که باید کوتاه‌ترین مسیر را بین دو نقطه روی نقشه محاسبه کنید، یا نامی را در دفترچه تلفنی که مثلاً حاوی یک میلیون ورودی است، بیابید. ناگفته نماند که ساختارهای داده به طور مداوم در برنامه نویسی ورزشی استفاده می شود. بیایید برخی از آنها را با جزئیات بیشتر در نظر بگیریم.

صف

پس به لوپی سلام کنید!

لوپی عاشق بازی هاکی با خانواده اش است. و منظور من از "بازی" است:

وقتی لاک پشت ها به سمت دروازه پرواز می کنند، به بالای شمع پرتاب می شوند. توجه داشته باشید که اولین لاک پشت اضافه شده به پشته اولین لاک پشتی است که ترک می کند. نامیده می شود صف... درست مانند آن صف هایی که در زندگی روزمره می بینیم، اولین موردی که به لیست اضافه می شود اولین موردی است که آن را ترک می کند. این ساختار نیز نامیده می شود FIFO(اولین ورودی اولین خروجی).

در مورد عملیات درج و حذف چطور؟

Q = def insert (elem): q.append (elem) # اضافه کردن یک آیتم به انتهای صف چاپ q def delete (): q.pop (0) # حذف آیتم صفر از صف چاپ q

پشته

پس از چنین بازی سرگرم کننده هاکی، لوپی برای همه پنکیک درست می کند. او آنها را در یک توده قرار می دهد.

وقتی همه پنکیک ها آماده شدند، لوپی آن ها را یکی یکی برای تمام خانواده سرو می کند.

توجه داشته باشید که اولین پن کیکی که او درست می کند در آخر سرو می شود. نامیده می شود پشته... آخرین موردی که به لیست اضافه می شود اولین موردی است که از لیست خارج می شود. همچنین این ساختار داده نامیده می شود LIFO(آخرین در اولین خروجی).

افزودن و حذف موارد؟

S = def push (elem): # افزودن یک آیتم به پشته - Push s.append (elem) print s def customPop (): # حذف یک مورد از پشته - Pop s.pop (len (s) -1) چاپ s

پشته

آیا تا به حال برج تراکم را دیده اید؟

همه عناصر از بالا به پایین با توجه به تراکم در مکان های خود قرار می گیرند. اگر جسم جدیدی را داخل آن بیندازید چه اتفاقی می‌افتد؟

بسته به چگالی آن انجام خواهد شد.

اینجوری کار میکند پشته.

پشته یک درخت دوتایی است. یعنی هر یک از والدین دو فرزند دارند. و اگرچه ما این ساختار داده را یک پشته می نامیم، اما در قالب یک آرایه منظم بیان می شود.
همچنین پشته همیشه logn بالا است، جایی که n تعداد عناصر است

شکل یک max-heap را بر اساس قانون زیر نشان می دهد: کودکان کمتروالدین. همچنین مین هیپ هایی وجود دارد که بچه ها همیشه در آنجا هستند بیشتروالدین.

چند کارکرد ساده برای کار با پشته ها:

Heap global currSize def والد (i): # دریافت شاخص والد عنصر i-امین بازگشت i / 2 def left (i): # دریافت فرزند سمت چپ عنصر i-امین بازگشت 2 * i def right (i ): # دریافت فرزند مناسب با بازگشت i-ام (2 * i + 1)

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

الگوریتم:

  1. مورد را به انتهای پشته اضافه کنید.
  2. عنصر اضافه شده را با والد مقایسه کنید. اگر دستور درست باشد، متوقف می‌شویم.
  3. اگر نه، عناصر را عوض می کنیم و به نقطه قبلی باز می گردیم.
کد:

دف swap (a, b): # تعویض عنصر با شاخص a به عنصر با شاخص b temp = heap [a] heap [a] = heap [b] heap [b] = temp def insert (elem): global currSize index = len (heap) heap.append (elem) currSize + = 1 par = parent (index) flag = 0 while flag! = 1: if index == 1: # به عنصر ریشه رسید flag = 1 elif heap> elem: # اگر شاخص عنصر ریشه بزرگتر از شاخص عنصر ما باشد - عنصر ما در جای خود است پرچم = 1 دیگری: # عنصر والد را با شاخص مبادله (par, index) ما تعویض کنید = par par = چاپ والد (شاخص) پشته
حداکثر تعداد پاس های حلقه while برابر با ارتفاع درخت یا logn است، بنابراین پیچیدگی الگوریتم O (logn) است.

بازیابی عنصر حداکثر هیپ
اولین عنصر در پشته همیشه حداکثر است، بنابراین ما فقط آن را حذف می کنیم (از قبل آن را به خاطر بسپاریم) و آن را با کمترین عنصر جایگزین می کنیم. سپس با استفاده از یک تابع، پشته را به ترتیب صحیح قرار می دهیم:

MaxHeapify ().

الگوریتم:

  1. عنصر ریشه را با کمترین عنصر جایگزین کنید.
  2. عنصر ریشه جدید را با کودکان مقایسه کنید. اگر ترتیب درستی دارند، متوقف شوید.
  3. اگر نه، عنصر ریشه را با یکی از فرزندان جایگزین کنید (کوچکتر برای min-heap، بزرگتر برای max-heap)، و مرحله 2 را تکرار کنید.

Def extractMax (): currSize جهانی اگر currSize! = 0: maxElem = heap heap = heap # عنصر ریشه را با جدیدترین heap.pop (currSize) جایگزین کنید # آخرین عنصر را حذف کنید currSize - = 1 # اندازه پشته را کاهش دهید maxHeapify ( 1) return maxElem def maxHeapify (index): global currSize lar = index l = left (index) r = right (index) # محاسبه کنید کدام فرزند بزرگتر است. اگر بزرگتر از والد است، اگر l را عوض کنید<= currSize and heap[l] >heap: lar = l اگر r<= currSize and heap[r] >heap: lar = r if lar! = index: swap (index, lar) maxHeapify (lar)
و باز هم حداکثر تعداد فراخوانی تابع maxHeapify برابر با ارتفاع درخت یا logn است که به این معنی است که پیچیدگی الگوریتم O (logn) است.

ساخت یک دسته از هر آرایه تصادفی
خوب، دو راه برای انجام این کار وجود دارد. اولین مورد این است که هر عنصر را یکی یکی در پشته قرار دهید. این ساده است، اما کاملا بی اثر است. پیچیدگی الگوریتم در این مورد O (nlogn) خواهد بود، زیرا تابع O (logn) n بار اجرا خواهد شد.

یک راه کارآمدتر استفاده از تابع maxHeapify برای " توده های فرعی'، از (currSize / 2) تا عنصر اول.

پیچیدگی O (n) خواهد بود و متأسفانه اثبات این گفته خارج از حوصله این مقاله است. فقط درک کنید که موارد موجود در قسمت currSize / 2 تا currSize هیپ فاقد فرزند هستند و بیشتر «هیپ‌های فرعی» که به این ترتیب شکل می‌گیرند کمتر از logn ارتفاع خواهند داشت.

Def buildHeap (): currSize جهانی برای i در محدوده (currSize / 2, 0, -1): # آرگومان سوم در محدوده () مرحله تکرار است، در این مورد جهت را تعیین می کند. print heap maxHeapify (i) currSize = len (heap) -1

راستی این همه چرا؟

برای اجرای نوع خاصی از مرتب‌سازی به هپ‌هایی نیاز است که به‌طور عجیبی به نام « دسته بندی". بر خلاف «مرتب‌سازی درج» و «مرتب‌سازی حبابی» کمتر کارآمد، با پیچیدگی وحشتناک O (n 2)، «مرتب‌سازی پشته» دارای پیچیدگی O (nlogn) است.

پیاده سازی بسیار ساده است. فقط به طور متوالی حداکثر عنصر (ریشه) را از پشته واکشی کنید و آن را در آرایه بنویسید تا زمانی که پشته خالی شود.

Def heapSort (): برای i در محدوده (1, len (heap)): print heap heap.insert (len (heap) -i, extractMax ()) # حداکثر عنصر را در انتهای آرایه وارد کنید currSize = len ( پشته) -1
برای خلاصه کردن همه موارد بالا، من چند خط کد حاوی توابع برای کار با هیپ نوشتم و برای طرفداران OOP همه چیز را در قالب یک کلاس طراحی کردم.

آسان است، اینطور نیست؟ و اینجاست که لوپی را جشن می گیرد!

هش

لوپی می خواهد به بچه هایش یاد بدهد که اشکال و رنگ ها را تشخیص دهند. برای انجام این کار، او تعداد زیادی از چهره های چند رنگ را به خانه آورد.

بعد از مدتی بالاخره لاک پشت ها گیج شدند.

بنابراین او یک اسباب‌بازی دیگر بیرون آورد تا کار را کمی آسان‌تر کند.

خیلی ساده تر شد، زیرا لاک پشت ها از قبل می دانستند که اشکال بر اساس شکل مرتب شده اند. اگر هر پست را علامت گذاری کنیم چه؟

اکنون لاک‌پشت‌ها باید ستونی را با یک عدد مشخص بررسی کنند و از تعداد بسیار کمتری از ارقام مورد نیاز خود را انتخاب کنند. و اگر برای هر ترکیب شکل و رنگ یک ستون جداگانه هم داشته باشیم؟

فرض کنید شماره پست به صورت زیر محاسبه می شود:

نام و نام خانوادگیتابستان سهمربع
ph + u + o + t + p + e = 22 + 10 + 16 + 20 + 18 + 6 = ستون 92

کراخواب آلود سر راستمستطیل
k + p + a + n + p + i = 12 + 18 + 1 + 17 + 18 + 33 = ستون 99

ما می دانیم که 6 * 33 = 198 ترکیب ممکن است، به این معنی که ما به 198 ستون نیاز داریم.

بیایید این فرمول را برای محاسبه شماره ستون صدا کنیم - تابع هش.

کد:
def hashFunc (piece): words = piece.split ("") # رشته را به کلمات تقسیم کنید color = شکل کلمات = کلمات poleNum = 0 برای i در محدوده (0، 3): poleNum + = ord (رنگ [i]) - 96 poleNum + = ord (شکل [i]) - 96 برگشت poleNum
(سیریلیک کمی پیچیده تر است، اما من برای سادگی آن را به این صورت رها کردم. - تقریبا)

حالا اگر بخواهیم بفهمیم مربع صورتی کجا ذخیره شده است، می توانیم محاسبه کنیم:
hashFunc ("مربع صورتی")

این نمونه ای از جدول هش است که در آن مکان عناصر توسط یک تابع هش تعیین می شود.
با این رویکرد، زمان صرف شده برای جستجوی هر عنصر به تعداد عناصر بستگی ندارد، یعنی. O (1). به عبارت دیگر، زمان جستجو در جدول هش یک مقدار ثابت است.

خوب، اما بیایید بگوییم که ما به دنبال " ماشینراحت سر راست moangle "(البته اگر رنگ" کارامل "وجود داشته باشد).

HashFunc ("مستطیل کاراملی")
به ما 99 برمی‌گرداند که همان عدد مستطیل قرمز است. نام دارد " برخورد". برای رفع تصادم، از « روش زنجیر زنی” به این معنی که هر ستون حاوی لیستی است که در آن رکورد مورد نیاز خود را جستجو می کنیم.

بنابراین ما فقط مستطیل کاراملی را روی یک مستطیل قرمز قرار می دهیم و زمانی که تابع هش به آن ستون اشاره می کند یکی از آنها را انتخاب می کنیم.

کلید یک جدول هش خوب، انتخاب تابع هش مناسب است. این بدون شک مهمترین چیز در ایجاد جدول هش است و افراد زمان زیادی را صرف توسعه عملکردهای هش با کیفیت می کنند.
در جداول خوب، هیچ موقعیتی حاوی بیش از 2-3 عنصر نیست، در غیر این صورت، هش کردن ضعیف عمل می کند و باید تابع هش را تغییر دهید.

یک بار دیگر، جستجوی مستقل از آیتم! ما می توانیم از جداول هش برای هر چیزی که غول پیکر است استفاده کنیم.

جداول هش همچنین برای یافتن رشته ها و زیر رشته ها در تکه های بزرگ متن با استفاده از الگوریتم استفاده می شود. رابین-کارپیا الگوریتم کنات-موریس-پرات، که برای مثال برای شناسایی سرقت ادبی در مقالات علمی مفید است.

در این مورد، من فکر می کنم، ما می توانیم پایان دهیم. برای مثال، در آینده قصد دارم به ساختارهای داده پیچیده تری نگاه کنم پشته فیبوناچیو درخت قطعه... امیدوارم این راهنمای غیررسمی جالب و مفید باشد.

ترجمه شده برای Habr locked on

مقالات مرتبط برتر