Страницы

Поиск по вопросам

среда, 3 апреля 2019 г.

Однонаправленый линейный список

Прошу помощи с заданием. Ввести с клавиатуры предложение и переписать его символы в однонаправленный линейный список.
С помощью этого списка скопировать в другой однонаправленный список K символов, начиная с позиции N. Список:
typedef struct list { char val; struct list *next; } listn, *listp;


Ответ

В С++ не нужны конструкции вида typedef struct X_ {} X, *PX;, вместо этого используется обычная struct X {}; Также в С++ есть конструкторы, поэтому в своем простейшем виде список выглядит так:
struct list { explicit list(char val = 0, list* next = nullptr) : val(val), next(next) {}
char val; list* next; };
У односвязного списка есть две основные операции: 1) добавление элемента в начало
void push_front(list*& list_head, list* new_element) { new_element->next = list_head; list_head = new_element; }
2) и удаление элемента из начала списка
list* pop_front(list*& list_head) { auto element = list_head; if (list_head) list_head = list_head->next; if (element) element->next = nullptr; return element; }
При помощи этих операций можно сделать другие полезные операции, а именно: Чтение списка из потока ввода:
list* read() { list* reversed_list_head = nullptr; char c; while (std::cin >> c) push_front(reversed_list_head, new list(c)); return reversed_list_head; }
Разворот списка:
void reverse(list*& list_head) { list* reversed_list_head = nullptr; while (auto element = pop_front(list_head)) push_front(reversed_list_head, element); list_head = reversed_list_head; }
Печать списка:
std::ostream& operator<<(std::ostream& stream, list* list_head) { for (auto element = list_head; element != nullptr; element = element->next) stream << element->val; return stream; }
Удаление списка:
void free(list* list_head) { while (auto element = pop_front(list_head)) delete element; }
При помощи этих функций можно написать программу:
int main() { auto list_head = read(); reverse(list_head);
Так как элементы всегда добавляются в начало, то при вводе символов с клавиатуры список окажется перевернутым, и его надо перевернуть.
Далее, мы перемещаемся на N символов вперед (или меньше, если список короче):
const auto N = 2; auto list_middle = list_head; for (auto i = 0; i != N && list_middle != nullptr; ++i) list_middle = list_middle->next;
Затем копируем K элементов в новый список (или меньше, если список короче). Т.к. мы всегда вставляем элементы в начало, то копия будет перевернутой, и ее надо будет перевернуть.
const auto K = 3; list* list_copy = nullptr; for (auto i = 0; i != K && list_middle != nullptr; ++i) { push_front(list_copy, new list(list_middle->val)); list_middle = list_middle->next; } reverse(list_copy);
Выводим копию списка на печать:
std::cout << "list copy: " << list_copy << std::endl;
И наконец удаляем оба списка
free(list_copy); free(list_head);
Тут можно посмотреть >>>весь код<<<

Комментариев нет:

Отправить комментарий