Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.75/4: Рейтинг темы: голосов - 4, средняя оценка - 4.75
0 / 0 / 0
Регистрация: 10.06.2019
Сообщений: 25

Сортировка слиянием односвязного списка типа очередь

20.11.2022, 10:02. Показов 873. Ответов 3

Студворк — интернет-сервис помощи студентам
Добрый день уважаемые!
Возникла проблема реализации сортировки слиянием односвязного списка, с положительными значениями, типа очередь. Есть код программы, как тут лучше реализовать сортировку списка?
Перерыл интернет, видел множество реализаций сортировки списка, но они все отказывались работать, либо некорректно работали с списком, хотелось бы добавить к коду программы сортировку, в виде подпрограммы, которая вызывается при объявлении. В списке реализовано добавление и удаление элементов, а также показ элементов списка. Как лучше выводить список, обычный и отсортированный сразу, или добавить возможность сортировки и сразу же, вывода списка?
Также, хотелось бы узнать, как правильно реализовать функцию поиска по такому списку. Заранее благодарю.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#include <iostream>
using namespace std;
struct node {
    int data;
    struct node* next;
};
struct node* front = NULL;
struct node* rear = NULL;
struct node* temp;
void Insert() {
    int val;
    cout << "Вставка элемента в список : " << endl;
    cin >> val;
    if (rear == NULL) {
        rear = (struct node*)malloc(sizeof(struct node));
        rear->next = NULL;
        rear->data = val;
        front = rear;
    }
    else {
        temp = (struct node*)malloc(sizeof(struct node));
        rear->next = temp;
        temp->data = val;
        temp->next = NULL;
        rear = temp;
    }
}
void Delete() {
    temp = front;
    if (front == NULL) {
        cout << "Нет элементов в списке" << endl;
        return;
    }
    else
        if (temp->next != NULL) {
            temp = temp->next;
            cout << "Элемент удален из очереди : " << front->data << endl;
            free(front);
            front = temp;
        }
        else {
            cout << "Элемент удален из очереди : " << front->data << endl;
            free(front);
            front = NULL;
            rear = NULL;
        }
}
void Display() {
    temp = front;
    if ((front == NULL) && (rear == NULL)) {
        cout << "Список пуст" << endl;
        return;
    }
    cout << "Элементы списка: ";
    while (temp != NULL) {
        cout << temp->data << " ";
        temp = temp->next;
    }
    cout << endl;
}
int main() {
    setlocale(LC_ALL, "Rus");
    int ch;
    cout << "1) Вставка элемента в очередь" << endl;
    cout << "2) Удаление элемента из очереди" << endl;
    cout << "3) Показать все элементы в списке" << endl;
    cout << "4) Выход" << endl;
    do {
        cout << "Введите цифру : " << endl;
        cin >> ch;
        switch (ch) {
        case 1: Insert();
            break;
        case 2: Delete();
            break;
        case 3: Display();
            break;
        case 4: cout << "Выход" << endl;
            break;
        default: cout << "Неверный выбор" << endl;
        }
    } while (ch != 4);
    return 0;
}
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
20.11.2022, 10:02
Ответы с готовыми решениями:

Программирование сортировки односвязного списка простым однократным слиянием
Доброго времени суток коллеги. Нужна ваша помощь. Я пишу курсовую по c++ на тему: &quot;Программирование сортировки односвязного списка...

Очередь на основе односвязного списка
Пишет:&quot;cl.exe завершилась с кодом 2&quot; не знаю в чем проблема подскажите в чем она может заключаться ? #include&lt;iostream&gt; ...

Очередь на основе односвязного списка
Задание: &quot;Реализовать очередь на основе односвязного списка&quot; Вообщем сделал простую очередь, вопрос, как её реализовать с помощью списка?...

3
 Аватар для SmallEvil
4086 / 2975 / 813
Регистрация: 29.06.2020
Сообщений: 11,000
20.11.2022, 11:16
Цитата Сообщение от SergeyGryzlov Посмотреть сообщение
лучше выводить список, обычный и отсортированный
Да.
Цитата Сообщение от SergeyGryzlov Посмотреть сообщение
как правильно реализовать функцию поиска по такому списку.
Кликните здесь для просмотра всего текста

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#include <iostream>
using namespace std;
struct node {
    int data;
    struct node* next;
};
struct node* front = NULL;
struct node* rear = NULL;
struct node* temp;
void Insert() {
    int val;
    cout << "Вставка элемента в список : " << endl;
    cin >> val;
    if (rear == NULL) {
        rear = (struct node*)malloc(sizeof(struct node));
        rear->next = NULL;
        rear->data = val;
        front = rear;
    }
    else {
        temp = (struct node*)malloc(sizeof(struct node));
        rear->next = temp;
        temp->data = val;
        temp->next = NULL;
        rear = temp;
    }
}
void Delete() {
    temp = front;
    if (front == NULL) {
        cout << "Нет элементов в списке" << endl;
        return;
    }
    else
        if (temp->next != NULL) {
            temp = temp->next;
            cout << "Элемент удален из очереди : " << front->data << endl;
            free(front);
            front = temp;
        }
        else {
            cout << "Элемент удален из очереди : " << front->data << endl;
            free(front);
            front = NULL;
            rear = NULL;
        }
}
int* Search(int key){
    temp = front;
    while(temp){
        if (temp->data == key)
            return &(temp->data);
        temp = temp->next;
    }
    return NULL;
} 
void Display() {
    temp = front;
    if ((front == NULL) && (rear == NULL)) {
        cout << "Список пуст" << endl;
        return;
    }
    cout << "Элементы списка: ";
    while (temp != NULL) {
        cout << temp->data << " ";
        temp = temp->next;
    }
    cout << endl;
}
int main() {
    setlocale(LC_ALL, "");
    int ch=0;
 
    do {
        cout << "1) Вставка элемента в очередь" << endl;
        cout << "2) Удаление элемента из очереди" << endl;
        cout << "3) Показать все элементы в списке" << endl;
        cout << "4) Найти элемент в списке" << endl;
        cout << "0) Выход" << endl;
        cout << "Введите цифру : " << endl;
        cin >> ch;
        switch (ch) {
        case 1: Insert();
            break;
        case 2: Delete();
            break;
        case 3: Display();
            break;
        case 4: 
            int key;
            cout << "Введите значение для поиска (целое число) : ";
            cin >> key;
            if (Search(key))
                cout << "Значение присутствует в списке." << endl;
            else
                cout << "Значение не найдено." << endl;
            break;
        case 0: cout << "Выход" << endl;
            break;
        default: cout << "Неверный выбор" << endl;
        }
    } while (ch != 0);
    return 0;
}
1
0 / 0 / 0
Регистрация: 10.06.2019
Сообщений: 25
20.11.2022, 17:35  [ТС]
Благодарю за функцию поиска! Возникла проблема с другим, с сортировкой все таки. При попытке отсортировать список, ничего не выводится, и программа попросту останавливается. Я подозреваю, что дело в том, что я неправильно как то указал на начало списка? И если это верно, то как лучше это сделать? Как вообще понять, отсортировался ли список, или нет.
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
#include <iostream>
using namespace std;
struct node {
    int data;
    struct node* next;
};
struct node* front = NULL;
struct node* rear = NULL;
struct node* temp;
//Найти и вернуть средний элемент списка
node* middle(node* head, node* tail) {
    node* slow = head;
    node* fast = head;
 
    while (fast != tail && fast->next != tail) {
        slow = slow->next;
        fast = fast->next->next;
    }
    node* afterMiddle = slow->next;
    slow->next = NULL;
    return afterMiddle;
}
//сортировка слиянием
node* mergeSort(node* head) {
    if (head == NULL || head->next == NULL) {
        return head;
    }
    node* tail = head;
    while (tail->next) {
        tail = tail->next;
    }
    node* afterMiddle = middle(head, tail);
    node* part1 = mergeSort(tail);
    node* part2 = mergeSort(afterMiddle);
    node* curr1 = part1, * curr2 = part2;
    node* si = NULL, * ei = NULL;
    while (curr1 && curr2) {
        if (curr1->data <= curr2->data) {
            if (si == NULL) {
                si = curr1;
                ei = curr1;
            }
            else {
                ei->next = curr1;
                ei = curr1;
            }
            curr1 = curr1->next;
        }
        else {
            if (si == NULL) {
                si = curr2;
                ei = curr2;
            }
            else {
                ei->next = curr2;
                ei = curr2;
            }
            curr2 = curr2->next;
        }
    }
    while (curr1) {
        ei->next = curr1;
        ei = curr1;
        curr1 = curr1->next;
    }
    while (curr2) {
        ei->next = curr2;
        ei = curr2;
        curr2 = curr2->next;
    }
    return si;
}
void Insert() {
    int val;
    cout << "Вставка элемента в список : " << endl;
    cin >> val;
    if (rear == NULL) {
        rear = (struct node*)malloc(sizeof(struct node));
        rear->next = NULL;
        rear->data = val;
        front = rear;
    }
    else {
        temp = (struct node*)malloc(sizeof(struct node));
        rear->next = temp;
        temp->data = val;
        temp->next = NULL;
        rear = temp;
    }
}
void Delete() {
    temp = front;
    if (front == NULL) {
        cout << "Нет элементов в списке" << endl;
        return;
    }
    else
        if (temp->next != NULL) {
            temp = temp->next;
            cout << "Элемент удален из очереди : " << front->data << endl;
            free(front);
            front = temp;
        }
        else {
            cout << "Элемент удален из очереди : " << front->data << endl;
            free(front);
            front = NULL;
            rear = NULL;
        }
}
int* Search(int key) {
    temp = front;
    while (temp) {
        if (temp->data == key)
            return &(temp->data);
        temp = temp->next;
    }
    return NULL;
}
void Display() {
    temp = front;
    if ((front == NULL) && (rear == NULL)) {
        cout << "Список пуст" << endl;
        return;
    }
    cout << "Элементы списка: ";
    while (temp != NULL) {
        cout << temp->data << " ";
        temp = temp->next;
    }
    cout << endl;
}
int main() {
    setlocale(LC_ALL, "");
    int ch = 0;
 
    do {
        cout << "1) Вставка элемента в очередь" << endl;
        cout << "2) Удаление элемента из очереди" << endl;
        cout << "3) Показать все элементы в списке" << endl;
        cout << "4) Найти элемент в списке" << endl;
        cout << "0) Выход" << endl;
        cout << "Введите цифру : " << endl;
        cin >> ch;
        switch (ch) {
        case 1: Insert();
            break;
        case 2: Delete();
            break;
        case 3: {Display();
            node* head = front;
            head = mergeSort(head);
            Display(); }
            break; 
        case 4:
            int key;
            cout << "Введите значение для поиска (целое число) : ";
            cin >> key;
            if (Search(key))
                cout << "Значение присутствует в списке." << endl;
            else
                cout << "Значение не найдено." << endl;
            break;
        case 0: cout << "Выход" << endl;
            break;
        default: cout << "Неверный выбор" << endl;
        }
    } while (ch != 0);
    return 0;
}
0
 Аватар для SmallEvil
4086 / 2975 / 813
Регистрация: 29.06.2020
Сообщений: 11,000
20.11.2022, 18:35
Лучший ответ Сообщение было отмечено SergeyGryzlov как решение

Решение

Цитата Сообщение от SergeyGryzlov Посмотреть сообщение
Как вообще понять, отсортировался ли список, или нет.
Посмотреть на его элементы. Вывести на экран.
Посмотреть в дебагере.

Цитата Сообщение от SergeyGryzlov Посмотреть сообщение
Сортировка слиянием
У меня вообще какое то отвращение к сортировке слиянием.
Потому как им сортируют массивы с вечным перевыделением памяти.
Или вектора...

Вам поможет чем то если я ее напишу?

Добавлено через 7 минут
Напишу ее в след. раз.
На этот раз просто скопировал с "паутины"
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
#include <iostream>
using namespace std;
struct Node {
    int data;
    struct Node* next;
};
Node* front = NULL;
Node* rear = NULL;
Node* temp;
 
// Берем два списка, отсортированных по возрастанию, и объединяем их узлы
// сделать один большой отсортированный список, который будет возвращен
Node* sortedMerge(struct Node* a, struct Node* b)
{
    // базовые случаи
    if (a == NULL) {
        return b;
    }
 
    else if (b == NULL) {
        return a;
    }
 
    Node* result = NULL;
 
    // выбираем `a` или `b` и повторяем
    if (a->data <= b->data)
    {
        result = a;
        result->next = sortedMerge(a->next, b);
    }
    else {
        result = b;
        result->next = sortedMerge(a, b->next);
    }
 
    return result;
}
 
/*
    Разделить узлы данного списка на переднюю и заднюю половины
    и вернуть два списка, используя ссылочные параметры.
    Если длина нечетная, дополнительный узел должен идти в переднем списке.
    Он использует стратегию быстрого/медленного указателя
*/
void frontBackSplit(struct Node* source, struct Node** frontRef,
                    struct Node** backRef)
{
    // если длина меньше 2, обрабатывать отдельно
    if (source == NULL || source->next == NULL)
    {
        *frontRef = source;
        *backRef = NULL;
        return;
    }
 
    Node* slow = source;
    Node* fast = source->next;
 
    // продвигаем `fast` на два узла и продвигаем `slow` на один узел
    while (fast != NULL)
    {
        fast = fast->next;
        if (fast != NULL)
        {
            slow = slow->next;
            fast = fast->next;
        }
    }
 
    // `slow` находится перед средней точкой в списке, поэтому разделите его на две части
    // в таком случае.
    *frontRef = source;
    *backRef = slow->next;
    slow->next = NULL;
}
 
// Сортируем заданный связанный список, используя алгоритм сортировки слиянием
void mergesort(Node** head)
{
    // базовый вариант — длина 0 или 1
    if (*head == NULL || (*head)->next == NULL) {
        return;
    }
 
    Node* a;
    Node* b;
 
    // разделить `head` на подсписки `a` и `b`
    frontBackSplit(*head, &a, &b);
 
    // рекурсивно сортируем подсписки
    mergesort(&a);
    mergesort(&b);
 
    // ответ = объединить два отсортированных списка
    *head = sortedMerge(a, b);
}
void Insert() {
    int val;
    cout << "Вставка элемента в список : " << endl;
    cin >> val;
    if (rear == NULL) {
        rear = (struct Node*)malloc(sizeof(struct Node));
        rear->next = NULL;
        rear->data = val;
        front = rear;
    }
    else {
        temp = (struct Node*)malloc(sizeof(struct Node));
        rear->next = temp;
        temp->data = val;
        temp->next = NULL;
        rear = temp;
    }
}
void Delete() {
    temp = front;
    if (front == NULL) {
        cout << "Нет элементов в списке" << endl;
        return;
    }
    else
        if (temp->next != NULL) {
            temp = temp->next;
            cout << "Элемент удален из очереди : " << front->data << endl;
            free(front);
            front = temp;
        }
        else {
            cout << "Элемент удален из очереди : " << front->data << endl;
            free(front);
            front = NULL;
            rear = NULL;
        }
}
int* Search(int key){
    temp = front;
    while(temp){
        if (temp->data == key)
            return &(temp->data);
        temp = temp->next;
    }
    return NULL;
} 
void Display() {
    temp = front;
    if ((front == NULL) && (rear == NULL)) {
        cout << "Список пуст" << endl;
        return;
    }
    cout << "Элементы списка: ";
    while (temp != NULL) {
        cout << temp->data << " ";
        temp = temp->next;
    }
    cout << endl;
}
int main() {
    setlocale(LC_ALL, "");
    int ch=0;
 
    do {
        cout << "1) Вставка элемента в очередь" << endl;
        cout << "2) Удаление элемента из очереди" << endl;
        cout << "3) Показать все элементы в списке" << endl;
        cout << "4) Найти элемент в списке" << endl;
        cout << "0) Выход" << endl;
        cout << "Введите цифру : " << endl;
        cin >> ch;
        switch (ch) {
        case 1: Insert();
            break;
        case 2: Delete();
            break;
        case 3: 
            mergesort(&front);
            Display();
            break;
        case 4: 
            int key;
            cout << "Введите значение для поиска (целое число) : ";
            cin >> key;
            if (Search(key))
                cout << "Значение присутствует в списке." << endl;
            else
                cout << "Значение не найдено." << endl;
            break;
        case 0: cout << "Выход" << endl;
            break;
        default: cout << "Неверный выбор" << endl;
        }
    } while (ch != 0);
    return 0;
}
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
20.11.2022, 18:35
Помогаю со студенческими работами здесь

Реализовать очередь на базе односвязного списка
собственно, весь вопрос содержится в теме. Помогите, пожалуйста, а то я совсем не понимаю как это сделать...

Очередь с приоритетным исключением на основе односвязного списка
Реализовать очередь с приоритетным исключением на основе односвязного списка. Для этого разработать следующие функции: 1. Помещение...

Программа должна обеспечивать:хранение данных в информационной системе в виде односвязного списка (стек и очередь)
1) Автоматизированная информационная система на железнодорожном вокзале содержит сведения об отправлении поездов дальнего следования.Для...

Сортировка односвязного списка
Помогите, пожалуйста, написать функцию сортировки односвязного списка (пузырьком) в алфавитном порядке по автору struct book { ...

Сортировка односвязного списка
Мне нужно сделать сортировку по пункту назначения и проверку вводимых данных (т.е. чтобы Первой была станция, второй целочисленный номер не...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
4
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
SDL3 для Android: Загрузка PNG с альфа-каналом с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru