Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 23.02.2009, 17:37   #1
Blade
Software Engineer
Участник клуба
 
Аватар для Blade
 
Регистрация: 07.04.2007
Сообщений: 1,618
По умолчанию Реализация однонаправленного шаблонного связанного списка

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

Реализация самого списка:
Код:
template <typename T> class list
{
private:
	class node //Класс node содержит данные списка
	{
		friend class list<T>;
	private:
		node *next; //Указатель на следующий элемент в списке
		T val; //Данные списка

		node(): next(NULL){}
		~node(){}
	};

	node *head; //Указатель на начало списка
	int count; //Количество элементов в списке
public:
	list(): head(NULL), count(0){}
	~list()
	{
		clear(); //Функция освобождает память, используемую для хранения списка
	}
	int getCount() const //Возвращает количество элементов в списке
	{
		return count;
	}
	
	int add(T data)//Добавление элемента в конец списка. Возвращает количество элементов в списке
	{
		node *to_add = new node;
		to_add->next=NULL;
		to_add->val=data;
		if(head==NULL) //Если в списке нет элементов
			head=to_add;
		else
		{
			node *current;
			for(current=head;current->next!=0;current=current->next);
			current->next=to_add;
		}
		count++;
		return count;
	}

	int del(int x) //Удаление элемента из списка. Возвращает количество элементов в списке. 
	{			   //Возвращает -1, если произошла ошибка
		if (x>count) return -1;
		node *to_del=head;
		if (x==1) //Если нужно удалить первый элемент
		{
			head=head->next;
			delete to_del;
		}
		else
		{
			node *current=head;
			for(int i=1;i<x-1;i++)
				current=current->next;
			to_del=current->next;
			current->next=current->next->next;
			delete to_del;
		}
		count--;
		return count;
	}
	
	void clear() //Очистка списка
	{
		node *current = head;
		node *to_del = head;
		while(to_del!=NULL)
		{
			current=current->next;
			delete to_del;
			to_del=current;
		}
		head=NULL;
		count=0;
	}
	
	T getData(int x) const //Возвращает данные из списка.
	{
		node *current;
		for(current=head;x>1;x--)
			current=current->next;
		return current->val;
	}
};

Пример использования списка:
Код:
#include <iostream>
#include "list.h"
using namespace std;

int main()
{
	list<int> my_list; //Пример использования списка с типом int
	
	my_list.add(-9);	
	for(int i=0;i<5;i++)
		my_list.add(i);	
	my_list.add(54);
	
	cout << my_list.getCount() << endl;	
	for(int i=1;i<=my_list.getCount();i++)
		cout << my_list.getData(i) << " ";
	cout << endl;

	my_list.del(1);
	my_list.del(3);
	my_list.del(5);	

	cout << endl;
	cout << my_list.getCount() << endl;
	for(int i=1;i<=my_list.getCount();i++)
		cout << my_list.getData(i) << " ";
	cout << endl;

	my_list.clear();

	struct my_type
	{
		int x;
		double y;
	};

	list<my_type> my_list_2; //Пример использования списка с типом, определенным пользователем

	for(int i=1;i<=5;i++)
	{
		my_type *point = new my_type;
		point->x=i;
		point->y=i+0.2;
		my_list_2.add(*point);
	}

	cout << endl << my_list_2.getCount() << endl;
	for(int i=1;i<=my_list_2.getCount();i++)
		cout << my_list_2.getData(i).x << " " << my_list_2.getData(i).y << endl;

	my_list_2.del(3);
	my_list_2.del(1);

	cout << endl << my_list_2.getCount() << endl;
	for(int i=1;i<=my_list_2.getCount();i++)
		cout << my_list_2.getData(i).x << " " << my_list_2.getData(i).y << endl;

	my_list_2.clear();
	return 0;
}
В дальнейшем планирую реализовать доступ к списку, как к элементам массива (операция []), а так же обработку исключительных ситуаций при не хватке памяти и при попытки доступа к несуществующим данным.
Спасибо за внимание Жду комментариев.

P.S Основа примера взята из книги C/C++. Архив программ
Мужество есть лишь у тех, кто ощутил сердцем страх, кто смотрит в пропасть, но смотрит с гордостью в глазах. (с) Ария
Blade вне форума Ответить с цитированием
Старый 23.02.2009, 18:40   #2
ISergeyN
Maniac
Форумчанин
 
Аватар для ISergeyN
 
Регистрация: 03.01.2009
Сообщений: 450
По умолчанию

Вместо
Код:
T getData(int x) const //Возвращает данные из списка.
лучше итератор бы сделал.
Стандартные библиотеки разработаны с учетом многолетнего опыта лучших программистов и они не больны "детскими болезнями крутизны в программизме"....
ISergeyN вне форума Ответить с цитированием
Старый 23.02.2009, 19:14   #3
MaTBeu
Eclipse Foundation
Старожил
 
Аватар для MaTBeu
 
Регистрация: 19.09.2007
Сообщений: 2,604
По умолчанию

Напиши конструктор для класса node, чтобы не писать
Код:
node *to_add = new node;
		to_add->next=NULL;
		to_add->val=data;
будет писать
Код:
node *to_add = new node(data);
а внутри конструктора зануляй уже все указатели и присваивай значения.
Кстати, для строк твой список не покатит. Потому что строки копируются при помощи strcpy, поэтому следует написать реализацию добавления отдельно для строк.
MaTBeu вне форума Ответить с цитированием
Старый 24.02.2009, 00:53   #4
Blade
Software Engineer
Участник клуба
 
Аватар для Blade
 
Регистрация: 07.04.2007
Сообщений: 1,618
По умолчанию

Спасибо, учту.

ISergeyN, что такое "интератор"? =)
Мужество есть лишь у тех, кто ощутил сердцем страх, кто смотрит в пропасть, но смотрит с гордостью в глазах. (с) Ария
Blade вне форума Ответить с цитированием
Старый 24.02.2009, 04:44   #5
ISergeyN
Maniac
Форумчанин
 
Аватар для ISergeyN
 
Регистрация: 03.01.2009
Сообщений: 450
По умолчанию

как в stl-e список организован видел? тоесть
Код:
#include <iostream>
#include <list>

using namespace std;

int main()
{
	list<int> lis;
	lis.push_back(1);
	lis.push_back(5);
	lis.push_back(6);

	list<int>::iterator it;//итератор

	for(it = lis.begin(); it != lis.end(); ++it)
		cout<<*it<<endl;

	return 0;
}
красивее чем
Код:
//-------------------------------------
for(int i=1;i<=my_list_2.getCount();i++)
		cout << my_list_2.getData(i).x << " " << my_list_2.getData(i).y << endl;
//-------------------------------------
хотя каждому на свой цвет и вкус. (!!все это только мое мнение)
Стандартные библиотеки разработаны с учетом многолетнего опыта лучших программистов и они не больны "детскими болезнями крутизны в программизме"....
ISergeyN вне форума Ответить с цитированием
Старый 24.02.2009, 12:06   #6
Blade
Software Engineer
Участник клуба
 
Аватар для Blade
 
Регистрация: 07.04.2007
Сообщений: 1,618
По умолчанию

Ясно. Ну это, как я понимаю, сделано для того, чтобы случайно не вылезти за границы списка... мне это не нужно, я так думаю =))
Мужество есть лишь у тех, кто ощутил сердцем страх, кто смотрит в пропасть, но смотрит с гордостью в глазах. (с) Ария
Blade вне форума Ответить с цитированием
Старый 24.02.2009, 18:23   #7
MaTBeu
Eclipse Foundation
Старожил
 
Аватар для MaTBeu
 
Регистрация: 19.09.2007
Сообщений: 2,604
По умолчанию

Цитата:
Сообщение от Blade Посмотреть сообщение
Ясно. Ну это, как я понимаю, сделано для того, чтобы случайно не вылезти за границы списка... мне это не нужно, я так думаю =))
Нет, просто есть классы-контейнеры, которые умеют только хранить в себе информацию, ну там добавлять удалять и так далее. А есть классы итераторы - которые "ходят" по контейнерам. Тоесть получить доступ к информации в контейнере можно только через итератор. Допустим вывод содержимого контейнера - через итератор.
MaTBeu вне форума Ответить с цитированием
Старый 24.02.2009, 18:50   #8
Blade
Software Engineer
Участник клуба
 
Аватар для Blade
 
Регистрация: 07.04.2007
Сообщений: 1,618
По умолчанию

Ясно. Но у меня же класс не контейнер, ибо можно получить доступ к данным через функции самого класса, значит и интератор не нужен, так?
Мужество есть лишь у тех, кто ощутил сердцем страх, кто смотрит в пропасть, но смотрит с гордостью в глазах. (с) Ария
Blade вне форума Ответить с цитированием
Старый 24.02.2009, 20:45   #9
MaTBeu
Eclipse Foundation
Старожил
 
Аватар для MaTBeu
 
Регистрация: 19.09.2007
Сообщений: 2,604
По умолчанию

Ну посмотрите - чтобы освоить все функции вашего класса, нужно знать все функции, а они по названиям отличаются от стандартных. Поэтому начинающий программер врядли быстро освоит ваш список. По сравнению с stl-овским списком ваш немного сложноват.
Да и не для всех типов он подойдет. К тому же у вас нет никакой обработки данных в списке.
MaTBeu вне форума Ответить с цитированием
Старый 24.02.2009, 22:04   #10
Blade
Software Engineer
Участник клуба
 
Аватар для Blade
 
Регистрация: 07.04.2007
Сообщений: 1,618
По умолчанию

А какую обработку данных можно сделать? Сортировку не получится, ибо список чаще всего будет использоваться для хранения структур, а рассмотреть все возможные структуры в списке, естественно, невозможно. Позже добавлю возможность сохранять и загружать список из файл, это будет полезная функция
И еще есть идея реализовать этот список как DLL, что бы использовать его в программах на Си. Возможно ли это будет сделать и вообще, стоит ли оно того? Проще наверно просто переписать его под Си, но с DLL интереснее =))
Мужество есть лишь у тех, кто ощутил сердцем страх, кто смотрит в пропасть, но смотрит с гордостью в глазах. (с) Ария

Последний раз редактировалось Blade; 24.02.2009 в 22:06.
Blade вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Программная реализация однонаправленного линейного списка Денис Ст Помощь студентам 2 14.01.2014 21:50
С++ перегрузка операций для шаблонного класса TIN Помощь студентам 7 29.03.2009 15:24
Загрузка связанного списка из файла (Си) Blade Общие вопросы C/C++ 4 14.12.2008 15:00
Ctrl+Z реализация delphin100 Общие вопросы Delphi 6 10.09.2008 06:59
помогите удалить элемент из связанного списка kermit Помощь студентам 5 13.06.2008 10:14