Линейные списки
(1/1)
Sergey1985:
Всем доброго времени суток. Имеется кодик
Код
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
struct Node
{
int d;
Node *next;
Node *prev;
};
//---------------------------------------------------------------------------
Node *first(int d);
void add(Node **pend, int d);
Node *find(Node *const pbeg, int i);
bool remove(Node **pbeg, Node **pend, int key);
Node *insert(Node *const pbeg, int key, int d);
Node *pbeg;
Node *pend;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
// Ôîðìèðîâàíèå ïåðâîãî ýëåìåíòà
Node *first(int d)
{
Node *pv = new Node;
pv->d = d;
pv->next = 0;
pv->prev = 0;
return pv;
}
// Äîáàâëåíèå â êîíåö ñïèñêà
void add(Node **pend, int d)
{
Node *pv = new Node;
pv->d = d;
pv->next = 0;
pv->prev = *pend;
(*pend)->next = pv;
*pend = pv;
}
// Ïîèñê ýëåìåíòà ïî êëþ÷ó
Node *find(Node *const pbeg, int d)
{
Node *pv = pbeg;
while (pv)
{
if (pv->d == d) break;
pv = pv->next;
}
return pv;
}
// Óäàëåíèå ýëåìåíòà
bool remove (Node **pbeg, Node **pend, int key)
{
if (Node *pkey = find(*pbeg, key))
{
if (pkey == *pbeg)
{
*pbeg = (*pbeg)->next;
(*pbeg)->prev = 0;
}
else
if (pkey == *pend)
{
*pend = (*pend)->prev;
(*pend)->next = 0;
}
else
{
(pkey->prev)->next = pkey->next;
(pkey->next)->prev = pkey->prev;
}
delete pkey;
return true;
}
return false;
}
// Âñòàâêà ýëåìåíòà
Node *insert(Node *const pbeg, Node **pend, int key, int d)
{
if (Node *pkey = find(pbeg, key))
{
Node *pv = new Node;
pv->d = d;
// Óñòàíîâëåíèå ñâÿçè íîâîãî óçëà ñ ïîñëåäóþùèì
pv->next = pkey->next;
// Óñòàíîâëåíèå ñâÿçè íîâîãî óçëà ñ ïðåäûäóùèì
pv->prev = pkey;
// Óñòàíîâëåíèå ñâÿçè ïðåäûäóùåãî óçëà ñ íîâûì
pkey->next = pv;
// Óñòàíîâëåíèå ñâÿçè ïîñëåäóþùåãî óçëà ñ íîâûì
if (pkey != *pend)
(pv->prev) = pv;
// Îáíîâëåíèå óêàçàòåëÿ íà êîíåö ñïèñêà
// åñëè óçåë âñòàâëÿåòñÿ â êîíåö
else
*pend = pv;
return pv;
}
return 0;
}
void __fastcall TForm1::Button1Click(TObject *Sender)
{
pbeg = first(1);
pend = pbeg; // ïåðâûé ýëåìåíò ÿâëÿåòñÿ è ïîñëåäíèì
for (int i = 2; i<6; i++)
add(&pend, i);
insert(pbeg, &pend, 2, 200);
if (!remove(&pbeg, &pend, 5))
Memo1->Lines->Add("Íå íàéäåí");
Node *pv = pbeg;
while(pv)
{
Memo1->Lines->Add(IntToStr(pv->d));
pv = pv->next;
}
}
//---------------------------------------------------------------------------
Поясните плиз (у самого видать серого вещества не хватает) как работают вот эти строчки кода
(pkey->prev)->next = pkey->next;
(pkey->next)->prev = pkey->prev;
в функции remove
как вообще возможна такая конструкция (pkey->prev)->next
Sergey1985:
И еще сразу же в дополнении : Зачем в функциях в качестве аргументов использовать не указатели, а указатели на указатели. Это дело вкуса или так работать будет лучше
Hex:
1. присвоение одному указателю значения другого. что не так? и кстати, скобочки можно выкинуть.
2. так в "стиле Си" передают в функцию массив указателей (указатель на указатель). RTFM.
но в данном коде это просто дурь автора и лишние операции внутри функции, реально используется только 1 элемент.
Навигация