Консультация № 145313
28.09.2008, 16:43
0.00 руб.
0 1 1
Здравствуйте уважаемые эксперты! Помогите, пожалуйста, с реализацией такой программы.
Необходимо реализовать на языке C++ следующий набор операций с двусвязным линейным списком:
• инициализация списка;
• уничтожение списка с освобождением памяти;
• добавление узла в голову списка;
• добавление узла в хвост списка;
• удаление узла из головы списка;
• удаление узла из хвоста списка;
• выдача текущего списка на экран
• добавить новый узел в указанную позицию;
• поменять местами первый и последний узлы.

Обсуждение

Неизвестный
29.09.2008, 20:08
общий
это ответ

Здравствуйте, [b]Borman Karlovich[/b]!

В приложении находится пример подобной реализации (сохраните в файл с именем dllist.h). Список выполнен в виде шаблона класса. Пример использования шаблона:
Код:
#include <iostream>
#include "dllist.h"

using std::cout;
using std::endl;

int main()
{
// Список целых чисел (int)
DLList<int> list;

int i;
// Вставка 5 элементов в конец списка
for (i = 1; i <= 5; ++i) list.push_back(i);

// Вставка 5 элементов в начало списка
for (i = -1; i >= -5; --i) list.push_front(i);
// Вставка в позицию с номером 5 (нумерация от нуля)
list.insert(5, 6);
// Вывод списка
list.print(cout); cout << endl;

// Удаление элемента из начала списка
list.pop_front();
// Проверка
list.print(cout); cout << endl;
// Удаление из конца списка
list.pop_back();
// Проверка
list.print(cout); cout << endl;
// Меняем первый и последний элементы местами
list.swapFrontBack();
// Доступ к элементам списка по индексу
list[4] = 100;
list.print(cout);
// Размер списка
cout << "\nSize: " << list.size() << endl;

return 0;
}


Список выполняемых классом DLList<T> операций:
• инициализация списка;
- конструктор (выполняется автоматически, при создании объекта)
• уничтожение списка с освобождением памяти;
- деструктор (автоматически, при удалении объекта)
• добавление узла в голову списка;
- void push_front(...)
• добавление узла в хвост списка;
void push_back(...)
• удаление узла из головы списка;
- T pop_front()
• удаление узла из хвоста списка;
- T pop_back()
• выдача текущего списка на экран
- void print(...)
• добавить новый узел в указанную позицию;
- void insert(...)
• поменять местами первый и последний узлы.
- void swapFrontBack()

Удачи!

Приложение:
// dllist.h

#ifndef DLLIST_H
#define DLLIST_H

#include <ostream>

// Interface of DLList
template <typename T>
class DLList
{
public:
// Инициализация списка
DLList():__counter(0)
{
__start = __end = new __dllnode;
if (!__start) throw;
};
// Удаление списка (с освобождением памяти)
~DLList();

class EOutOfIndex{};

// Вставка в конец списка
void push_back(const T &anItem) { __insert(__end, anItem); };
// Удаление из конца списка
T pop_back();
// Вставка в начало списка
void push_front(const T &anItem) { __insert(__start, anItem); };
// Удаление из начала списка
T pop_front();
// Вставка в определенную позицию
void insert(const int&, const T&);
// Размер списка
int size() const { return __counter; };
// Вывод списка в поток
void print(std::ostream&, const char* = ", ") const;
// Обмен между первым и последним элементами
void swapFrontBack();
// Доступ к элементам
T& operator[](const int&);
const T& operator[](const int&) const;
private:
class __dllnode
{
private:
__dllnode *__next, *__prev;
T *__value;
public:
__dllnode(): __next(0), __prev(0), __value(0) { };
explicit __dllnode(const T &aValue): __next(0), __prev(0)
{
__value = new (T)(aValue);
if (!__value) throw;
};
~__dllnode() { if (__value) delete __value; };

__dllnode* next() const { return __next; };
void setNext(__dllnode *aNode)
{
__next = aNode;
if (__next) __next->__prev = this;
};

__dllnode* prev() const { return __prev; };
void setPrev(__dllnode *aNode)
{
__prev = aNode;
if (__prev) __prev->__next = this;
};

__dllnode* insert(__dllnode *newNode)
{
newNode->__prev = __prev;
newNode->__next = this;
if (__prev) __prev->__next = newNode;
__prev = newNode;
return newNode;
};
T& value() const { return *__value; };
void setValue(const T &aValue) { *__value = aValue; };
void swap(__dllnode *aNode)
{
if ((aNode == this) || !aNode) return;
T *temp = __value;
__value = aNode->__value;
aNode->__value = temp;
};
};
__dllnode *__start, *__end;
void __delete_item(__dllnode*) throw (EOutOfIndex);
int __counter;
void __insert(__dllnode*, const T&);
};

// Implementation of DLList
template <typename T>
DLList<T>::~DLList()
{
while (__start)
{
__dllnode *__cur = __start;
__start = __cur->next();
delete __cur;
}
}

template <typename T>
void DLList<T>::__insert(__dllnode *pos, const T &anItem)
{
pos->insert(new __dllnode(anItem));
if (pos == __start) __start = pos->prev();

++__counter;
}

template <typename T>
void DLList<T>::__delete_item(__dllnode *anItem) throw (EOutOfIndex)
{
if (!__counter) throw EOutOfIndex();
if (anItem)
{
if (anItem == __end) throw;

anItem->next()->setPrev(anItem->prev());
if (anItem == __start) __start = anItem->next();
delete anItem;
anItem = NULL;

--__counter;
}
}

template <typename T>
T DLList<T>::pop_back()
{
if (__counter)
{
T temp = __end->prev()->value();
__delete_item(__end->prev());
return temp;
}
throw EOutOfIndex();
}

template <typename T>
T DLList<T>::pop_front()
{
if (__counter)
{
T temp = __start->value();
__delete_item(__start);
return temp;
}
throw EOutOfIndex();
}

template <typename T>
void DLList<T>::insert(const int &pos, const T &anItem)
{
if ((pos > __counter) || (pos < 0)) throw EOutOfIndex();
else if (pos == __counter)
{
push_back(anItem);
return;
}
else
{
int i = 0;
__dllnode *__cur = __start;
while (i < pos)
{
__cur = __cur->next();
++i;
}

__insert(__cur, anItem);
}
}

template <typename T>
void DLList<T>::print(std::ostream &out, const char *delim) const
{
if (!__counter) return;
if (__counter == 1)
{
out << (__start->value());
return;
}
__dllnode *__cur = __start, *__last = __end->prev();
while (__cur != __last)
{
out << (__cur->value()) << delim;
__cur = __cur->next();
}
out << (__cur->value());
}

template <typename T>
void DLList<T>::swapFrontBack()
{
__start->swap(__end->prev());
}

template <typename T>
T& DLList<T>::operator[](const int &pos)
{
if ((pos < 0) || (pos >= __counter)) throw EOutOfIndex();
int i = 0;
__dllnode *__cur;
if (pos < __counter/2)
{
__cur = __start;
while(i < pos)
{
++i;
__cur = __cur->next();
}
}
else
{
i = __counter-1;
__cur = __end->prev();
while (i > pos)
{
--i;
__cur = __cur->prev();
}
}
return __cur->value();
}

template <typename T>
const T& DLList<T>::operator[](const int &pos) const
{
if ((pos < 0) || (pos >= __counter)) throw;
int i = 0;
__dllnode *__cur;
if (pos < __counter/2)
{
__cur = __start;
while(i < pos)
{
++i;
__cur = __cur->next();
}
}
else
{
i = __counter-1;
__cur = __end->prev();
while (i > pos)
{
--i;
__cur = __cur->prev();
}
}
return __cur->value();
}

#endif // DLLIST

Форма ответа