Скачиваний:
89
Добавлен:
10.05.2014
Размер:
37.85 Кб
Скачать

Стек-вектор

SP - индекс элемента вектора

n - длина вектора

тип stack[n];

В приведенных ниже примерах вершина стека определяет элемент стека, доступный для записи.

// запись в стек

intpush(типel){

if(SP< n){

stack[SP++] = el;

return 1;

} else

return 0;

}

// чтение из стека

intpop(тип *el){

if(SP > 0){

*el = stack[--SP];

} else

return 0;

}

Очередь-вектор

TypeQue[QSIZE];/* очередь */

intj = 0,/* индекс начала очереди */

k = 0,/* индекс конца очереди */

cnt = 0;/* количество запросов, поставленных в очередь */

/* Запись в очередь */

intputQ(Typeel)

{

if(j == k &&cnt)

return -1; /* очередьполна */

Que[k] = el;

k = (k + 1) % QSIZE;

cnt ++;

return 0;

}

/* Чтение из очереди */

intgetQ(Type *el)

{

if(!cnt)

return -1; /* очередьпуста */

*el = Que[j];

j = (j + 1) % QSIZE;

cnt --;

return 0;

}

Стек-список

При отображении стека списком используется линейный односвязный список.

struct Item{

типinfo;

Item * next;

};

Исходное состояние

Item *SP=NULL;

// записьвстек

int push(типel){

Item *tmp = new Item;

if(!tmp) return 0;

temp->info = el;

tmp->next = SP;

SP = tmp;

return 1;

}

// чтениеизстека

int pop(тип *el){

Item *tmp = SP;

if(!tmp) return 0;

SP = SP->next;

*el = tmp->info;

deletetmp;

returntmp;

}

Очередь-список

При отображении стека списком используется линейный односвязный список.

struct Item{

типinfo;

Item * next;

};

Item * first, // начало очереди

*last;// конец очереди

// запись в очередь

intputQ(тип el){

Item *ptr = newItem;

if(!ptr) return -1;

ptr->info = el;

ptr->next = NULL;

if(!first) first = ptr;

else last->next = ptr;

last = prt;

return 0;

}

// чтение из очереди

intgetQ(тип *el){

Item *ptr = first;

if(!first) return -1;

*el = first->info;

first = first->next;

delete(ptr);

if(!first) last = NULL;

return 0;

}

При отображении очереди циклическим односвязным списком достаточно иметь один указатель – на последний элемент очереди (last). Первый элемент очереди (циклического списка) будет определяться ее последним элементом; это означает, что указателем на начало очереди будет являться поле next последнего элемента списка, т.е., last->next.

struct Item{

типinfo;

Item * next;

};

Item*last;// конец очереди

// запись в очередь

intputQ(типel){

Item *ptr = new Item;

if(!ptr) return -1;

ptr->info = el;

if(!last)

ptr->next = ptr;

else{

ptr->next = last->next;

last->next = prt;

}

last = prt;

return 0;

}

//чтениеизочереди

intgetQ(тип *el){

Item *ptr;

if(!last) return -1;

ptr = last->next;

*el = prt->info;

if(last = ptr) /*прочитан последний элемент*/

last = NULL;

else

last->next = ptr->next;

deleteptr;

return 0;

}

Просматриваемаятаблица-вектор

struct Item{

int key;

Type info;

};

constintM = 100; /* максимальный размер таблицы */

Память под такую таблицу может быть выделена и статически, и динамически:

Itemtable[M]; // статическое выделение памяти

Item *table = newItem[M]; // динамическое выделение памяти

Статическая просматриваемая таблица-вектор

Для статической просматриваемой таблицы определена только операция поиска элемента. Реализация алгоритма поиска элемента не вызывает затруднений и может быть такой:

intsearch(int k){

inti;

for(i = 0; i< M && table[i].key != k; i++);

return (i<M ? i : -1);

}

Динамическая просматриваемая таблица-вектор

constintM = 20; // Максимальный размер таблицы

struct Item{

int busy; //полезанятости

int key; //ключ

Type info; // информация

};

Item table[M];

int n = 0; // текущий размер таблицы

/* поиск элемента в таблице */

int search(int k){

inti;

for(i = 0; i< n; i++)

if(table[i].busy && table[i].key == k)

returni; /* элемент найден – он занят и имеет искомый ключ */

return-1; /* элемент не найден */

}

/* удаление элемента */

int del(int k){

int l;

if((l = search(k)) < 0)

return-1; /* указанного элемента в таблице нет */

table[l].busy= 0; /* "удаление" элемента */

return0;

}

/* "сборкамусора" */

int garbage()

{

inti, cur = n;

n = 0;

for(i = 0; i< cur; i++)

if(table[i].busy){ /* элементзанят */

if(i != n) /* элемент должен быть перемещен */

table[n] = table[i]; /* перемещение элемента */

n++;

}

returnn== M ? -1 : 0; /* в таблице нет свободного места */

}

/* включение нового элемента в таблицу */

int insert(int k, Type in){

if(search(k) >= 0)

return -1; /* в таблице есть элемент с заданным ключом */

if(n== M) /* в конце таблицы нет свободной позиции */

if(garbage() < 0) /* "сборка мусора" */

return-2; /* в таблице нет свободной позиции */

/* включение нового элемента в таблицу */

table[n].busy = 1;

table[n].key = k;

table[n++].info = in;

return 0;

}

Просматриваемаятаблица-список

structItem{

int key;

Type info;

structItem *next;

};

/* вставка в начало списка, как стек */

Item *ptab; /* указатель на начало таблицы */

int del1(int k)

{

Item *cur, *prev;

cur = ptab;

/* проверяем, есть ли в таблице элементы */

if(!cur)

return -1; /* таблица пуста – отказ */

/* возможно, требуется удалить первый элемент таблицы */

if(cur->key == k){

/* удаляем первый элемент */

ptab = cur->next;

delete cur;

return 0;

}

/* ищем удаляемый элемент среди других элементов таблицы */

while(cur->next){ /* есть другие элементы */

prev = cur;

cur = cur->next;

if(cur->key == k){

/* нашли элемент, который надо удалить */

prev->next = cur->next;

delete cur;

return 0;

}

}

/* естественный выход из цикла – в таблице нет элемента с ключомk */

return -1;

}

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

structItem{

intkey;

Type info;

structItem *next;

};

Item *ptab; /* указатель на начало таблицы */

int del2(int k)

{

Item *cur, **pptr;

pptr = &ptab; /* указатель на указатель на первый элемент таблицы */

/* ищем удаляемый элемент среди всех элементов таблицы */

while(*pptr){ /* еще есть элементы */

if((*pptr)->key == k){

/* нашли элемент, который надо удалить */

cur = *pptr; /* указатель на удаляемый элемент */

*pptr = cur->next;

Delete cur;

return 0;

}

/* продвигаемся к следующему элементу таблицы */

pptr = &(*pptr)->next;

}

/* естественный выход из цикла – в таблице нет элемента с ключомk */

return-1;

}