Поиск элемента в связном списке
Поможем в ✍️ написании учебной работы
Поможем с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой

#include <iostream>

#include <stdlib.h>

void main( )

{ int N;                               // количество элементов в списке

int a;                                // искомое значение

int ind;                             // местоположение искомого эемента

struct node

{ int dat;                         // информационное поле

    struct node *link;      // поле-указатель

};

typedef node *Node_ptr; // указатель на тип node

Node_ptr head = NULL;

Node_ptr here;                      // указатель на текущий элемент

cout << “Введите количество элементов в списке”;

cin >> N;

for (int i = 0; i < N; i++)

  { if (head == NULL)

     { head = new node;

        head -> dat = rand() % 100 - 50;      // случайным образом

        cout << head -> dat << ‘ ‘;

        head -> link = NULL;

     }

       else

        { here = new node;

            here -> dat = rand() % 100 - 50;

            cout << head -> dat << ‘ ‘;

            here -> link = head;

            head = here;

         }

   }

cout << endl;

cout << “Введите искомое значение”;

cin >> a;

here = head; ind = 1;                              // встали в начало списка

if (here == NULL)

   cout << “Список пуст” << endl;

  else

     { while (here -> dat != a && here -> link != NULL)

           { here = here -> link;

               ind++;

            }

         if (here -> dat ==a)

            cout << “Искомый элемент имеет индекс ” << ind << endl;

          else cout << “Элемент не найден” << endl;

      }

Мы рассмотрели работу с однонаправленными списками. По такому списку можно двигаться только в одном направлении от первого элемента к последнему, быстрого доступа к предшествующим элементам нет. Для устранения этого неудобства в употребление вводятся такие динамические структуры как двунаправленный и кольцевой списки.

Добавим в каждый элемент списка еще одно поле, значением которого будет ссылка на предыдущий элемент списка.

struct node

{ int info;

struct node *next;     // указатель на следующий узел

struct node *prev;          // указатель на предыдущий узел

};

typedef node *Node_ptr; // указатель на тип node

Node_ptr head = NULL;

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

 


U

 

 

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

В программировании двунаправленные списки часто обобщают следующим образом: для последнего элемента следующим является первый, а для первого предыдущим является последний. Списки подобного рода называются кольцевыми двунаправленными списками.

 

 


U

 

 

В кольцо можно заключить и однонаправленный список. Из процедур обработки кольцевого списка принципиально отличается от процедур обработки линейного только обход списка. При обходе линейного списка мы переходим от одного элемента к другому, пока рабочий указатель не становится равным NULL. При просмотре кольцевого списка надо переходить к следующему элементу до тех пор, пока рабочий указатель не совпадет с указателем на первый элемент. Однако если мы начнем просмотр с первого элемента, то сразу же выйдем из цикла просмотра. Поэтому первый элемент должен обрабатываться отдельно, а обход при помощи цикла надо начинать со второго звена.

 

б) Очередь

Понятие очереди хорошо известно из повседневной жизни. Структура данных – очередь – в программировании часто используется для моделирования реальных очередей с целью определения их характеристик (средняя длина очереди, время пребывания в очереди и так далее). Поэтому очередь как структура данных должна отражать специфику реальных очередей. По своему существу очередь является сугубо динамическим объектом – с течением времени и длина очереди, и набор образующих ее элементов изменяется.

Очередь - это линейный список, где элементы добавляются в один конец списка, а удаляются с другого конца. Очереди иногда называют списками типа “первым пришел – первым ушел” (First-In-First-Out list – FIFO).

                                   

                                 добавить

 
 
 
 

                                  исключить             

 

Описание очереди:

struct och

{int info;

struct och *next;

}

 typedef och *OCH_ptr;      // указатель на тип och

 OCH_ptr head = NULL;    // указатель на начало

 OCH_ptr tail = NULL;      // указатель на хвост

Над очередью определены две операции: занесение элемента в очередь и исключение элемента из очереди. Можно, кроме того, очищать очередь и получать значение первого элемента очереди. В очереди доступны две позиции: ее конец, куда заносятся новые элементы, и ее начало, откуда извлекаются элементы.

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

А) Нет элементов в очереди.

head tail       

 

NULL

 

Б) Добавление первого элемента.

 

head tail       

 

Х1 NULL

 

В) Добавление второго элемента.

 

head                       tail                  

 

Х1     Х2 NULL

 

Г) Удаление первого элемента.

 

head tail       

 

Х2 NULL

 

Такова структура очереди, реализованной связанным динамическим списком.

 

в) Стек

Стек – это линейный список с одной точкой доступа к элементам, которая называется вершиной стека. Принцип работы со стеком: “последним пришел – первым ушел”. Стек называют также списком типа “LIFO” (Last-In-First-Out list). Операции со стеком возможны только в его вершине.

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

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

Мы будем реализовывать стек как динамический связанный список.

 Описание стека :

struct st

{int info;

st *next;

}

 typedef st *ST_ptr;             // указатель на тип st

 ST_ptr head = NULL;        // указатель на вершину стека

 

Основные операции над стеком:

- выбрать элемент из стека;

- добавить элемент в стек;

- получить значение вершины стека;

- проверить наличие элементов в стеке.

Исторически сложилось, что добавление элемента в стек называют проталкиванием (pushing), а удаление – выталкиванием (popping).

Достаточно много задач в программировании решается с использованием стека. Стек используют в программировании для реализации рекурсии. Рекурсия выполняется так: сначала все вызовы накапливаются (аналогия такая: пружина сжимается), а потом выполняются вложенные процедуры и функции (пружина распрямляется). Одно из применений стека – синтаксический разбор выражения, арифметического или логического, когда не только нужно определить правильность записи, но и вычислить значение выражения. Другой пример – разбор выражения на проверку баланса открывающих и закрывающих скобок. В одном стеке храним открывающие скобки, в другом – закрывающие и соответственно помещаем новую скобку или удаляем скобки, которые являются парными.



Дата: 2019-05-28, просмотров: 196.