【Структура данных】Сначала поймите временную и пространственную сложность структуры данных.

Дорога длинная и длинная, и я буду искать вдоль и поперек. —— Цюй Юань

 

Оглавление

1. Что такое структура данных?

2. Что такое алгоритм?

1. Сложность алгоритма

2. Временная сложность

3. Упражнения на временную сложность

4. Пространственная сложность


1. Что такое структура данных?

Структура данных — это набор и обработка элементов данных, которые имеют одно или несколько конкретных отношений друг с другом.

Это относится к взаимосвязям между элементами данных, то есть к организации данных. Эта организационная форма является логической структурой данных.

Логика данных обычно имеет следующие четыре основные структуры:

1. Коллективные учреждения

2. Линейная структура

3. Древовидная структура

4. Структура графика

В процессе фактической обработки данных компьютером мы должны учитывать, как данные должны храниться, чтобы они могли отражать взаимосвязь между данными.

Способ хранения данных в компьютере является структурой хранения данных . Например, последовательный список, связанный список и т. д., которые будут изучены позже .

Кроме того, в процессе обработки данных также будут происходить такие операции , как удаление данных, вставка и поиск , поэтому следует рассмотреть и способ обработки данных, то есть алгоритм .

2. Что такое алгоритм?

Алгоритм (алгоритм) относится к точному и полному описанию схемы решения проблемы, которая представляет собой серию четких инструкций по решению проблемы.Алгоритм представляет собой механизм стратегии для систематического описания решения проблемы. То есть требуемый результат может быть получен в течение ограниченного времени для определенного стандартного ввода .

Подобно пузырьковой сортировке, поиску числа, проверке дубликатов и т. д. — все это алгоритмы.

Особенности алгоритма:

Конечность: алгоритм должен иметь возможность завершаться после выполнения конечного числа шагов.

Точность: каждый шаг алгоритма должен иметь точное определение.

Входы: Алгоритм имеет 0 или более входов для описания исходной ситуации операнда.

Выходной элемент: Алгоритм имеет один или несколько выходных данных для отражения результата обработки входных данных, а алгоритм без выходных данных не имеет смысла.

Выполнимость: любой вычислительный шаг, выполняемый в алгоритме, можно разбить на основные выполняемые рабочие шаги.

1. Сложность алгоритма

После того, как алгоритм скомпилирован в исполняемую программу, ему необходимо потреблять временные ресурсы и ресурсы пространства (памяти) при работе. Следовательно, чтобы измерить качество алгоритма, его обычно измеряют по двум измерениям времени и пространства, то есть по временной и пространственной сложности.

Временная сложность в основном измеряет скорость работы алгоритма, а пространственная сложность в основном измеряет дополнительное пространство, необходимое для работы алгоритма. В первые дни развития компьютеров у компьютеров было очень мало места для хранения данных . Поэтому меня очень беспокоит космическая сложность. Однако с быстрым развитием компьютерной индустрии емкость компьютеров достигла очень высокого уровня. Таким образом, нам больше не нужно уделять особое внимание пространственной сложности алгоритма.

2. Временная сложность

Определение временной сложности. В информатике временная сложность алгоритма — это функция (математическая функция) , которая количественно описывает время выполнения этого алгоритма. Теоретически время, необходимое для выполнения алгоритма, невозможно рассчитать, узнать его можно только в том случае, если вы поместите свою программу на машину и запустите ее. Но нужно ли тестировать каждый алгоритм на компьютере?Да, мы можем протестировать все алгоритмы на компьютере, но это очень хлопотно, поэтому у нас есть метод анализа временной сложности. Время, затрачиваемое алгоритмом, пропорционально количеству выполнений операторов в нем , а количество выполнений основных операций в алгоритме есть временная сложность алгоритма .

Резюме: Алгоритм — это не количество времени выполнения, потому что, когда вы запускаете код, скорость времени также связана с конфигурацией вашего компьютера и скоростью сети в это время. Так что просто найдите количество запусков алгоритма. То есть математическое выражение между некоторым базовым предложением и размером задачи N состоит в вычислении временной сложности алгоритма.

Пример: подсчитайте, сколько раз было выполнено выражение count++ в Fun1?


void Func1(int N)
{
	int count = 0;

	for (int i = 0; i < N; i++)
	{
		for (int j = 0; j < N; j++)
		{
			count++;
		}
	}

	for (int k = 0; k < 2 * N; k++)
	{
		count++;
	}
	int M = 10;
	while (M--)
	{
		count++;
	}
	printf("%dn", count);
}

Общее количество петель выше: выражение математической функции F(N)=N^2+2*N+10.

Временная сложность F(N)=N^2+2*N+10.

Когда N принимает разные значения:

  • N = 10 F(N) = 130
  • N = 1000 F(N) = 1002010
  • N = 100000 F(N) = 10000200010

Здесь мы видим, что по мере постепенного увеличения N 2*N+10 в F(N)=N^2+ 2*N+10 оказывает все меньшее и меньшее влияние на значение всей функции. Временная сложность все ближе и ближе к N^2, можно сказать, что N^2 — это временная сложность этого алгоритма.

Для сложности времени мы используем асимптотическую нотацию большого 0:
нотация большого 0 (нотация Big 0)  : это математический символ, используемый для описания асимптотического поведения функций.

Вывод метода Big 0: 
1. Замените все аддитивные константы во время выполнения константой 1 . 2. В модифицированной функции времени работы сохраняется только член высшего порядка . 3. Если элемент наивысшего порядка существует и не равен 1 , удалите константу, умноженную на этот элемент . Полученный результат порядка 0.

После использования асимптотического представления большого 0 временная сложность Func1 составляет: O (N ^ 2).

Из вышеизложенного мы обнаружим, что прогрессивное представление большого 0 удаляет те элементы, которые мало влияют на результат, и кратко и ясно выражает количество выполнений. Кроме того, существуют лучшие, средние и худшие временные сложности некоторых алгоритмов :


Наихудший случай: максимальное количество запусков для любого размера входных данных (верхняя граница)
Средний случай: ожидаемое количество запусков для любого размера входных данных
Наилучший случай: минимальное количество запусков для любого размера входных данных (нижняя граница)


Например: Поиск данных x в массиве длины N
Лучший случай: 1 найти
Наихудший случай: N найти
Средний случай: N/2 найти
На практике общий случай фокусируется на наихудших условиях работы алгоритма , поэтому время сложность поиска данных в массиве равна 0(N) .

3. Упражнения на временную сложность

1. Какова временная сложность Func2?

void Fun2(int N)
{
	int count = 0;
	for (int k = 0; k < 2 * N; k++)
	{
		count++;
	}
	int M = 10;
	while (M--)
	{
		count++;
	}
	printf("%d\n", count);
}

Точно F(N)=2*N+10.

Поскольку N продолжает увеличиваться, размер F(N) не имеет ничего общего с 10, поэтому при выражении временной сложности 10 нужно убрать, а согласно третьему пункту вывода метода большого 0-го порядка: 3. Если член высшего порядка существует и не равен 1 , константа, умноженная на этот член, удаляется . Полученный результат порядка 0. Так что 2 в 2*N тоже можно убрать.

Следовательно, временная сложность Func2 равна O(N).

2. Какова временная сложность вычисления Func3?

void Func3(int N, int M)
{
	int count = 0;
	for (int k = 0; k < M; k++)
	{
		count++;
	}
	for (int k = 0; k < N; k++)
	{
		count++;
	}
	printf("%d\n", count);
}

Очевидно, что между M и N нет очевидной связи, поэтому временная сложность равна O(N+M).

1. Если N намного больше, чем M, временная сложность равна O(N).

2. Если M намного больше, чем N, временная сложность равна O(M).

3. Если M и N примерно одного размера, временная сложность равна O(N) или O(M).

3. Рассчитать временную сложность strchr?

Функция функции strchr состоит в том, чтобы найти указанный символ в строке, и если символ найден, она возвращает адрес, по которому появляется первый символ. Если после поиска в строке символ не найден, возвращается нулевой указатель.

#include<string.h>//NULL空指针需要的头文件
#include<assert.h>//assert必须要的头文件
char* strchr(const char* str, int character)
{ //字符的ASCll值就是数子,所以这里字符的数据类型可以用int
	assert(str);
	while (*str)
	{
		if (*str == character)
			return str;
		else
			str++;
	}
	return NULL;
 }

 При вычислении временной сложности мы все рассчитываем в худшем случае , поэтому временная сложность алгоритма strchr составляет O(N).

3. Рассчитать временную сложность пузырьковой сортировки?

void Bulllesort(int *arr,int N)
{
    assert(arr);
    for (int i = 0; i < N; i++)
    {
        for (int j = 0; j < N - i; j++)
        {
            if (arr[j] > arr[j + 1]) {
                int ret = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = ret;
            }
        }
    }

 Здесь видно, что при первом входе в пузырьковую сортировку массив нужно поменять местами 9 раз, при втором входе в пузырьковую сортировку массив нужно поменять местами 8 раз и так далее. По сути, это арифметическая прогрессия. F(N)=N(1+N)/2, поэтому временная сложность равна O(N^2).

4. Рассчитать временную сложность бинарного поиска?

int Binarysearch(int nums[], int size, int target) 
{
    int left = 0;
    int right = size - 1;	
    while (left <= right) {
        int middle = left + ((right - left) / 2);
        if (nums[middle] > target)
        {
            right = middle - 1;
        }
        else if (nums[middle] < target)
        {
            left = middle + 1;
        }
        else {
            return middle;
        }
        }
}

Мы вычисляем временную сложность в худшем случае, В бинарном поиске худший случай состоит в том, что искомое число находится ровно посередине. То есть 2 ^ x = N, x - количество поисков.В математике log - это логарифм с основанием 2, но его нелегко набирать на клавиатуре, поэтому он упрощается до log2, поэтому временная сложность двоичного поиска Это O (log2).

4. Пространственная сложность

Пространственная сложность также является выражением математической функции, которая является мерой временного объема памяти, занимаемого алгоритмом во время работы.
Пространственная сложность — это не то, сколько байт занимает программа , потому что это не очень значимо. Таким образом, пространственная сложность подсчитывает количество переменных . Правила расчета пространственной сложности в основном аналогичны практической сложности, также используется асимптотическое представление большого 0.
Примечание. Пространство стека (параметры хранения, локальные переменные, некоторая информация о регистрах и т. д.), необходимое функции во время выполнения, определяется во время компиляции, поэтому сложность пространства в основном определяется дополнительным пространством, явно запрашиваемым функцией во время выполнения.
 

void Bulllesort(int *arr,int N)
{
    assert(arr);
    for (int i = 0; i < N; i++)
    {
        for (int j = 0; j < N - i; j++)
        {
            if (arr[j] > arr[j + 1]) {
                int ret = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = ret;
            }
        }
    }

Как и в случае с этой пузырьковой сортировкой, в дополнение к параметрам в функции определены две дополнительные переменные i и j , поэтому пространственная сложность равна O(1).

В настоящее время объем памяти компьютеров относительно велик, и объемная сложность не имеет большого значения.

Общие сравнения сложности:

 

 

Это не легко создать, я надеюсь, что каждый может поставить лайк, спасибо. 

рекомендация

отblog.csdn.net/adcxhw/article/details/129509152