Форум программистов, компьютерный форум CyberForum.ru

Добавление элемента в двусвязный список - C++

Восстановить пароль Регистрация
 
romanova_e
0 / 0 / 0
Регистрация: 11.04.2016
Сообщений: 10
11.04.2016, 15:29     Добавление элемента в двусвязный список #1
Здравствуйте, нужно вставить элемент в двусвязный список
Написала код, но он не работает.
C++
1
2
3
4
5
6
7
8
tek=first;
    while(tek)
        {i++;
        tek=tek->next;
        if(i==z-2){p->next=tek->next;
                    p->pred=tek->pred;
                    tek->next=p;
        };
где ошибка и как ее исправить?
р это вставляемый элемент
z место на которое нужно вставить
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
RQdan
65 / 65 / 17
Регистрация: 26.10.2013
Сообщений: 198
11.04.2016, 16:29     Добавление элемента в двусвязный список #2
romanova_e,
C++
1
2
3
4
5
6
7
8
9
10
tek=first;
    while(tek)
        {i++;
        tek=tek->next;
        if(i==z-2){
                    tek->pred->next=p;
                    p->next=tek;
                    p->pred=tek->pred;
                    tek->pred=p;
        };
Не забудьте сделать проверку, если предыдущий элемент NULL.
romanova_e
0 / 0 / 0
Регистрация: 11.04.2016
Сообщений: 10
11.04.2016, 16:35  [ТС]     Добавление элемента в двусвязный список #3
Выдает ошибку в строке tek->pred->next=p;
Необработанное исключение по адресу 0x012B6F31 в 1.exe: 0xC0000005: нарушение прав доступа при чтении по адресу 0x00000030.
что делать?
RQdan
65 / 65 / 17
Регистрация: 26.10.2013
Сообщений: 198
11.04.2016, 16:54     Добавление элемента в двусвязный список #4
Цитата Сообщение от romanova_e Посмотреть сообщение
Выдает ошибку в строке tek->pred->next=p;
Скорее всего:
Цитата Сообщение от RQdan Посмотреть сообщение
Не забудьте сделать проверку, если предыдущий элемент NULL.
ssXXss
263 / 185 / 10
Регистрация: 15.01.2011
Сообщений: 668
11.04.2016, 17:03     Добавление элемента в двусвязный список #5
С++ Линейный двусвязный список , гугла тыкнула.
Кликните здесь для просмотра всего текста

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
#include <stdlib.h>
#include <iostream.h>
 
struct Node       //Структура являющаяся звеном списка
 {
     int x;     //Значение x будет передаваться в список
     Node *Next,*Prev; //Указатели на адреса следующего и предыдущего элементов списка
 };
 
 class List   //Создаем тип данных Список
 {
     Node *Head,*Tail; //Указатели на адреса начала списка и его конца
 public:
     List():Head(NULL),Tail(NULL){}; //Инициализируем адреса как пустые
     ~List(); //Деструктор
     void Show(); //Функция отображения списка на экране
     void Add(int x); //Функция добавления элементов в список
 };
 
List::~List() //Деструктор
 {   
     while (Head) //Пока по адресу на начало списка что-то есть
     {
         Tail=Head->Next; //Резервная копия адреса следующего звена списка
         delete Head; //Очистка памяти от первого звена
         Head=Tail; //Смена адреса начала на адрес следующего элемента
     }
 }
 
 void List::Add(int x)
 {
   Node *temp=new Node; //Выделение памяти под новый элемент структуры
   temp->Next=NULL;  //Указываем, что изначально по следующему адресу пусто
   temp->x=x;//Записываем значение в структуру
 
   if (Head!=NULL) //Если список не пуст
   {
       temp->Prev=Tail; //Указываем адрес на предыдущий элемент в соотв. поле
       Tail->Next=temp; //Указываем адрес следующего за хвостом элемента
       Tail=temp; //Меняем адрес хвоста
   }
   else //Если список пустой
   {
       temp->Prev=NULL; //Предыдущий элемент указывает в пустоту
       Head=Tail=temp; //Голова=Хвост=тот элемент, что сейчас добавили
   }
 }
 
 void List::Show()
 {
//ВЫВОДИМ СПИСОК С КОНЦА
     Node *temp=Tail;
      //Временный указатель на адрес последнего элемента
     while (temp!=NULL) //Пока не встретится пустое значение
     {
     cout<<temp->x<<" "; //Выводить значение на экран
     temp=temp->Prev; //Указываем, что нужен адрес предыдущего элемента
     }
     cout<<"\n";
 
 //ВЫВОДИМ СПИСОК С НАЧАЛА
     temp=Head; //Временно указываем на адрес первого элемента
      while (temp!=NULL) //Пока не встретим пустое значение
     {
     cout<<temp->x<<" "; //Выводим каждое считанное значение на экран
     temp=temp->Next; //Смена адреса на адрес следующего элемента
     }
     cout<<"\n";
 }
 
int main ()
{
 system("CLS");
 List lst; //Объявляем переменную, тип которой есть список
 lst.Add(100); //Добавляем в список элементы
 lst.Add(200);
 lst.Add(900);
 lst.Add(888);
 
 lst.Show(); //Отображаем список на экране
  system("PAUSE");
}
romanova_e
0 / 0 / 0
Регистрация: 11.04.2016
Сообщений: 10
11.04.2016, 17:09  [ТС]     Добавление элемента в двусвязный список #6
проверку сделала, но все равно та же ошибка
ssXXss
263 / 185 / 10
Регистрация: 15.01.2011
Сообщений: 668
11.04.2016, 17:16     Добавление элемента в двусвязный список #7
перед использованием указателя , не важно на что, присвой ему значение NULL, так как с точки зрения компа адрес - 0x00000030 корректный а с точки зрения ОС нет, защита ОС самой себя и все такое прочее. в не инициализируемом указателе может хранится всякий мусор и в последствии будет произведена попытка перейти на этот мусор в качестве адреса.
C++
1
 List():Head(NULL),Tail(NULL){}; //Инициализируем адреса как пустые
romanova_e
0 / 0 / 0
Регистрация: 11.04.2016
Сообщений: 10
11.04.2016, 17:35  [ТС]     Добавление элемента в двусвязный список #8
та же ошибка
вот код:

C++
1
2
3
4
5
6
7
8
9
10
first->pred=last->next=NULL;
    while(tek)
        {i++;
        tek=tek->next;
        if((i==z-2)&(tek->pred!=NULL)){
                    tek->pred->next=p;
                    p->next=tek;
                    p->pred=tek->pred;
                    tek->pred=p;
        };};};
RQdan
65 / 65 / 17
Регистрация: 26.10.2013
Сообщений: 198
11.04.2016, 17:43     Добавление элемента в двусвязный список #9
Цитата Сообщение от romanova_e Посмотреть сообщение
проверку сделала, но все равно та же ошибка
Тогда надо смотреть весь код.
Вполне возможно, что ошибка была при создании списка, как указал ssXXss.

Добавлено через 4 минуты
Цитата Сообщение от romanova_e Посмотреть сообщение
if((i==z-2)&(tek->pred!=NULL)){
Ненужно. Оставьте как было.

Цитата Сообщение от romanova_e Посмотреть сообщение
tek->pred->next=p;
заменить на
C++
1
2
3
if(tek->pred) tek->pred->next=p;
else Head = p;//Head - ссылка на начало списка. 
//Вставьте ту переменную, что у Вас забита под указатель на начало списка
romanova_e
0 / 0 / 0
Регистрация: 11.04.2016
Сообщений: 10
11.04.2016, 17:49  [ТС]     Добавление элемента в двусвязный список #10
Исправила, выдает ошибку:
Необработанное исключение по адресу 0x0021A0B4 в 1.exe: 0xC0000005: нарушение прав доступа при чтении по адресу 0x00000030.
ssXXss
263 / 185 / 10
Регистрация: 15.01.2011
Сообщений: 668
11.04.2016, 17:52     Добавление элемента в двусвязный список #11
покажи код полностью
RQdan
65 / 65 / 17
Регистрация: 26.10.2013
Сообщений: 198
11.04.2016, 17:52     Добавление элемента в двусвязный список #12
Цитата Сообщение от romanova_e Посмотреть сообщение
Исправила, выдает ошибку:
Я там еще раз исправлял свой пост - проверьте.

И лучше выложить весь код программы, чтобы посмотреть детальнее. Ошибка, возможно, напрямую не связана с функцией поиска.
romanova_e
0 / 0 / 0
Регистрация: 11.04.2016
Сообщений: 10
11.04.2016, 18:00  [ТС]     Добавление элемента в двусвязный список #13
Имеются сведения об автомобилях: марка, год выпуска, цвет.
1.Создать линейный двунаправленный список
2. Вывести его справа налево и слева направо
3.Распечатывать список слева направо до тех пор, пока на экран не выведутся сведения о 20 марках ауди. (я заменила на qq)
4.Добавить сведения о новой машине, поместив сведения о ней после первой по порядку машины такой же марки
5.Удалить сведения о машинах заданного цвета
6.Уничтожить список удалив заданную под него память

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
#include "stdafx.h"
#include "iostream"
#include "string"
using namespace std;
 
char g[20];
int i=0;
int k=0;
int n=0;//количество элементов списка
 
struct elem 
{public:
    char mar[20];
    int god;
    char cvet[20];
    struct elem *next;
    struct elem *pred;
    struct elem *p;
    elem();
};
 
elem::elem()
{
    next=pred=NULL;
};
 
 
class list //сам список
{elem *first, *tek, *last;
//elem *pred, *next;
public:
    list();//конструктор
    void sozd(); 
    void vivod();
    void audi();
    void vstav();
 
};
 
list::list()
{
    first=tek=last=NULL;
    //next=pred=NULL;
};
 
 
void list::sozd()
{
    
    first=tek=last=NULL;
    //next=pred=NULL;
    //tek->next=NULL;
    cout<<"Признак конца ввода точка "<<endl;
    do
            {
            cout<<"Введите марку машины ";
            cin>>g;
            if( strcmp(g,".")==0)break;
            tek=new elem;
            strcpy_s(tek->mar,g);
            n++;// считаем количество элементов списка
            cout<<"Введите год машины  ";
            cin>>tek->god;
 
            cout<<"Введите цвет машины ";
            cin>>tek->cvet;
 
            tek->pred=first;
 
            if(first==NULL)last=tek;
            else first->next=tek;
            first=tek;
            }
 
            while((first->mar)!=".");
            cout<<"Список создан"<<endl;
}
 
 
void list::vivod()
{tek=first;
cout<<"Вывод справа налево (с конца)"<<endl;
while(tek)
{cout<<tek->mar<<' '<<tek->god<<' '<<tek->cvet<<endl;
tek=tek->pred;}
 
tek=last;
cout<<"Вывод слева направо (сначала)"<<endl;
while(tek)
{cout<<tek->mar<<' '<<tek->god<<' '<<tek->cvet<<endl;
tek=tek->next;}
};
 
void list::audi()
{
    tek=last;
    int l=0;
    cout<<"Вывод сведений о 20 ауди"<<endl;
    while(i<20)
        {l++;
        while(tek)
            {
            if(strcmp(tek->mar,"qq")==0)
                    {
                    cout<<tek->mar<<' '<<tek->god<<' '<<tek->cvet<<endl;
                    i++;
                    if(i==20)break;
                    };
            
            tek=tek->next;
            };
    if(i==0)
        {cout<<"Машин данной марки нет в списке "<<endl;
        break;}
    tek=last;};
    cout<<"Количество полных проходов списка "<<l<<endl;};
 
 
void list::vstav()
{
    int i=0;int z=0;
    tek=first;
    elem *p=new elem;
    cout<<"Введите  марку машины, которую вы хотите добавить в список ";
    cin>>p->mar;
    cout<<"Введите год машины, которую вы хотите добавить в список ";
    cin>>p->god;
    cout<<"Введите цвет машины, которую вы хотите добавить в список ";
    cin>>p->cvet;
 
    tek=last;
    while(tek)
            {z++;
            if(strcmp(tek->mar,p->mar)==0)break;
            tek=tek->next;
            };
    z=z+1;
    cout<<z<<endl;//на какое место нужно добавить машину
    cout<<n<<endl;//количество элементов в списке
 
    if(z==n+1)//добавление на последнее место
        {p->pred=first;
            if(first==NULL)last=p;
            else first->next=p;
            first=p;
            }
    else
    {first->pred=last->next=NULL;
    while(tek)
        {i++;
        tek=tek->next;
        if(i==z-2){
                   if(tek->pred) tek->pred->next=p;
                    else first = p;
                    p->next=tek;
                    p->pred=tek->pred;
                    tek->pred=p;
        };};};
};
 
 
 
int _tmain(int argc, _TCHAR* argv[])
{   
    setlocale(LC_ALL,"Russian");
    list obj;
    obj.sozd();
    obj.vivod();
    //obj.audi();
    obj.vstav();
    obj.vivod();
    system("pause");
    return 0;
}
RQdan
65 / 65 / 17
Регистрация: 26.10.2013
Сообщений: 198
11.04.2016, 18:21     Добавление элемента в двусвязный список #14
romanova_e, у меня Ваш код работает.
При каких входных данных происходит ошибка?
romanova_e
0 / 0 / 0
Регистрация: 11.04.2016
Сообщений: 10
11.04.2016, 18:26  [ТС]     Добавление элемента в двусвязный список #15
При вставке элемента в середину.
Например
qq 1 q
ww 2 w
ee 3 e
когда вводишь ww и заполняешь дальше, там выдает ошибку
RQdan
65 / 65 / 17
Регистрация: 26.10.2013
Сообщений: 198
11.04.2016, 18:42     Добавление элемента в двусвязный список #16
Цитата Сообщение от romanova_e Посмотреть сообщение
При вставке элемента в середину.
Например
qq 1 q
ww 2 w
ee 3 e
когда вводишь ww и заполняешь дальше, там выдает ошибку
У меня все работает и ошибок не выдает.
Хотя при вставке результат неправильный при совпадении марок.
romanova_e
0 / 0 / 0
Регистрация: 11.04.2016
Сообщений: 10
11.04.2016, 18:44  [ТС]     Добавление элемента в двусвязный список #17
вы не знаете где там ошибка?
ssXXss
263 / 185 / 10
Регистрация: 15.01.2011
Сообщений: 668
11.04.2016, 18:46     Добавление элемента в двусвязный список #18
romanova_e если подождешь , накидаю код.
romanova_e
0 / 0 / 0
Регистрация: 11.04.2016
Сообщений: 10
11.04.2016, 19:02  [ТС]     Добавление элемента в двусвязный список #19
жду
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
11.04.2016, 23:24     Добавление элемента в двусвязный список
Еще ссылки по теме:

Добавление элемента в список C++
C++ Добавление элемента в список
C++ Двусвязный список. Добавление элемета в начало

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

Или воспользуйтесь поиском по форуму:
ssXXss
263 / 185 / 10
Регистрация: 15.01.2011
Сообщений: 668
11.04.2016, 23:24     Добавление элемента в двусвязный список #20
Кликните здесь для просмотра всего текста

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
196
197
//*.cpp
#include <iostream>
#include <string.h>
#ifndef nullptr
#define nullptr         0
#endif
 
struct car_info
{
public:
    //указатели
    car_info* prev_car_info;
    car_info* next_car_info;
    //описание машины
    std::string strName;
    std::string strYear;
    std::string strColor;
    int count;
    
 
    car_info() {
        prev_car_info = nullptr;
        next_car_info = nullptr;
        count = 0;
    }
    void init_head() {
        prev_car_info = this;
    }
};
// новый элемент для списка
car_info* init_car_info(const std::string& sName, const std::string& sYear, const std::string& sColor) {
    car_info* pcar_info = new car_info;
    pcar_info->strColor = sColor;
    pcar_info->strName = sName;
    pcar_info->strYear = sYear;
    pcar_info->count = 1;
    return pcar_info;
}
//получим голову списка
car_info* get_head(car_info* node_from_list) {
    if (!node_from_list)
        return nullptr;
    car_info* ptemp = node_from_list;
    while (ptemp->prev_car_info != ptemp)
        ptemp = ptemp->prev_car_info;
    return ptemp;
}
//получим хвост списка
car_info* get_tail(car_info* node_from_list) {
    if (!node_from_list)
        return nullptr;
    car_info* ptemp = node_from_list;
    while (ptemp->next_car_info)
        ptemp = ptemp->next_car_info;
    return ptemp;
}
//добавим сведения о новой машине
bool add_car_info(car_info* node_from_list,car_info* added) {
    if (!node_from_list || !added)
        return false;
    bool pasted = false;
    //если указан элемент из середины списка, то поднимаемся в начало списка
    car_info* ptemp = get_head(node_from_list);
    if (!ptemp) return false;
    while (ptemp) {
        //ищем нужную модель
        if (ptemp->strName == added->strName) {
            //нашли первую запись с такой же моделью, теперь вставим после нее 
            if (!pasted) {
                car_info* pt = ptemp->next_car_info;
                ptemp->next_car_info = added;
                added->prev_car_info = ptemp;
                added->next_car_info = pt;
                added->count = ptemp->count + 1;
                pasted = true;
                if (pt) {
                    pt->prev_car_info = added;
                    ptemp = pt;
                }
                else {
                    added->count = added->prev_car_info->count + 1;
                    break;
                }
            }
            //исправим номера записей всех остальных, этой же модели                
            if (pasted)
                ptemp->count++;                                     
        }
        if (ptemp->next_car_info)
            ptemp = ptemp->next_car_info;
        else
            break;
    }
    if (!pasted) {//нет подобной модели, простодобавим в конец списка
        ptemp->next_car_info = added;
        added->prev_car_info = ptemp;
        added->next_car_info = nullptr;
        added->count = 1;
    }
    return true;
}
//вывод нужного количества моделей из списка
void print_car_info(car_info* node_from_list,int num, const std::string& strName) {
    if (!node_from_list || strName.empty() || !num)
        return;
    car_info* ptemp = get_head(node_from_list);
    if (!ptemp) return;
    int index = 0;
    while (ptemp || index >= num) {
        std::cout << ptemp->strName.c_str() << std::endl;
        if (ptemp->strName == strName)
            index++;
        ptemp = ptemp->next_car_info;
    }
}
//печать с головы true? с хвоста false
void print_all_car_info(car_info* node_from_list, bool head = true) {
    if (!node_from_list)
        return;
    car_info* ptemp = nullptr;
    ptemp = head ? get_head(node_from_list) : get_tail(node_from_list);
    if (!ptemp) return;
    if (head) {
        while (ptemp) {
            std::cout << ptemp->strName.c_str() << " " << ptemp->strYear.c_str() << std::endl;
            ptemp = ptemp->next_car_info;
        }
    }
    else{
        while (ptemp->prev_car_info != ptemp) {
            std::cout << ptemp->strName.c_str() << " " << ptemp->strYear.c_str() << std::endl;
            ptemp = ptemp->prev_car_info;
        }
    }   
}
//удаление модели с опр. цветом
void delete_car_info(car_info* node_from_list, const std::string& strColor) {
    if (!node_from_list || strColor.empty())
        return;
    car_info* ptemp = get_head(node_from_list),*pt = nullptr;
    if (!ptemp) return;
 
    while (ptemp) {
        if (ptemp->strColor == strColor) {
            pt = ptemp->next_car_info;
            if (ptemp->prev_car_info == ptemp)
                pt->prev_car_info = pt;
            else {
                pt->prev_car_info = ptemp->prev_car_info;
                pt->prev_car_info->next_car_info = pt;
            }
            delete ptemp;
            ptemp = pt;
        }
        else
            ptemp = ptemp->next_car_info;
    }
}
//удаляем весь список
void delete_all(car_info* node_from_list) {
    car_info* ptemp = get_head(node_from_list), *pt = nullptr;
    if (!ptemp) return;
    while (ptemp) {
        pt = ptemp->next_car_info;
        delete ptemp;
        ptemp = pt;
    }
}
void main(){
car_info* c1 = init_car_info("qqq", "www", "1");
    c1->init_head();
    car_info* c2 = init_car_info("qqq", "www", "2");
    car_info* c3 = init_car_info("qqq", "www", "3");
    car_info* c4 = init_car_info("qqq", "www", "4");
    car_info* c5 = init_car_info("rrr", "eee", "11");
    car_info* c6 = init_car_info("rrr", "eee", "22");
 
 
    add_car_info(c1, c2);
    add_car_info(c1, c3);
    add_car_info(c2, c4);
    add_car_info(c4, c5);
    add_car_info(c2, c6);
 
    print_car_info(c6, 60, "rrr");
    print_all_car_info(c2);
    print_all_car_info(c1,false);
 
    delete_car_info(c6, "eee");
    delete_car_info(c6, "11");
    print_all_car_info(c1);
    delete_car_info(c6, "4");
    print_all_car_info(c6);
 
    delete_all(c1);
    c1 = nullptr;
}
Yandex
Объявления
11.04.2016, 23:24     Добавление элемента в двусвязный список
Ответ Создать тему
Опции темы

Текущее время: 21:23. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru