- •Общие сведения
- •Средства разработки
- •Структура программы
- •Алфавит
- •Лексемы
- •1.2. Переменные. Типы данных
- •Простые типы данных
- •Структурированные типы данных
- •1.3. Константы
- •1.4. Операции Арифметические
- •Присваивание
- •1.5. Операторы ветвления и цикла
- •1.6. Функции Описание и вызов
- •Неявно заданные параметры функции
- •Рекурсия
- •Механизм вызова функций, подставляемые функции
- •Перегрузка функций. Параметры по умолчанию
- •1.7. Указатели. Массивы. Строки Обзор
- •Приведение типов
- •Типизированные и нетипизированные указатели
- •Операции над указателями
- •Массивы
- •Многомерные массивы
- •Указатели в качестве параметров функций
- •Указатель на функцию
- •Функции работы с указателями и памятью
- •Строки.
- •1.8. Организация ввода-вывода
- •Форматированный ввод-вывод
- •1.9. Директивы препроцессора
- •1.10. Метки. Безусловный переход
- •1.11. Время жизни и область видимости переменных
- •1. 12. Многофайловые проекты
- •1.13. Введение в объектно-ориентированное программирование
- •2.3. Проблемы разработки сложных программных систем
- •2.4. Жизненный цикл программного продукта
- •Модели жц.
- •Экстремальное программирование
- •2.5. Оценка качества процессов создания программного обеспечения
- •2.6. Проектирование надёжного программного средства
- •2.7. Процессы проектирования
- •2.8. Требования, цели
- •2.9. Внешнее проектирование
- •Диаграммы потоков данных (Data Flow Diagrams).
- •Диаграммы переходов состояний (State Transition Diagrams). Функциональные диаграммы.
- •Описание структур данных
- •2.10. Проектирование архитектуры
- •2.11. Проектирование модульной структуры. Модуль
- •Внешнее проектирование модулей
- •Модульная декомпозиция
- •2.12. Кодирование.
- •2.13. Тестирование
- •2.14. Документирование
- •2.15. Проектирование пользовательского интерфейса
- •Реализация многомерных массивов
- •Очередь и стек
- •Ассоциативные массивы
- •3.3. Упорядоченные структуры данных.
- •Сортировка методом пузырька
- •Быстрая сортировка
- •3.4. Деревья
- •Бинарное дерево
- •Обход дерева
- •3.5. Множества, графы Множества
- •3.6. Строки Константные строки
- •Списковое представление строк
- •Представление массива строк
- •3.7. Библиотека stl
- •3.8. Реализация некоторых структур данных Реализация двусвязанного списка.
- •Реализация массива переменного размера:
- •Примеры программ
- •Список литературы
Реализация массива переменного размера:
1. С быстрым извлечением – создаётся вектор размера top, если происходит попытка записи элемента с номером n больше top, происходит перевыделение памяти так, чтобы (n < top). Может дополнительно задаваться шаг роста массива. Далее существующие данные копируются в новый массив; освобождается место, где ранее размещался массив. Недостаток – существенные временные затраты на «рост».
2. С быстрым расширением – создаётся список векторов, инициализируется только первый вектор (размер top). При попытке записи элемента с номером n больше top к списку добавляются один или несколько векторов, чтобы (n<top). Для ускорения доступа все векторы целесообразно создавать одного размера. Доступ к элементу осуществляется по номеру вектора (k) и номеру элемента в векторе (m). При равных размерах векторов (top) и заданном порядковом номере элемента (n) получаем: k=n/top, m=n%top.
В качестве модификации можно использовать вектор векторов (несколько быстрее доступ, но сложнее организовать рост).
class Vector
{
protected:
void** data; //поле данных
int top,step; //верхняя граница и шаг роста
public:
//конструктор принимает аргументы: начальный размер вектора и шаг роста
Vector(int top = 10, int step = 10):top(top),step(step)
{
data = (void**)malloc(top*sizeof(void*));
memset(data,0,top*sizeof(void*)); //сброс всех данных в ноль
}
~Vector()
{
free(data);
}
void* GetAt(int n)
{
if (n>-1 && n<top) return data[n];
return NULL; //если данные за допустимым диапазоном
}
bool SetAt(int n, void* element)
{
if (n>=top) //рост массива если вышли за границы
{
int oldtop = top;
while((top+=step)<=n);
void **tdata = (void**)malloc(top*sizeof(void*));
if (tdata == NULL) return false;
memcpy(tdata,data,oldtop*sizeof(void*));
memset(tdata+oldtop,0,(top-oldtop)*sizeof(void*));
free(data);
data = tdata;
}
*(data+n) = element;
return true;
}
int Count() {return top;} //верхняя граница
};
Примеры программ
Половинное деление
int Find(int *array, int size, int x)
{
int a = 0,b = size-1,t;
do
{
t = (b+a)/2;
if (m[t] == x)return t;
if (m[t]>x) b = t;
else a = t;
}while (b-a>1);
if (m[a] == x) return a;
if (m[b] == x) return b;
return -1;
}
Сортировка пузырьком
int t;
char flag;
do
{
flag = 0;
for(int i=0;i<N-1-i;i++)
if (m[i]>m[i+1]) {t=m[i];m[i]=m[i+1];m[i+1]=t;flag=1;}
}while(flag)
Обход дерева
struct Node
{
Node *parent,*left,*right;
};
void Action(Node *node)
{
if (node == NULL) return;
//action;
Action(node->left);
Action(node->right);
}
void Action2(Node *node)
{
queue<Node*> q;
q.push(node);
do
{
node = q.front();
q.pop();
//action
if (node->left!=NULL) q.push(node->left);
if (node->right!=NULL) q.push(node->right);
}
while(!q.empty) // action
}
size_t first = 0; /* Номер первого элемента в массиве */
size_t last = n; /* Номер элемента в массиве, СЛЕДУЮЩЕГО ЗА последним */
/* Если просматриваемый участок непустой, first<last */
size_t mid;
if (n == 0)
{
/* массив пуст */
}
else if (a[0] > x)
{
/* не найдено; если вам надо вставить его со сдвигом - то в позицию 0 */
}
else if (a[n - 1] < x)
{
/* не найдено; если вам надо вставить его со сдвигом - то в позицию n */
}
while (first < last)
{
/* ВНИМАНИЕ! В отличие от более простого (first+last)/2, этот код стоек к переполнениям.
Если first и last знаковые, возможен код (unsigned)(first+last) >> 1. */
mid = first + (last - first) / 2;
if (x <= a[mid])
{
last = mid;
}
else
{
first = mid + 1;
}
}
/* Если условный оператор if(n==0) и т.д. в начале опущен - значит, тут раскомментировать! */
if (/* last<n &&*/ a[last] == x)
{
/* Искомый элемент найден. last - искомый индекс */
} else
{
/* Искомый элемент не найден. Но если вам вдруг надо его вставить со сдвигом, то его место - last. */
}
