Список в классах - C (СИ)

Узнай цену своей работы

Формулировка задачи:

Здравствуйте всем. Нужно было написать программу на С++ и на С++ в классах, которая вставляет заданный элемент в однонаправленный список до и после элемента с минимальным ключом, т.е. например, вводим такой список 3 24 6 5 4 1 2 5 98 и вводим элемент 101, должно получиться 3 24 6 5 4 101 1 101 2 5 98. Так вот, на С++ программа работает вроде нормально, а на С++ с классами неправильно вставляет заданный элемент. Помогите исправить код программы в классах, чтобы она работала корректно. Ниже код работающей программы на языке С++:
#include <iostream.h>
#include <conio.h>
 
struct Node
{Node() {}
 Node(int k) { key = k; }
 int key;
 Node* next;
};
 
//добавить узел в конец списка
Node* Append(Node* base, int key)
{base->next = new Node(key);
 base = base->next;
 base->next = NULL;
 return base;
}
 
//вывод списка на экран
void Print(const Node* head)
{if (!head) return;
 cout << head->key << " ";
 Print(head->next);
}
 
//найти узел с минимальным ключом
Node* FindMin(Node *head)
{Node* ptr = head;
 Node* minNode = head;
 while (ptr -> next)
  {
   ptr = ptr -> next;
   if (ptr -> key < minNode -> key)
    {
     minNode = ptr;
    }
  }
 return minNode;
}
 
// вставка элемента Е до и после узла с минимальным ключом
Node* Insert(Node* head, Node* min, int key)
{//добавить после
 Node* nodeAfterMin = min -> next;
 Node* newNode_1 = new Node(key);  // новый узел после узла min
 newNode_1 -> next = nodeAfterMin;
 min -> next = newNode_1;
 //найти предыдущий элемент
 Node* ptr = head;
 while (ptr -> next != min)
 {
  if (ptr == min)
   {//если первый элемент
    Node* tempHead = head;
    Node* newNode_2 = new Node(key);
    newNode_2 -> next = tempHead;
    head = newNode_2;
    return head;
   }
  if (ptr -> next == NULL)
   {
    Node* newNode_2 = new Node(key);
    ptr -> next = newNode_2;
    newNode_2 -> next = NULL;
    break;
   }
  ptr = ptr->next;
 }
 //добавить до
 Node* nodeBeforeMin = ptr;
 ptr = NULL;
 Node* newNode_2 = new Node(key);
 nodeBeforeMin -> next = newNode_2;
 newNode_2 -> next = min;
 return head;
}
 
void main()
{clrscr();
 Node *ptr, *head;
 int key;
 head = ptr = new Node;
 cout << "Введите элементы списка, в конце нажать Ctrl+Z: \n";
 cin >> ptr->key;
 while (cin >> key)
 {
  ptr = Append(ptr, key);
 }
 cout << "Список: \n";
 Print(head);
 cin.clear();
 getch();
 int E = 0;
 cout << "\nВведите ключи: \n";
 cin >> E;
 Node* minNode = FindMin(head);
 head = Insert(head, minNode, E);
 cout << "Новый список: \n";
 Print(head);
 getch();
}
А вот на С++ в классах:
#include <iostream.h>
#include <stddef.h>
#include <conio.h>
 
struct Node
{
        int key;        // ключ узла списка
        Node *link;   //ссылка на узел списка
};
 
typedef Node* NodePtr; //тип - указатeль на узел списка
 
class LIST//класс LIST
{
        public://в разделе находяться ф-ии доступные пользователю
                LIST();//конструктор
                ~LIST();//деструктор - удаляет лист
                void createlist();//ф-я создания списка
                void outlist();//вывод списка на экраy
                void insertE();
                void moveE();
 
        private://ф-ии доступные только ф-ям данного класса
 
                NodePtr p,head,w;
                int E;
                void make(int key);//создание спика

};
 
LIST::LIST()
{
        p=head=NULL;
}
 
LIST::~LIST()
{
        while(head)
        {
                p=head->link;
                delete head;
                head=p;
        }
}

void main()
{LIST mylist;
 clrscr();
 cout<<"Введитe E: ";
 mylist.moveE();
 cout<<"\nВведите список! В конце списка Ctrl+z: \n";
 mylist.createlist();
 cout<<"\nИсходный список: ";
 mylist.outlist();
 cout<<"\nРезультат: ";
 mylist.insertE();
 mylist.outlist();
 getch();
}
 
void LIST::moveE()
{
  cin >> E;
}
 
void LIST::insertE()
{p=head;
 while ( p->link != NULL )  //если есть след элемент
  {if ( p->key < p->link->key )  //если текущ элем меньше след
    {
     w = new Node;
     w->key=E;
     w->link=p->link;
     p->link=w;
    }
   p=p->link;
  }
}
 
void LIST::outlist()
{p=head;
  while(p!=NULL)
        {
         cout<<p->key<<' ';
         p=p->link;
        }
}
 
void LIST::createlist()
{
        int key;
        while(cin>>key)
        {
                make(key);
        }
}
 
void LIST::make(int key)
{p=new Node;
 p->key=key;
 head=p;
 while(cin>>key)
   {
        p->link=new Node;
        p=p->link;
        p->key=key;
   }
 p->link=NULL;
}
А ещё нужно написать эту же программу на С++ в классах с перегрузкой операций в нескольких местах (например, вывод,...) и наследованием. У меня не получается разобраться самостоятельно((

Решение задачи: «Список в классах»

textual
Листинг программы
#include <iostream.h>
#include <time.h>
#include <stdlib.h>
 
 
typedef int Tp;
 
// базовый класс элемента списка
struct NodeBase {
  NodeBase() : next(this) {}
  NodeBase(NodeBase *next_node) : next(next_node) {}
  NodeBase *next;
};
 
// элемент списка
struct Node : NodeBase {
  Tp value;
  Node(NodeBase *after, Tp node_value)
    : NodeBase(after->next), value(node_value) {
    after->next = this;
  }
};
 
// класс особенного односвязного списка
class SpecialList {
 public:
  typedef Node NodeType;
  SpecialList() : first_(), least_(&first_) {}
  ~SpecialList() {
    clear();
  }
  // вставка нового элемента перед минимальным
  void insertAfterLeast(Tp value) {
    NodeType *node = new NodeType(least_, value);
    if ((least_ == &first_) ||
      (static_cast<NodeType*>(least_)->value >= value)) {
      least_ = node;
    }
  }
  // удаление односвязного списка
  void clear() {
    NodeBase *node = first_.next;
    while (node != &first_) {
      first_.next = node->next;
      delete node;
      node = first_.next;
    }
    least_ = &first_;
  }
  // перегруженный оператор вывода
  friend std::ostream &operator<<(std::ostream &stream, const SpecialList &list) {
    NodeBase *node = list.first_.next;
    while (node != &(list.first_)) {
      stream << static_cast<NodeType*>(node)->value << " ";
      node = node->next;
    }
    return stream;
  }
 private:
  NodeBase first_;     // элемент списка, стоящий перед первым и
                       // после последнего
  NodeBase *least_;  // указатель на ноду минимального элемента списка
};
 
int main(int argc, char *argv[]) {
  srand(time(NULL));
  SpecialList list;
  for (int i = 0; i < 10; ++i) {
    // случайное число
    int value = rand() % 10;
    // вывод числа
    std::cout << value << " ";
    // добавление числа в список
    list.insertAfterLeast(value);
  }
  // вывод списка
  std::cout << std::endl << list << std::endl;
}

Объяснение кода листинга программы

  1. Объявление и инициализация первых двух структур классов NodeBase и Node.
  2. Создание специализированного класса для односвязного списка с именем SpecialList.
  3. В классе SpecialList:
    • Создание конструктора и деструктора.
    • Создание методов для вставки нового элемента после наименьшего (insertAfterLeast) и очистки списка (clear).
    • Перегрузка оператора вывода << для вывода списка на экран.
    • Приватные переменные first и least для хранения первого и наименьшего элементов списка.
  4. В функции main:
    • Инициализация генератора случайных чисел.
    • Создание экземпляра класса SpecialList.
    • Цикл for для создания и вставки 10 случайных чисел в список.
    • Вывод списка на экран.

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

11   голосов , оценка 4.091 из 5
Похожие ответы