С Новым годом! Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.55/11: Рейтинг темы: голосов - 11, средняя оценка - 4.55
1 / 1 / 0
Регистрация: 06.10.2018
Сообщений: 161

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

15.04.2019, 14:03. Показов 2235. Ответов 5
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Добрый день. Помогите пожалуйста написать сортировку слиянием для двусвязанного списка.
Вот объявление очереди и её узлов:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
struct QNode {
    int value;
    QNode* next;
    QNode* prev;
    int number;
    friend bool operator==(const QNode node1, const QNode node2)
    {
        return node1 == node2;
    }
};
struct Q {
    QNode* begin;
    QNode* end;
};
Ну и инициализацию оставлю очереди:
C++
1
2
3
4
void initialization(Q& queue)
{
    queue.begin = queue.end = NULL;
}
Вот функция добавления элемента в очередь:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void addElement(Q& queue, int value)
{
    QNode* newNode = new QNode;
    howQNodes++;
    newNode->number = howQNodes;
    newNode->value = value;
    cout << "\t" << newNode->value;
    cout << "\t(" << newNode->number << ")" << endl;
    newNode->next = NULL;
    newNode->prev = NULL;
    if (queue.begin == NULL) {
        queue.begin = newNode;
        queue.end = queue.begin;
    }
    else {
        newNode->prev = queue.end;
        queue.end->next = newNode;
        queue.end = queue.end->next;
    }
}
А вот я пытался написать сортировку:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
void MergeSort(Q queue, QNode* begin, QNode* end)
{
    if (begin == end) //для этого создал friend-функцию
        return;
    size_t middle = howQNodes / 2 + 1;//(нахожу середину)howQNodes - сколько всего элементов очереди есть
 
    //
    int bufint = 0;
    QNode* temp = queue.begin;
    while (bufint!=middle) {  //bufint переменная, чтоб найти средний элемент и установить на него temp для 
        temp = temp->next;    //последующей передачи в MergeSort();
        bufint++;
    }
    MergeSort(queue, begin, temp);
    MergeSort(queue, temp->next, end);
    merge(queue, begin, end, temp);
}
void merge(Q queue, QNode* begin, QNode* end, QNode* temp)
{
    //не знаю как написать под
}
Да, делаю очень своеобразно, поскольку в интернете сортировка для Int-значений написана, а как её применить в моём случае
не знаю. Помогите пожалуйста.
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
15.04.2019, 14:03
Ответы с готовыми решениями:

Сортировка слиянием кольцевого списка
Есть класс двусвязного кольцевого списка и итератор к нему-шаблоны. не могу довести до ума сортировку слиянием для этого списка и понять...

Удаление из двусвязанного списка
Всем здравия. В двусвязанном списке нужно удалить выбранный элемент. Упорно косячу на этом моменте, постоянно ошибка. Может, кто...

Сортировка линейного списка слиянием сверху вниз
«Функция merge должна сливать список, на который указывает a, со списком, на который указывает b, с помощью вспомогательного указателя с....

5
 Аватар для zayats80888
6352 / 3523 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
15.04.2019, 14:57
YFKoenigsegg, вот делал когда-то. Не очень эффективно, но работает.
Кликните здесь для просмотра всего текста
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
template <class T>
struct Node
{
    Node(T d) :data(d), next(nullptr), prev(nullptr) {}
    T data;
    Node* next;
    Node* prev;
};
 
template <class T>
class MyList
{
public:
    MyList() :head(nullptr), tail(nullptr), size(0) {}
    MyList(MyList& list) :MyList()
    {
        for (int i = 0; i < list.size; ++i)
            Add(list.get_data(i));
    }
    MyList& operator=(const MyList& list) {
        clear();
        for (int i = 0; i < list.size; ++i)
            add(list.get_data(i));
        return *this;
    }
    ~MyList() {
        clear();
    }
 
    void add(const T& data)
    {
        Node<T>* temp = new Node(data);
        if (tail)
        {
            temp->prev = tail;
            tail->next = temp;
            tail = temp;
        }
        else
            head = tail = temp;
        size++;
    }
 
    int get_size() const { return size; }
 
    Node<T>* get_node(int index) const
    {
        Node<T>* temp = head;
        while (temp && index--) temp = temp->next;
        return temp;
    }
 
    T get_data(int index) const
    {
        Node<T>* temp = get_node(index);
        if (temp) return temp->data;
        return T();
    }
 
    void remove(int index)
    {
        Node<T>* temp = get_node(index);
        if (!temp) return;
        if (temp->next) temp->next->prev = temp->prev;
        else tail = temp->prev;
        if (temp->prev) temp->prev->next = temp->next;
        else head = temp->next;
        delete temp;
        --size;
    }
 
    void clear()
    {
        while (head)
        {
            Node<T>* temp = head;
            head = head->next;
            delete temp;
        }
        head = tail = nullptr;
        size = 0;
    }
private:
    Node<T>* head;
    Node<T>* tail;
    int size;
};
 
template <class T>
void div_list(MyList<T>& list, MyList<T>& left, MyList<T>& right)
{
    left = list;
    right = list;
    for (int i = 0; i < list.get_size() / 2; ++i)
    {
        right.remove(0);
        left.remove(left.get_size() - 1);
    }
    if (list.get_size() % 2) right.remove(0);
}
 
template<class T>
void merge_sort(MyList<T>& list)
{
    if (list.get_size() > 1)
    {
        MyList<T> left;
        MyList<T> right;
        div_list(list, left, right);
 
        merge_sort(left);
        merge_sort(right);
        list.clear();
        while (0 < left.get_size() || 0 < right.get_size())
        {
            if (left.get_data(0) < right.get_data(0))
            {
                list.add(left.get_data(0));
                left.remove(0);
            }
            else
            {
                list.add(right.get_data(0));
                right.remove(0);
            }
            if (left.get_size() == 0)
            {
                while (right.get_size())
                {
                    list.add(right.get_data(0));
                    right.remove(0);
                }
                break;
            }
            if (right.get_size() == 0)
            {
                while (left.get_size())
                {
                    list.add(left.get_data(0));
                    left.remove(0);
                }
                break;
            }
        }
    }
}
0
1 / 1 / 0
Регистрация: 06.10.2018
Сообщений: 161
15.04.2019, 16:18  [ТС]
Спасибо
А есть не через класс?
0
 Аватар для zayats80888
6352 / 3523 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
15.04.2019, 16:33
YFKoenigsegg, переделайте методы в обычные функции.
0
1 / 1 / 0
Регистрация: 06.10.2018
Сообщений: 161
15.04.2019, 21:09  [ТС]
Вот так я переписал:
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
void divList(Q& queue, Q& left, Q& right)
{
    left = queue;     //для этих двух строк написал конструктор копирования
    right = queue;
    for (int i = 0; i < queue.size / 2; ++i)
    {
        QNode* toDel = right.begin;    //right.remove(0); - удаляю элем. из начала right
        deleteElem(right, toDel);
        QNode* otherToDel = left.end;  // left.remove(left.get_size() - 1); - аналогично с left
        deleteElem(left, otherToDel);
    }
    if (queue.size % 2) {
        QNode* toDel = right.begin;  //right.remove(0);
        deleteElem(right, toDel);
    }
}
void mergeSort(Q& queue)
{
    if (queue.size > 1)
    {
        Q left;
        initialization(left);
        Q right;
        initialization(right);
        divList(queue, left, right);
 
        mergeSort(left);
        mergeSort(right);
        while (!isempty(queue)) {   //удаляю элементы queue
            deleteElement(queue);
        }
        while (0 < left.size || 0 < right.size)
        {
            if (left.begin->value < right.begin->value)  //вроде как сравниваю элементы, но действительно ли так
            {                                                                //поскольку я не итерируюсь далее
                addElement(queue, left.begin->value);  //добавляем на финальную очередь узел
                QNode* toDel = left.begin;     //удаляем, где он находился
                deleteElem(left, toDel);
            }
            else
            {
                addElement(queue, right.begin->value);  //аналогичные действия в противоположной ситуации
                QNode* toDel = right.begin;
                deleteElem(right, toDel);
            }
            if (left.size == 0)    //далее проще, если одна пуста, то просто переписываем остаток другой очереди
            {
                while (right.size)
                {
                    addElement(queue, right.begin->value);
                    QNode* toDel = right.begin;
                    deleteElem(right, toDel);
                }
                break;
            }
            if (right.size == 0)
            {
                while (left.size)
                {
                    addElement(queue, left.begin->value);
                    QNode* toDel = left.begin;
                    deleteElem(left, toDel);
                }
                break;
            }
        }
    }
}
Но я предварительно добавил конструктор копирования и так переписал структуру:
C++
1
2
3
4
5
6
7
8
9
10
struct Q {
    QNode* begin;
    QNode* end;
    int size;
    Q() {};
    Q(const Q& queue)
    {
        this->begin = queue.begin;
    }
};
Не работает, зависает, ошибка доступа появляется. Как рассуждал, написал всё в комментариях(возможно кому-нибудь понадобиться)
0
 Аватар для zayats80888
6352 / 3523 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
15.04.2019, 21:29
YFKoenigsegg, расставьте точки останова, и следите за всеми значениями в каждой итерации. так быстрее найдете ошибку
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
15.04.2019, 21:29
Помогаю со студенческими работами здесь

Сортировка слиянием. В каком куске кода происходит сортировка и каким именно образом?
Помогите, пожалуйста, разобраться. Подскажите в каком куске кода происходит сортировка и каким именно образом? #include &lt;iostream&gt; ...

Сортировка Слиянием vs Быстрая Сортировка - что лучше
Народ, помогите разобраться какой из методов сортировки лучше &quot;Сортировка Слиянием&quot; или &quot;Быстрая Сортировка&quot;: у быстрой...

2 сортировки: пирамидальная сортировка и сортировка слиянием
Реализовать два улучшенных алгоритма сортировки. Для каждого алгоритма вычислить показатель качества сортировки (количество операций, т.е....

Шейкерная сортировка + сортировка слиянием
вот часть когда,которая выполняет шейкерную сортировку : для символьного и целочисленого массива . // ConsoleApplication15.cpp:...

Сортировка слиянием
Нужен алгоритм сортировки массива слиянием. Массив из 1000 чисел, введенных рандомно. На visual c++ заранее большое спасибо.


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

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Новые блоги и статьи
сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
Модель микоризы: классовый агентный подход 2
anaschu 06.01.2026
репозиторий https:/ / github. com/ shumilovas/ fungi ветка по-частям. коммит Create переделка под биомассу. txt вход sc, но sm считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
Расчёт токов в цепи постоянного тока
igorrr37 05.01.2026
/ * Дана цепь постоянного тока с сопротивлениями и источниками (напряжения, ЭДС и тока). Найти токи и напряжения во всех элементах. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа и. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru