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

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

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 04.11.2011, 11:42   #1
Fantom.as
Пользователь
 
Аватар для Fantom.as
 
Регистрация: 19.04.2010
Сообщений: 62
Восклицание Реализация класса множество через двусвязный список.

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

Сам класс список мне реализовать вроде удалось, но стоит загвоздка в том, как реализовать некоторые функции для множества: пересечение множеств (*), объединение множеств(+), и разность множеств (-), поиск заданного элемента, удаление и добавление его.

для пересечение множеств (*), объединение множеств(+), и разность множеств (-) думаю стоит переопределять операции *, + и - соответственно.

пересечение: в новое множество идут только общие элементы двух мн-в.
объединение: в новое мн-во идут все элементы, причем они не должны повторяться.
разность: в новое мн-во идут элементы, которые есть в первом, но нет во втором.

вот что у меня пока реализовано.

//Set_list.h

Код:
//Set_list.h

#pragma once
#ifndef Set_list_h
#define Set_list_h
class Set_list
{
public:
	Set_list(void);
	~Set_list(void);


    void push_begin(int value);				//добавление в начало списка
    void push_end(int value);				//добавление в конец списка

    void print_all();						//печать списка
    void print_all_rev();					//печать списка в обратном порядке
    
    int print_count();						//размерность множества
    void clear();							//очистить список
    bool clear_one(int num);				//удалить элемент
    
    int select(int num);					//вывести элемент


protected:
    struct node
    {
        int data;

        node *next;
        node *prev;

        node(int value, node *n, node *p) : data(value), next(n), prev(p) {}
    };

    node *end;
    node *first;
    int count;

private:
    Set_list(const Set_list & rhs);					//конструктор копирования
    Set_list& operator=(const Set_list & rhs);		//конструктор присваивания
};

#endif
//Set_list.cpp
Код:
//Set_list.cpp

#include "StdAfx.h"
#include "Set_list.h"
#include <iostream>
using namespace std;

Set_list::Set_list(void) : count(0), first(NULL), end(NULL)
{
}


Set_list::~Set_list(void)
{
	clear();
}

/* ------- */
/* ФУНКЦИИ */
/* ------- */

// добавление записи в начало списка
void Set_list::push_begin(int value)
{
    first = new node(value, first, 0);
    
    if(!count)
         end = first;
    
    node *ptr = first->next;
    if(ptr)
         ptr->prev = first;

    count++;
}

// добавление записи в конец списка
void Set_list::push_end(int value)
{
    end = new node(value, NULL, end);
    
    if (!count)
       first = end;
    
    node *ptr = end->prev;
    if (ptr)
       ptr->next = end;

    count++;
}

// печать списка
void Set_list::print_all()
{
    node *ptr = first;
    
    while (ptr)
    {
        cout<<ptr->data<<"\n";
        ptr = ptr->next;
    }
}

// печать списка в обратном порядке
void Set_list::print_all_rev()
{
    node *ptr = end;
    
    while (ptr)
    {
        cout<<ptr->data<<"\n";
        ptr = ptr->prev;
    }
}

// кол-во элементов
int Set_list::print_count()
{
     return count;
}

// выборка элемента по порядковому номеру
int Set_list::select(int num)
{
    if(!count || !num || num>count+1)
         return 0;
    
    int cnt=0;
         
    node *ptr = first;
    
    while (ptr)
    {
         cnt++;
         if (num==cnt)
              return ptr->data;
         ptr = ptr->next;
    }
}

// удаление произвольного элемента
bool Set_list::clear_one(int num)
{
    if(!count || !num || num>count+1)
         return false;
    
    int cnt=0;
         
    node *ptr = first;
    
    while (ptr)
    {
         cnt++;
         if (num==cnt) {
              node *ptr_prev = ptr->prev;
              node *ptr_next = ptr->next;
              
              if(ptr_prev)
                   ptr_prev->next = ptr_next;
              if(ptr_next)
                   ptr_next->prev = ptr_prev;
              
              delete ptr;
              
              count--;
              return true;
         }
         ptr = ptr->next;
    }
}

// удаление всего списка
void Set_list::clear()
{
     while (first)
     {
          node *ptr = first;
          first = ptr->next;
          delete ptr;
     }
     end = first;
     
     count = 0;
}
осталось дописать функции, о которых сказано выше, но я что-то не знаю, как это сделать....
<--<--<--Нажми на весы слева <---<---<---
Fantom.as вне форума Ответить с цитированием
Старый 04.11.2011, 12:22   #2
Fantom.as
Пользователь
 
Аватар для Fantom.as
 
Регистрация: 19.04.2010
Сообщений: 62
По умолчанию

забыл добавить, элементами множества являются целые числа
<--<--<--Нажми на весы слева <---<---<---
Fantom.as вне форума Ответить с цитированием
Старый 04.11.2011, 13:12   #3
Abstraction
Старожил
 
Аватар для Abstraction
 
Регистрация: 25.10.2011
Сообщений: 3,178
По умолчанию

Объединение и пересечение, в случае операторов, лучше задавать как | и &. Тем более что операция произведения множеств тоже существует.

Во-первых, я бы менял интерфейс. У множества идеологически нет "начала" или "конца", а есть операция "добавить элемент в множество" (традиционно возвращающая признак того, был ли там уже такой элемент), аналогичная операции "убрать элемент".
Кроме того, совершенно непонятны причины запрета на копирование-присваивание. Как именно Вы представляете запись пересечения? Я - Set_list c = a&b;
Если сделать так, появляется возможность хранить элементы в списке упорядоченным образом (вообще, как мы что храним внутри класса - дело нас, как разработчиков класса; до тех пор, пока мы выдерживаем заявленный интерфейс, окружающим о подробностях знать необязательно).
Пересечение:
Код:
Set_list operator&(const Set_list& with)const
Создать временный объект под возвращение, идти параллельно по спискам двух пересекаемых множеств "если текущий элемент в первом меньше, чем во втором - шагнуть по первому; если во втором меньше, чем в первом - шагнуть по второму; если равны - занести элемент в "ответ" и шагнуть по обоим, если один из списков кончился - пересечение найдено".
Остальные две операции делаются практически идентично, только заносится в "ответ" элементы будут в другие моменты.
Abstraction вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
реализация стека через односвязный список snusnu Общие вопросы C/C++ 7 06.04.2014 23:59
Множество через двусвязный список. Fantom.as Помощь студентам 0 02.11.2011 20:38
Двусвязный список в виде класса. delphi Rei-li Помощь студентам 5 21.09.2011 02:51
Двусвязный список narcot Visual C++ 13 28.05.2011 21:12
Шаблон класса "Двусвязный список DIMON007 Помощь студентам 0 17.05.2010 17:35