{ "cells": [ { "cell_type": "markdown", "id": "2acfa743", "metadata": {}, "source": [ "# 0. Подготовим окружение" ] }, { "cell_type": "code", "execution_count": 8, "id": "4689b73e", "metadata": {}, "outputs": [], "source": [ "import sys\n", "import os\n", "sys.path.insert(0, os.path.abspath( '../task1'))\n", "sys.path.insert(0, os.path.abspath( '../'))" ] }, { "cell_type": "markdown", "id": "37cc11a5", "metadata": {}, "source": [ "# 1. Генерация тестовых данных\n", "\n", "Создадим список records из N=10000 элементов. Каждый элемент — кортеж (name, phone). \n", "Имена возъмём случайные из небольшого набора (чтобы были повторения и коллизии). \n", "Для проверки влияния порядка подготовим два варианта: \n", "\n", "_records_shuffled_ — случайный порядок. \n", "_records_sorted_ — отсортированный по имени (по алфавиту)." ] }, { "cell_type": "code", "execution_count": 9, "id": "a3b5c31b", "metadata": {}, "outputs": [], "source": [ "from util.randomNames import generate_test_data\n", "from util.timeTester import test\n", "\n", "records_shuffled = generate_test_data(N=10000)\n", "records_sorted = generate_test_data(N=10000, _sorted=True)" ] }, { "cell_type": "markdown", "id": "c2f4989c", "metadata": {}, "source": [ "# 2. Проведение замеров" ] }, { "cell_type": "code", "execution_count": 10, "id": "df12d41d", "metadata": {}, "outputs": [], "source": [ "# Подготовим функции СД, которые будем тестировать\n", "from structures.LinkedList import *\n", "from structures.HashTable import *\n", "from structures.BinaryTree import *\n", "\n", "func_list = {\"Связанный список\" : (ll_insert, ll_find, ll_delete),\n", " \"Хэш-таблица\" : (ht_insert, ht_find, ht_delete),\n", " \"Бинарное дерево\" : (bst_insert, bst_find, bst_delete)}" ] }, { "cell_type": "code", "execution_count": 11, "id": "cc8d0436", "metadata": {}, "outputs": [], "source": [ "# Проведём замеры\n", "report = [[\"Структура\", \"Режим\", \"Вставка\", \"Поиск\", \"Удаление\"]]\n", "records = {\"Cлучайный\" : records_shuffled, \"Отсортированный\" : records_sorted}\n", "\n", "TEST_ITERATIONS_NUM = 5\n", "\n", "for _ in range(TEST_ITERATIONS_NUM):\n", " for mode, data in records.items():\n", " for struct_name, fns in func_list.items():\n", " result = test(data, *fns)\n", " row = [struct_name, mode,\n", " result[\"insert_time\"],\n", " result[\"find_time\"],\n", " result[\"delete_time\"]]\n", " report.append(row)" ] }, { "cell_type": "code", "execution_count": 12, "id": "2eedf056", "metadata": {}, "outputs": [], "source": [ "# Сохраним данные в csv\n", "import csv\n", "with open(\"data/task1/results.csv\", \"w\", newline=\"\") as f:\n", " writer = csv.writer(f)\n", " writer.writerows(report)" ] }, { "cell_type": "markdown", "id": "94335af1", "metadata": {}, "source": [ "# 3. Построение графиков и их анализ" ] }, { "cell_type": "code", "execution_count": 13, "id": "cad64d2f", "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAABdEAAAHqCAYAAADrpwd3AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjYuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/P9b71AAAACXBIWXMAAA9hAAAPYQGoP6dpAACcZElEQVR4nOzde1xVZfr///eWo2migoEUIFqjkKUF5YDiYUwMyzx+pCysPBSDpUJpovLJLCPLbOcokqUxTqXMZ0jtwCQ4o6RJNiDYNFGaoZjBGFqSppx/f/hl/9zuvREU3IKv5+OxHtO+17Xu+157kGvti3uvZaitra0VAAAAAAAAAACw0MbeEwAAAAAAAAAA4EpFER0AAAAAAAAAABsoogMAAAAAAAAAYANFdAAAAAAAAAAAbKCIDgAAAAAAAACADRTRAQAAAAAAAACwgSI6AAAAAAAAAAA2UEQHAAAAAAAAAMAGiugAAAAAAAAAANhAER1owVJSUmQwGMy2Ll26aPDgwfroo4/sPT0AANCErOX987du3brZe5oAAABAq0MRHWgF3n77bWVnZ2vXrl1avXq1HBwcNHLkSH344Yf2nhoAAGhidXn//K1///72nhoAAK3eyy+/LIPBoA8++MBiX0lJiZydnTV69OjLPzEAzcrR3hMAcOl69+6t4OBg0+u7775bnTp10vr16zVy5Eg7zgwAADS18/N+nY4dO+qHH36ww4wAALh6TJ06VQsXLtSf/vQn3XfffWb7Vq1apcrKSj355JN2mh2A5sJKdKAVcnV1lbOzs5ycnExt5eXlWrRokQICAuTq6ip3d3cNGTJEu3btkqQLfj188ODBkqQzZ87oqaeeUt++feXm5qbOnTsrJCREmzdvtpjHucc7ODjI29tbDz/8sP773/+aYg4ePCiDwaCUlBRTW2lpqW699VYFBASopKTE1L5y5UoNHDhQ1113ndq1a6dbbrlFL7/8siorK5v4HQQAoOU7c+aM4uPj5e/vL2dnZ11//fWaPn26fvnlF7O4bt266ZFHHjFr+8tf/mL19jAXup6Qzub/hQsXml6fPn1aQ4cOVdeuXfXNN9808VkCAHB5de7cWQ8++KC2bt2qgoICU3tFRYXeeOMN3XzzzRo6dKgdZwigOVBEB1qB6upqVVVVqbKyUj/88INmzZqlU6dOaeLEiZKkqqoqRURE6Pnnn9e9996rjRs3KiUlRaGhoSoqKpIks6+DL1iwQJL0/vvvm9qSkpIknf3wfPz4cT399NPatGmT1q9frwEDBmjs2LFat26dxdymTJmi7OxsZWVlafbs2UpNTdWjjz5q81xKS0v1hz/8QZWVldq2bZu8vLxM+w4cOKCJEyfqL3/5iz766CNNmTJFr7zyih5//PEmey8BAGgNamtrNXr0aC1dulRRUVH6+OOPFRcXpz//+c/6wx/+oPLycpvHlpWVac6cOXJwcDBrb8j1xPlOnz6te++9V19//bW2bdumXr16Nel5AgBgD3Urzf/0pz+Z2lJTU/Xf//7XYhX6I488YnWh2vl/wE5NTVV4eLi6du2qtm3bKiAgQHPnztWpU6eszsHWAriDBw+aYmpra5WUlKS+ffuqbdu26tSpk8aPH6/vv//erK/Bgwerd+/eFmMsXbrUos/G/PG9oqJCL7zwgnr16iUXFxd16dJFjz76qH766Ser5wRcybidC9AK/P73vzd77eLiohUrVmj48OGSpPXr12vbtm168803NXXqVFPcubd6ObePulVit912m0USdHNz09tvv216XV1draFDh+rnn3+W0WjUpEmTzOJvuOEGU98DBgzQp59+arZa7VylpaUaOnSo1QK6JC1btsz03zU1NQoLC5O7u7seffRRvfrqq+rUqZP1NwgAgKtMRkaGtmzZopdfflmzZ8+WJA0bNkw+Pj6KjIzUunXrNG3aNKvHPvvss3JwcNDo0aOVk5Njam/I9cS5Tp8+rZEjR1JABwC0OrfeeqsGDhyodevWKTExUW5ubvrTn/6kTp06KSoqyiK+bdu2+uc//2l6/Yc//MEiZv/+/RoxYoRmzZqldu3a6ZtvvtGSJUv0xRdfmB17rilTpphy8scff6wXXnjBbP/jjz+ulJQUzZgxQ0uWLNHx48e1aNEihYaGau/evfL09LyUt0GS7T++19TUaNSoUdqxY4fmzJmj0NBQHTp0SM8++6wGDx6snJwctW3b9pLHBy4XiuhAK7Bu3ToFBARIOluI3rhxo6ZPn67q6mo98cQT+vvf/y5XV1dNnjy5Scb7v//7PxmNRu3du9fsr+Kurq4WsTU1NaqqqlJ1dbW++OIL7dy5U8OGDbOIO3bsmIYOHaovv/xS//nPfywK6JKUl5enZ599Vp999pmOHz9utm/fvn3q169fE5wdAAAtX92H7fNXiv3P//yPJk+erH/84x9Wi+hfffWVVqxYoXfeeUd///vfzfY15nri9OnTuu+++/SPf/xDH3/8MQV0AECr8+STT+p//ud/9Pbbb6tfv37617/+paefflrXXHONWVx5ebmcnJzMFq61aWN5Y4i6b4RLZ1eQ9+/fXwEBARo0aJC+/PJL3Xrrrab9FRUVks6uCq/r9/xbpn3++ed688039eqrryouLs7UHhYWpt/97ndatmyZlixZcgnvwFm2/vj+17/+VZ988onS0tI0duxYU3ufPn10xx13KCUlRX/84x8veXzgcuF2LkArEBAQoODgYAUHB+vuu+/WG2+8ofDwcM2ZM0e//PKLfvrpJ3l7e1tN1I31/vvva8KECbr++uv1zjvvKDs7W//61780efJknTlzxiL++eefl5OTk1xdXTVw4EDdeOONMhqNFnHz5s1TRUWFvLy8lJCQYLG/qKhIYWFhOnLkiF5//XXt2LFD//rXv7Ry5UpJZz+sAwCAs44dOyZHR0d16dLFrN1gMMjLy0vHjh2zetz06dMVFhamyMhIi32NuZ4wGo366quv1KtXLy1atEhVVVUXdyIAAFyhRo8eLR8fH61YsUJGo1EODg6aPn26RdzJkyctCuvWfP/995o4caK8vLzk4OAgJycnDRo0SJLM7r0u/f+ff60tZKvz0UcfyWAw6KGHHlJVVZVp8/LyUp8+fbR9+3aLY86Nq6qqUk1NTb1zrvvj+6uvvqr27dtbjN+xY0eNHDnSrM++ffvKy8vL6vjAlYyV6EArdeutt2rLli3at2+funTpop07d6qmpuaSC+nvvPOO/P39lZqaKoPBYGq3dW/VadOm6bHHHlNtba1+/PFHvfjiiwoJCVF+fr6uvfZaU1z37t21bds27d27VxEREVqzZo2mTJli2r9p0yadOnVK77//vvz8/Ezt+fn5l3Q+AAC0Ru7u7qqqqtJPP/1kVkivra1VSUmJ7rjjDotj3n33XWVnZ9vMrY25nujcubO2bdumiooK3XnnnXruuef0/PPPX9I5AQBwJXF0dNQf//hHzZs3TwcOHNDo0aMtbocqSUeOHJG3t3e9fZ08eVJhYWFydXXVCy+8oN/97ne65pprdPjwYY0dO9Zi0VhpaakkycPDw2af//3vf1VbW2vzli3du3c3e/2f//xHTk5O9c7zfOf+8f38b7D997//1S+//CJnZ2erx9adA9BSUEQHWqm6D8BdunRRRESE1q9fr5SUlEu+pYvBYJCzs7NZAb2kpESbN2+2Gu/t7a3g4GDT69raWo0ZM0bZ2dkKDw83tT/zzDPy8vKSl5eXnnzySc2cOdP0NbO6caWz93s/t68333zzks4HAIDWaOjQoXr55Zf1zjvvKDY21tSelpamU6dOaejQoWbxv/76q2bPnq2ZM2cqMDDQap+NuZ54/PHHTbdwSUxM1NNPP63w8HCFhYVd4pkBAHDlmDZtmhYtWqQzZ85oxowZFvsrKytVUFBg9Rte5/rnP/+pH3/8Udu3bzetPpekX375xWr8/v37JUk33nijzT49PDxkMBi0Y8cOs8/Rdc5v69GjhzZs2GDW9s477+j111+32v+F/vju4eEhd3d3ffLJJ1b3n7uoDmgJKKIDrcBXX31l+pr0sWPH9P777yszM1NjxoyRv7+/fHx89Pbbbys6OlrffvuthgwZopqaGu3evVsBAQG6//77GzzWvffeq/fff18xMTEaP368Dh8+rOeff15du3Y1JfJz/fDDD/r8889NK9ETExPl4uJiuoe7NUuWLNE///lPPfjgg9q1a5ecnJw0bNgwOTs764EHHtCcOXN05swZrVq1Sj///HPj3zAAAFq5YcOGafjw4XrmmWdUVlam/v3768svv9Szzz6r2267zeKhZ5s3b5anp6eeffZZm30+8MADF3U9MWvWLP3973/XQw89pL1796pjx45NeaoAANhNhw4d1L59e910000aMmSIxf6MjAydOXPG5kO461hbNCZJb7zxhtX4TZs2qV27dgoKCrLZ57333quXXnpJR44c0YQJEy50KnJ1dTVbACfJ5i1XGvLH93vvvVcbNmxQdXU1zy9Dq0ARHWgFHn30UdN/u7m5yd/fX8uWLVNMTIyks18zS09PV2JiotavXy+j0ahrr71Wffr00d13393osY4ePark5GStXbtW3bt319y5c/XDDz/oueees4hfs2aN1qxZI4PBoM6dO6tPnz76+9//Lh8fH5tjuLq66t1339Wdd96phIQEvfTSS+rVq5fS0tK0YMECjR07Vu7u7po4caLi4uIUERHRqHMAAKC1MxgM2rRpkxYuXKi3335bixcvloeHh6KiovTiiy9afEivrq62ej/Tc13s9YTBYFBK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1Pb222/rf/7nf0z/4F1dXXX69Gmb/ffp00ePP/64brnlFt1000164YUX1L17d33wwQdW4//85z/rzJkzGjVqVENP95Lt27dPa9euVWxs7GUbEwAAAJcP18eNw/UxAOBKRU5vHHL6xaGIfpWora2VdPZrJxdSVlZm9S93daZOnaq3335bknT06FF9/PHHmjx5smn/zTffrL/97W+qrKy0evypU6c0Z84cBQYGqmPHjmrfvr2++eYbq3+V++2337RgwQK98sorcnS0vIV/UlKS2rdvb9pefPFFi5iPPvpI7du3V8eOHXXLLbdo5cqVF3wP5syZo8cff1zdu3e/YCwAAABaHq6PuT4GALQO5HRy+uVAEf0qcdNNN8lgMKigoOCCsT/++KO8vb1t7p80aZK+//57ZWdn65133lG3bt0UFhZm2v/aa6/p008/Vbt27dS+fXtFR0ebHT979mylpaVp8eLF2rFjh/Lz83XLLbeooqLCYqxXXnlFPXv21MiRI63O5cEHH1R+fr5pO38sSRoyZIjy8/P1+eefKzo6WjNmzNA//vEPm+eXlZWlHTt2aMGCBTZjAAAA0LJxfcz1MQCgdSCnk9MvB8s/c6BV6ty5s4YPH66VK1dqxowZFn91++WXX9SxY0edOnVKBQUFio+Pt9mXu7u7Ro8erbffflvZ2dl69NFHzfaHhYWppKRERUVFqq6u1vvvv2/217IdO3bokUce0ZgxYySdvV/UwYMHLcYpLi7WqlWrtH37dptzcXNz04033mh2nudr166dKaZXr1567bXXlJeXZ/WvfLW1tXrqqaeUkJCgTp062RwX51noZu8ZXJqFJ+w9AwAArgwXk9Pb+0j9X5WOnpYcL7wCrNn8mCd539bgcK6PuT4GgFatsTn9SsnnEjn9/yGnX1nsvhI9KSlJ/v7+cnV1VVBQkHbs2GEztri4WBMnTlTPnj3Vpk0bi6fU1vnll180ffp0de3aVa6urgoICFB6enoznUHLkZSUpOrqat15551KS0vT/v37VVBQoOXLlyskJETffPONHnjgAXXs2FERERH19jV16lT9+c9/VkFBgR5++GGL/Q4ODvL399eNN96o6667zmzfjTfeqPfff1/5+fnau3evJk6cqJqaGos+Vq5cqTFjxuj222+/pPOuqanRmTNndPLkSX3wwQc6dOiQbrnlFqux//jHP3TixAnFxMRc0pgAAAC48nF9zPUxAKB1IKeT05ubXVeip6amatasWUpKSlL//v31xhtvKCIiQl9//bV8fX0t4svLy9WlSxfNnz9fr732mtU+KyoqNGzYMF133XX629/+phtuuEGHDx/Wtdde29ync8Xz9/fXnj17tHjxYj311FMqLi5Wly5dFBQUpFWrVmnhwoWqqqrS1q1bL/hU4Lvuuktdu3bVzTffXO/XYKx57bXXNHnyZIWGhsrDw0PPPPOMysrKLOJqamq0ePHiRvVtzYcffqi2bdvK0dFRvr6+SkxM1PDhw61+zefUqVN66aWXzB4sAQAAgNaJ62OujwEArQM5nZze3Ay1dXfft4N+/frp9ttv16pVq0xtAQEBGj16tBITE+s9dvDgwerbt6+MRqNZe3Jysl555RV98803cnJyuqh5lZWVyc3NTSdOnFCHDh3M9p05c0aFhYWm1fNXq99++03e3t5au3atxo4da+/poIlc9M83t3MBGqS+/ILmwXsONNJF5PQz7X1U2P9V+V/fRa72/vp3I7763dS4Pm596rs2Jr9cfrznQCM1MqdfUflcIqejSTVFTrfb7VwqKiqUm5ur8PBws/bw8HDt2rXrovv94IMPFBISounTp8vT01O9e/fWiy++qOrq6kudMnT2L2U//vijEhIS5Obmpvvuu8/eUwIAAADshutjAABaB3I66mO327mUlpaqurpanp6eZu2enp4qKSm56H6///57/fOf/9SDDz6o9PR07d+/X9OnT1dVVZX+93//1+ox5eXlKi8vN7229jULnFVUVCR/f3/dcMMNSklJsfqgAgAAAOBqwfUxAACtAzkd9bH7T4PBYP4VkdraWou2xqipqdF1112n1atXy8HBQUFBQfrxxx/1yiuv2CyiJyYm6rnnnrvoMa8m3bp1kx3vAAQAAABcUbg+BgCgdSCnoz52u52Lh4eHHBwcLFadHz161GJ1emN07dpVv/vd7+Tg4GBqCwgIUElJiSoqKqweEx8frxMnTpi2w4cPX/T4AAAAAAAAAIDWw25FdGdnZwUFBSkzM9OsPTMzU6GhoRfdb//+/fXdd9+ppqbG1LZv3z517drV5tNnXVxc1KFDB7MNAAAAAAAAAAC7FdElKS4uTm+99ZbWrl2rgoICxcbGqqioSNHR0ZLOrhCfNGmS2TH5+fnKz8/XyZMn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lzWtS5cuOnv2rH744QcdPHhQeXl5uv/+++2W88477+jbb78td3udPn1aDRo0cDl/9+7d2rJli91y27RpI0l2y77rrrvs2hcbG6sjR46oqKhI6enpMsaoVatWdsvZunWr3TJKtoO/v7/uuusujRw50tp2GRkZuvXWW+3OVHfp0kXFxcX6+uuvnbbd/P9HCZRuV3lKvu+GDRvqzJkzdr8giI6OVkpKik6cOOHy89u2bVNAQICCg4N14cIFTZ8+3Zq3ZcsW3X///WratKkCAwOVkJCg06dP69y5cw7r76oflGjWrJldOWc6d+6sgIAANWvWTD169FBmZma5617RvlDi5MmT+vHHH3XvvfeWW85d58+f1/jx4/X666+rbt261vSMjAzl5+e7rMfd/pCZmanu3bsrLy9P3bp1q5I2V8aiRYtUr149ZWZm6ocffrCbd9NNN1nfYa9evZSfn293XKiMyZMn2/WJsscgV9zpl126dJG3979j6He/+50uXryob775xpqWm5vr9FckZRlj9MILL2jSpEkKCgqqxBr+27x589SpUyddf/31CggI0IIFC9xeX9Q+ZDqZXoJMJ9PJ9PKR6ajpyHQyvQSZTqaT6eUj0y8Pg+iVUL9+fd1444268cYbdccdd2jRokXy8/PTBx984FD2hRde0IgRIxQWFuZ0WTNmzLCCfu/everUqZM179y5c4qPj1dAQID+53/+R2lpaVq9erWkS5ePVaR0YAQGBtrVs27dOruyxhiHgCkdPMXFxZKktWvX2i3n4MGD+sc//lFuO7777jtFRUW5nF9cXKyHH37Ybrl79+7VkSNHdPfdd1e4niXLqFOnjnbv3m23jIyMDL311lsO22H//v366KOPtGTJEi1ZssTlNijhanrLli3l5eXl9gGv5PvetWuXoqOj9cc//tGaN3HiREVFRVnB6Cw4O3XqpD179mjDhg06ffq0FixYIEn6/vvv9dBDD6l9+/ZKTk7W7t27NXv2bEmyu1ywon5QYtu2bXblnFmxYoX27t2r999/X1lZWUpISCh33SvaF0r8lsspy/P666+rdevWevjhhytVj7v9Yf/+/Ro4cKAef/xxPfnkk9a+ciWkpqZqxowZ+vDDDxUbG6uBAwda+60krVu3zvoOS45Pv3X7Dho0yK5PhIeHV/gZd/plw4YN3drOP/74o1t1vvPOOzp3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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import pandas as pd\n", "import numpy as np\n", "import matplotlib.pyplot as plt\n", "\n", "df = pd.read_csv('data/task1/results.csv')\n", "mean_times = df.groupby(['Структура', 'Режим'])[['Вставка', 'Поиск', 'Удаление']].mean().reset_index()\n", "structures = mean_times['Структура'].unique()\n", "modes = mean_times['Режим'].unique()\n", "\n", "fig, axes = plt.subplots(1, 3, figsize=(15, 5))\n", "operations = ['Вставка', 'Поиск', 'Удаление']\n", "\n", "for ax, op in zip(axes, operations):\n", " # a\n", " x = np.arange(len(structures))\n", " width = 0.35\n", " \n", " random_vals = []\n", " sorted_vals = []\n", " for s in structures:\n", " random_row = mean_times[(mean_times['Структура']==s) & (mean_times['Режим']=='Cлучайный')]\n", " sorted_row = mean_times[(mean_times['Структура']==s) & (mean_times['Режим']=='Отсортированный')]\n", " random_vals.append(random_row[op].values[0] if not random_row.empty else 0)\n", " sorted_vals.append(sorted_row[op].values[0] if not sorted_row.empty else 0)\n", " \n", " ax.bar(x - width/2, random_vals, width, label='Случайный')\n", " ax.bar(x + width/2, sorted_vals, width, label='Отсортированный')\n", " ax.set_xticks(x)\n", " ax.set_xticklabels(structures)\n", " ax.set_ylabel('Время (сек)')\n", " ax.set_title(op)\n", " ax.legend()\n", "\n", "plt.tight_layout()\n", "plt.savefig('data/task1/performance_plot.png', dpi=150)\n", "plt.show()" ] }, { "cell_type": "code", "execution_count": 14, "id": "1d86131d", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
СтруктураРежимВставкаПоискУдаление
0Бинарное деревоCлучайный0.0119210.0001500.000137
1Бинарное деревоОтсортированный0.1221710.0016270.000873
2Связанный списокCлучайный0.0900390.0008930.000605
3Связанный списокОтсортированный0.1624470.0017070.000915
4Хэш-таблицаCлучайный0.0448310.0006180.000324
5Хэш-таблицаОтсортированный0.0493690.0005270.000272
\n", "
" ], "text/plain": [ " Структура Режим Вставка Поиск Удаление\n", "0 Бинарное дерево Cлучайный 0.011921 0.000150 0.000137\n", "1 Бинарное дерево Отсортированный 0.122171 0.001627 0.000873\n", "2 Связанный список Cлучайный 0.090039 0.000893 0.000605\n", "3 Связанный список Отсортированный 0.162447 0.001707 0.000915\n", "4 Хэш-таблица Cлучайный 0.044831 0.000618 0.000324\n", "5 Хэш-таблица Отсортированный 0.049369 0.000527 0.000272" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df = pd.read_csv('data/task1/results.csv')\n", "df.groupby(['Структура', 'Режим'])[['Вставка', 'Поиск', 'Удаление']].mean().reset_index()" ] }, { "cell_type": "markdown", "id": "c9a486a5", "metadata": {}, "source": [ "# 4. Анализ результатов\n", "---\n", "### 4.1 Влияние порядка данных на вставку в BST\n", "При вставке элементов в отсортированном порядке в бинарное дерево оно превращается в связный список - это связанно с тем, что все элементы вставляются в одну ветвь дерева. Сложность всех операций приблтижается к **O(n)**. Вставка в BST на отсортированных данных заняла 0.122171c вместо 0.011921с, разница более чем в 10 раз. Причём, время вставки даже хуже, чем у чистого связнного списка - это связанно с дополнительными расходами бинарного дерева. Поиск так же ухудшился, примерно в 10 раз, а с ним ухудшилось и удаление.\n", "\n", "### 4.2 Почему хэш-таблица почти не чувствительна к порядку\n", "По графикам видно, что для хэш-таблицы время операций почти не изменяется. Исключение составляет лишь поиск, его время больше на отсортированных данных. Это связано с особенностями теста - поиск 10 несуществующих записей ухудшают результат для отсортированных данных. Все эти наблюдения связаны с механизмом работы хэш-таблицы - она распределяет данные по корзинам независимо от порядка поступления. Получается, что сложность всех операций **O(1)**\n", "\n", "### 4.3 Почему связный список всегда медленен при поиске\n", "Для поиска в связном списке нужно просматривать все элементы по порядку, так что сложность всех операций **O(n)**\n", "\n", "### 4.4 Сравнение удаления\n", "\n", "- **Связаный список** удаление требует сначала найти элемент за O(n), затем переставить ссылки за O(1). Время удаления (0.000605 с) близко ко времени поиска, что логично.\n", "- **Хеш-таблица:** при удалении, поиск корзины за O(1) и поиск в коротком связаном списке за O(n) удаляется элемент. Время удаления (0.000324) меньше, чем в списке.\n", "- **BST:** на случайных данных удаление очень быстрое (0.000137 с) благодаря логарифмической высоте. На отсортированных данных время возрастает до 0.000873, что отражает деградацию до O(n)." ] }, { "cell_type": "markdown", "id": "a7ed5470", "metadata": {}, "source": [ "# 5. Вывод\n", "На основе полученных результатов можно сформулировать следующие рекомендации:\n", "\n", "- Хеш-таблица – хороший выбор, если приоритетом является максимальная скорость вставки, поиска и удаления по ключу, а порядок элементов не имеет значения. Время операций близко к **O(1)** и практически не зависит от упорядоченности входных данных. Идеальна для кэшей, словарей и частых запросов по идентификатору.\n", "\n", "- Двоичное дерево поиска – следует применять, когда необходимо получать данные в отсортированном порядке. На случайных данных демонстрирует хорошую производительность **O(log n)**, однако при поступлении заранее отсортированных элементов вырождается в связный список с падением скорости до **O(n)**.\n", "\n", "- Связный список – демонстрирует линейную сложность поиска и удаления **O(n)** что делает его непригодным для задач с частым доступом к произвольным элементам. Может быть оправдан только в узких случаях, где вставки и удаления происходят исключительно в начале или конце коллекции (очереди, стеки) и не требуется поиск.\n", "\n", "Таким образом, для реальных задач чаще всего выбирают хеш-таблицы или сбалансированные деревья в зависимости от требований к упорядоченности данных.\n" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.11.2" } }, "nbformat": 4, "nbformat_minor": 5 }