Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
DSD_Spiskovye_struktury_dannykh_na_baze_massivo...doc
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
3 Мб
Скачать
☆

2.1.15Функция удаления элемента из отсортированного списка

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

При удалении элемента из списка следует различать два случая – удаляемый элемент является последним элементом списка и удаляемый элемент находится в начале или внутри списка.

Если позиция удаляемого элемента списка находится в конце списка, т.е. в элементе массива указателей с индексом CountElmList - 1, то удаление элемента требует только освобождения памяти, занимаемой этим элементом списка и, желательно, корректировки значения указателя.

Если удаляемый элемент оказывается не последним в списке и располагается на позиции J, то все указатели в массиве указателей, начиная с указателя в позиции J+1 и до CountElmList - 1, смещаются на одну позицию вниз.

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

Функция удаления элемента списка в качестве параметров получает позицию 1-го байта массива указателей на элементы списка, реальное количество элементов списка,ключ удаляемого элемента списка, адрес начала списка дыр.

void DelElmSortList (TFile &f, int Start_list, int &CntElmList, char* DelKey, int

&Head_Hole)

{

TElmArrPtrFile PtrElmLst; /*указатель на элемент списка*/

int IndPtrDelEl; /*индекс указателя на удаляемый

элемент в массиве указателей*/

int PosDelEl; /*позиция удаляемого элемента в файле*/

bool FindOK;

if (CntElmList == 0)

{return;}

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

мент в массиве указателей*/

FindOK = FindElSortList2 (f, Start_list, CntElmList, DelKey, IndPtrDelEl);

/*анализ результатов поиска*/

if (!FindOK) /*Элемент не найден. Выход из функции*/

{return;}

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

fseek (f, Start_list + IndPtrDelEl * sizeof(PtrElmLst), SEEK_SET);

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

fread (&PosDelEl, sizeof(PosDelEl), 1, f); /*чтение позиции удаляемого

элемента*/

DisposeElList (f, PosDelEl, Head_Hole); /*занесение удаляемого элемента

в список дыр*/

/*удаление указателя на найденный элемент из массива указателей*/

/*сдвиг всех элементов массива, начиная со следующего за

удаляемым и до последнего*/

for (int K = IndPtrDelEl + 1; K < CntElmList; K++)

{

/*Читаем К-й элемент в массиве указателей и сдвигаем его на к-1 - й*/

fseek (f, Start_list + K * sizeof(PtrElmLst), SEEK_SET);

fread (&PtrElmLst, sizeof(PtrElmLst), 1, f);

fseek (f, Start_list + (K-1)*sizeof(PtrElmLst), SEEK_SET);

fwrite (&PtrElmLst, sizeof(PtrElmLst), 1, f);

}

/*корректировка счетчика реальных элементов списка*/

CntElmList--;

ChangeCntElmList (f , CntElmList);

} /*DelElmSortList*/

2.1.16Функция удаления списка

Функция удаляет все элементы списка и соответствующим образом пополняет список дыр.

Функция в качестве параметра получает позицию начала (1-го байта) массива указателей на элементы списка, реальное количество элементов списка и значение заголовка списка дыр.

void DelList (TFile &f, int Start_list, int &CntElmList, int &HeadHole)

{

TElmArrPtrFile PtrElmLst; /*указатель на элемент списка*/

int PosPtrDelEl; /*позиция указателя на удаляемый

элемент в массиве указателей*/

int PosDelEl; /*позиция удаляемого элемента*/

if (CntElmList == 0)

{return;}

PosPtrDelEl = Start_list; /*начальная позиция указателя на

удаляемый элемент списка*/

for (int K = 0; K < CntElmList; K++)

{

/*чтение указателя на удаляемый элемент списка*/

fseek (f, PosPtrDelEl, SEEK_SET); /*позиционирование на указа-

тель на удаляемый элмент*/

fread (&PosDelEl, sizeof(PosDelEl), 1, f); /*чтение позиции

удаляемого элемента*/

DisposeElList (f, PosDelEl, HeadHole); /*занесение удаляемого

элемента в список дыр*/

fseek (f, PosPtrDelEl, SEEK_SET); /*позиционирование на указатель

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

/*"обнуление" указателя на удаляемый элемент*/

PtrElmLst = -1;

fwrite (&PtrElmLst, sizeof(PtrElmLst),1 , f);

/*позиционирование на указатель на следующий

удаляемый элемент списка*/

PosPtrDelEl = PosPtrDelEl + sizeof(PtrElmLst);

}

/*корректировка счетчика реальных элементов списка*/

CntElmList = 0;

ChangeCntElmList (f, CntElmList);

} /*DelList*/