Список в классах - 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; }
Объяснение кода листинга программы
- Объявление и инициализация первых двух структур классов NodeBase и Node.
- Создание специализированного класса для односвязного списка с именем SpecialList.
- В классе SpecialList:
- Создание конструктора и деструктора.
- Создание методов для вставки нового элемента после наименьшего (insertAfterLeast) и очистки списка (clear).
- Перегрузка оператора вывода << для вывода списка на экран.
- Приватные переменные first и least для хранения первого и наименьшего элементов списка.
- В функции main:
- Инициализация генератора случайных чисел.
- Создание экземпляра класса SpecialList.
- Цикл for для создания и вставки 10 случайных чисел в список.
- Вывод списка на экран.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д