Переписать лист в обратном порядке - C (СИ)
Формулировка задачи:
Дан лист, написать программу реверс лист(Обратный порядок).
Решение задачи: «Переписать лист в обратном порядке»
textual
Листинг программы
#include <stdio.h>
#include <malloc.h>
struct node {
struct node* next;
int val;
};
typedef struct {
struct node* head, *tail;
} slist;
void slist_init(slist* lst);
void slist_reverse(slist* lst);
int slist_add(slist* lst, int val);
void slist_clear(slist* lst);
void slist_print(FILE* _out, slist* lst);
int main(void){
int i;
slist lst;
slist_init(&lst);
for(i = 0; i < 10; ++i)
slist_add(&lst, i);
slist_print(stdout, &lst);
slist_reverse(&lst);
slist_print(stdout, &lst);
slist_clear(&lst);
getchar();
return 0;
}
//переворачивание списка
void slist_reverse(slist* lst){
struct node* q, *p = lst->head, *h = NULL, *t = NULL;
while(p != NULL){
q = p;
p = p->next;
if(h == NULL)
h = t = q;
else {
q->next = h;
h = q;
}
}
t->next = NULL;
lst->head = h;
lst->tail = t;
}
//добавление
int slist_add(slist* lst, int val){
struct node* p = (struct node*)malloc(sizeof(struct node));
if(p == NULL)
return 0;
p->val = val;
p->next = NULL;
if(lst->head == NULL)
lst->head = lst->tail = p;
else
lst->tail = lst->tail->next = p;
return 1;
}
//удаление
void slist_clear(slist* lst){
struct node* t;
while(lst->head != NULL){
t = lst->head;
lst->head = lst->head->next;
free(t);
}
lst->tail = NULL;
}
//печать
void slist_print(FILE* _out, slist* lst){
const struct node* p = lst->head;
while(p != NULL){
fprintf(_out, "%d ", p->val);
p = p->next;
}
fputc('\n', _out);
}
void slist_init(slist* lst){
lst->head = lst->tail = NULL;
}
Объяснение кода листинга программы
- Структура данных, используемая в программе, - это связанный список (slist).
- Список содержит элементы типа struct node, каждый из которых содержит значение int и указатель на следующий элемент списка.
- Функция slist_reverse() переворачивает порядок элементов в списке.
- Алгоритм переворачивания списка следующий:
- Создается новый указатель q, который будет следовать за текущим элементом списка p.
- Пока p не равен NULL, происходит следующее:
- q становится новым указателем на текущий элемент списка.
- p обновляется на следующий элемент списка.
- Если список пуст, то создается новый элемент списка и добавляется в начало списка.
- Если список не пуст, то текущий элемент списка добавляется в конец списка.
- В конце списка устанавливается указатель на NULL.
- Обновляется head списка, чтобы указывать на новый первый элемент списка.
- Обновляется tail списка, чтобы указывать на новый последний элемент списка.
- Функция slist_add() добавляет новый элемент в список.
- Алгоритм добавления элемента в список следующий:
- Выделяется память под новый элемент списка.
- Новый элемент списка инициализируется значением val.
- Устанавливается указатель next нового элемента списка в NULL.
- Если список пуст, то новый элемент становится первым элементом списка.
- Если список не пуст, то новый элемент добавляется в конец списка.
- Функция slist_clear() очищает список, освобождая память, занятую каждым элементом списка.
- Функция slist_print() печатает список на стандартный вывод.
- Алгоритм печати списка следующий:
- Инициализируется указатель p на первый элемент списка.
- Пока p не равен NULL, происходит следующее:
- Выводится значение элемента списка, на которое указывает указатель p.
- Указатель p обновляется на следующий элемент списка.
- Функция slist_init() инициализирует список.
- Алгоритм инициализации списка следующий:
- Устанавливается head списка в NULL.
- Устанавливается tail списка в NULL.