Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 5.00/4: Рейтинг темы: голосов - 4, средняя оценка - 5.00
1 / 1 / 0
Регистрация: 12.02.2014
Сообщений: 47
1

Постраничный вывод записей двунаправленного списка

20.11.2017, 22:56. Показов 820. Ответов 6

Здравствуйте!

Проблема в чём - курсовик, постраничный вывод записей двунаправленного списка, при удалении последнего элемента на странице не происходит переход на предыдущую страницу, а происходит вылет проги к чёртовой бабушке.
Волосы на голове вырваны, нервы убиты.

Понимаю, что надо влепить проверку при удалении элемента на то, если этот элемент первый на странице (при удалении элемент поднимается на первую позицию) и при этом он же последний на этой странице(за ним не следуют другие), то мы его удаляем, а указатель на первый элемент переносим на указатель первого элемента предыдущей страницы.
Но настолько глуп, что не понимаю как реализовать. Привожу функции удаления и имена некоторых переменных.
C++
1
 pBegin // указатель на первый элемент на странице
C++
1
 pageAmount  //указатель на переменную с количеством страниц
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
//Функция DeleteNode
//Удаляет элемент списка по ключу
//Принимает ключ в качестве параметра
void DeleteNode(int key)
{
    if (pHead == NULL)
        return;
    Node * pDelete = pHead;
    //поиск удаляемого элемента
    while (true)
    {
        if (pDelete->data.key == key)
            break;
        else
            pDelete = pDelete->pNext;
    }
    //Изменение указателей
    if (pDelete == pHead)
    {
        if (pHead == pTail)
        {
            pHead = NULL;
            pTail = NULL;
        }
        else
        {
            pHead = pHead->pNext;
            pHead->pPrev = NULL;
        }
    }
    else
    {
        if (pDelete == pTail)
        {
            pTail = pTail->pPrev;
            pTail->pNext = NULL;
        }
        else
        {
            pDelete->pNext->pPrev = pDelete->pPrev;
            pDelete->pPrev->pNext = pDelete->pNext;
        }
    }
    pTemp = pHead;
    //изменение ключей в списке
    while (pTemp != NULL)
    {
        if (pTemp->data.key > pDelete->data.key)
            pTemp->data.key -= 1;
        pTemp = pTemp->pNext;
    }
    //освобождение памяти
    delete(pTemp);
    notesAmount--;
    notesForPrint--;
}
//Функция DeleteNode
//Удаляет элемент списка по ссылке
//Принимает ключ в качестве параметра
void DeleteNode(Node * pDelete)
{
    if (pDelete == NULL)
        return;
    //Изменение указателей
    if (pDelete == pHead)
    {
        if (pHead == pTail)
        {
            pHead = NULL;
            pTail = NULL;
        }
        else
        {
            pHead = pHead->pNext;
            pHead->pPrev = NULL;
        }
    }
    else
    {
        if (pDelete == pTail)
        {
            pTail = pTail->pPrev;
            pTail->pNext = NULL;
        }
        else
        {
            pDelete->pNext->pPrev = pDelete->pPrev;
            pDelete->pPrev->pNext = pDelete->pNext;
        }
    }
    pTemp = pHead;
    //изменение ключей в списке
    while (pTemp != NULL)
    {
        if (pTemp->data.key > pDelete->data.key)
            pTemp->data.key -= 1;
        pTemp = pTemp->pNext;
    }
    //осовбождение памяти
    delete(pTemp);
    notesAmount--;
    notesForPrint--;
}
__________________
Помощь в написании контрольных, курсовых и дипломных работ здесь
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
20.11.2017, 22:56
Ответы с готовыми решениями:

Получить указатель на элемент двунаправленного списка, добавить значение в начало списка и очистить его
Нужно создать двунаправленный список //вроде так, но не уверен struct Double_List {//структура...

Вывод и ввод двумерного списка записей
Добрый день уважаемые форумчане. Столкнулся с задачей: Необходимо создать двумерный массив\список...

Реализация Двунаправленного списка
Ребят, что он хочет от меня, ошибка компиляции, понять не могу в чем проблема, у меня еще просто...

Удаление из двунаправленного списка
Программа компилируется, добавляет элементы в список, но когда доходит до удаления вылетает. ...

6
42 / 42 / 23
Регистрация: 20.11.2017
Сообщений: 80
21.11.2017, 12:42 2
первая причина по которой вылетает мне кажется, нет проверки на Null в
Цитата Сообщение от Slevin_K Посмотреть сообщение
while (true)
{
if (pDelete->data.key == key)
break;
else
pDelete = pDelete->pNext;
}
страница ( список) заканчивается и вам некуда переходить
1
1 / 1 / 0
Регистрация: 12.02.2014
Сообщений: 47
21.11.2017, 14:37  [ТС] 3
Цитата Сообщение от Shchusia Посмотреть сообщение
нет проверки на Null
не подскажете, как это должно выглядеть ?
0
42 / 42 / 23
Регистрация: 20.11.2017
Сообщений: 80
21.11.2017, 15:35 4
вы же делаете это в методе DeleteNode(Node * pDelete)
Цитата Сообщение от Slevin_K Посмотреть сообщение
while (pTemp != NULL)
но там вам надо идти по той переменной которую итерируете
и можно взглянуть на структуру вашу
1
1 / 1 / 0
Регистрация: 12.02.2014
Сообщений: 47
21.11.2017, 18:49  [ТС] 5
Цитата Сообщение от Shchusia Посмотреть сообщение
и можно взглянуть на структуру вашу
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
//Структура данных записей
struct NodeInfo
{
    int key;                    //ключ
    int StoreNumber;            //Номер магазина
    int SectionNumber;          //Номер секции
    int CheckNumber;            //Номер чека
    char ProductName[31];       //Наименование продукта
    char ProductArticle[13];    //Артикул
    float Price;                //Цена
    int ProductAmount;          //Количество
    char DateOfSale[11];        //Дата продажи
};
//Структура узла списка
struct Node
{
    NodeInfo data;          //данные
    bool Visible;           //видимость (используется для реализации поиска)
    Node* pNext;            //указатель на следующий элемент списка
    Node* pPrev;            //указатель на предыдущий элемент списка
}*pHead, *pTail, *pTemp;    //Указатель на голову списка(pHead), на хвост списка(pTail) и указатель для временного хранения ссылки (pTemp)
 
//Cтруктура узла списка обработанных данных
struct ProcessNode
{
    int StoreNumber;                //Номер магазина
    double Profit;              //Выручка
    ProcessNode *pNext, *pPrev;     //Указатели на следующий и предыдыущий элементы списка
};
0
42 / 42 / 23
Регистрация: 20.11.2017
Сообщений: 80
21.11.2017, 23:03 6
давайте разбираться по очереди
вылетает когда удаляешь по ссылке или по значению ?
и добавление условия в цикл помогло ?
и зачем эта часть кода ?
Цитата Сообщение от Slevin_K Посмотреть сообщение
pTemp = pHead;
* * //изменение ключей в списке
* * while (pTemp != NULL)
* * {
* * * * if (pTemp->data.key > pDelete->data.key)
* * * * * * pTemp->data.key -= 1;
* * * * pTemp = pTemp->pNext;
* * }
* * //освобождение памяти
* * delete(pTemp);
и такой идеалогический вопрос почему тут, вы освобождаете память там где ссылка на NULL, а там где реально удаляете элемент не освобождаете ?
1
1 / 1 / 0
Регистрация: 12.02.2014
Сообщений: 47
28.11.2017, 19:50  [ТС] 7
Добавили костыль, дабы не вылетало при удалении последнего.
C++
1
2
3
4
5
6
7
8
9
10
11
    case 0:
                //обработка на вылет при удалении последнего элемента КОСТЫЫЫЫЫЫЛЬЬЬЬЬЬЬЬ
                if (notesAmount > 16 && notesAmount % 16 == 1) {
                notesAmount--;
                notesForPrint--;
                PrintAll();
                notesForPrint++;
                notesAmount++;
                }
                DeleteNode((*data).key, active);
                return;
Цитата Сообщение от Shchusia Посмотреть сообщение
вы освобождаете память там где ссылка на NUL
То, что Вы подметили ) Оставил функцию удаления по ключу. По ссылке удалил.
C++
1
2
3
    delete(pDelete);    //снос данных
    notesAmount--;
    notesForPrint--;
Итог: теперь не вываливаемся при удалении последнего элемента, но после удаления активное поле пропадает и при нажатии Enter (клавиши открытия окна редактирования записи) открывается запись (та, которую мы только что удалили, только из-за последних внесенных изменений заметно, что функция удаления подчистила запись. - скрин прикрепляю).
Надо бы, что активная запись переходила к предыдущей записи, а не оставалась на удаленной.
Миниатюры
Постраничный вывод записей двунаправленного списка  
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
28.11.2017, 19:50

Сортировка двунаправленного списка
Посоветуйте пожалуйста адекватный метод сортировки двунаправленного списка. Я сопсно вычитал на...

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

Шаблон двунаправленного списка
Добрый день! Пишу программу "библиотека", которая включает в себя типы данных Книга и Читатель...

Очередь из двунаправленного списка
Вот мой двусвязный список : struct Num { int number; bool ring; Num *next, *prev; };...


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

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2022, CyberForum.ru