Вы разработчик, который хочет узнать о структурах данных очередей? Ну, вы пришли в нужное место! В этой статье мы рассмотрим, что такое очереди, как они работают и как их можно реализовать в Golang. Так что расслабьтесь, расслабьтесь и приготовьтесь узнать об одной из самых фундаментальных структур данных!

Если вы пропустили, я написал статью о создании собственного стека в Go. не стесняйтесь читать это здесь.



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

Что такое очередь?

Очередь — это линейная структура данных, которая следует порядку доступа к элементам. Он очень похож на стеки, с той лишь разницей, что очередь открыта с обоих концов. Один конец используется для добавления элементов, а другой конец используется для удаления элементов. Технический термин для добавления и удаления элементов называется Enqueue и Dequeue соответственно.

Очередь — это тип структуры данных, которыйпозволяет добавлять или удалять данные в порядке поступления последним (первым обслужен) (FIFO). То есть последний добавленный элемент удаляется первым.

Постановка элемента в очередь добавляет его сзади (назад). Удаление из очереди предполагает удаление с фронта.

Как это можно использовать?

  1. Посредники сообщений. Посредник сообщений — это программный посредник, который позволяет компонентам приложения взаимодействовать друг с другом. Брокеры сообщений используют очереди для хранения сообщений до тех пор, пока они не будут готовы к обработке.
  2. Планировщики заданий. Планировщик заданий — это программа, которая позволяет операционной системе управлять выполнением приложений и служб. Планировщики задач используют очереди для хранения информации о задачах, которые необходимо выполнить.
  3. Подсистемы рабочих процессов. Подсистема рабочих процессов — это программное приложение, которое позволяет управлять рабочими процессами и выполнять их. Механизмы рабочих процессов используют очереди для хранения информации о рабочих процессах, которые необходимо выполнить.
  4. Платежные системы. Платежные системы используют очереди для хранения информации о транзакциях, которые необходимо обработать.
  5. Системы поддержки клиентов. Системы поддержки клиентов используют очереди для хранения информации о запросах клиентов, которые необходимо решить.

Зачем это использовать?

Есть много преимуществ использования очереди в качестве структуры данных. Некоторые из основных преимуществ:

  1. Очень быстрый доступ к данным. Это связано с тем, что данные хранятся линейным образом, что означает, что к ним можно получить быстрый и простой доступ.
  2. Очень легко реализовать: это связано с тем, что структура данных проста и с ней необходимо выполнить всего несколько операций.
  3. Очень универсальные: они могут использоваться для хранения данных любого типа, включая строки, целые числа, числа с плавающей запятой и объекты.

Почему бы не использовать его?

Существует несколько недостатков использования структуры данных очереди:

  1. Очереди могут быть неэффективны при поиске данных. Например, если вы хотите найти определенную часть данных в очереди, вам придется выполнять поиск по всей очереди, пока не найдете нужную часть. данных, которые вы ищете.
  2. С очередями может быть сложно работать, когда дело доходит до манипулирования данными: например, если вы хотите изменить порядок данных в очереди, это может быть сложно сделать.

Реализация очереди в Go

Есть несколько причин использовать Golang при построении структуры данных очереди.

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

Почему указатели?

Есть несколько причин, по которым вы можете захотеть использовать указатели Golang для построения структуры данных очереди.

  1. Указатели позволяют динамически выделять память для вашей очереди, что означает, что вы можете увеличивать или уменьшать очередь по мере необходимости. Это может быть более эффективно, чем использование массива, который требует предварительного выделения фиксированного объема памяти.
  2. Указатели также дают вам большую гибкость с точки зрения операций, которые вы можете выполнять в своей очереди. Например, вы можете легко реализовать операцию "удаления из очереди", просто уменьшив указатель на единицу, вместо того чтобы перемещать все остальные элементы вниз в массиве.
  3. Наконец, указатели могут упростить отслеживание размера вашей очереди, поскольку вы можете изменять указатель по мере добавления или удаления элементов.

Создание нашей структуры данных

Структуры — это способ структурирования и использования данных. Это позволяет нам группировать данные. Чтобы использовать структуру, мы объявляем тип структуры, которую собираемся использовать.

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

type Item struct {
    value interface{} // hold any data type
    next  *Item
}
type Queue struct {
    front  *Item
    rear  *Item
    length int
}

Добавление возможности постановки в очередь

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

func (queue *Queue) Len() int {
 return queue.length
}
func (queue *Queue) isEmpty() bool {
  return queue.Len() == 0
}
func (queue *Queue) Enqueue(v interface{}) {
  fmt.Println(v)
  newItem := &Item{
  value: v,
  next:  queue.front,
 }
  if queue.isEmpty(){
    queue.front = newItem
    queue.rear = newItem
  } else {
    queue.rear.next = newItem
    queue.rear = newItem
  }
  queue.length = queue.length + 1
}

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

Добавление возможности исключения из очереди

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

func (queue *Queue) Dequeue() interface{} {
  if queue.isEmpty() {
    return nil
  }
  valueToDequeue := queue.front.value
  queue.front = queue.front.next
  queue.length = queue.length - 1
  return valueToDequeue
}

Добавление фронтальной возможности

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

func (queue *Queue) Front() interface{} {
  if queue.isEmpty() {
    return nil
  }
  return queue.front.value
}

Проверьте, как мы возвращаем nil, если очередь пуста, и как мы все еще используем интерфейс, чтобы не связывать нашу очередь с каким-либо конкретным типом.

Собираем все вместе

package main
import (
 "fmt"
)
type Item struct {
    value interface{} // hold any data type
    next  *Item
}
type Queue struct {
    front  *Item
    rear  *Item
    length int
}
func (queue *Queue) Enqueue(v interface{}) {
  fmt.Println(v)
  newItem := &Item{
  value: v,
  next:  queue.front,
 }
  if queue.isEmpty(){
    queue.front = newItem
    queue.rear = newItem
  } else {
    queue.rear.next = newItem
    queue.rear = newItem
  }
  queue.length = queue.length + 1
}
func (queue *Queue) Len() int {
 return queue.length
}
func (queue *Queue) isEmpty() bool {
  return queue.Len() == 0
}
func (queue *Queue) Dequeue() interface{} {
  if queue.isEmpty() {
    return nil
  }
  valueToDequeue := queue.front.value
  queue.front = queue.front.next
  queue.length --
  return valueToDequeue
}
func (queue *Queue) Front() interface{} {
  if queue.isEmpty() {
    return nil
  }
  return queue.front.value
}
func main() {
  var integerQueue Queue = Queue{};
  integerQueue.Enqueue(100) // 100 is the new queue
  integerQueue.Enqueue(200) // 100-200 is the new queue
  integerQueue.Dequeue() // Dequeues 100 | 200 is the new queue
  fmt.Println("The new Queue front is",integerQueue.Front()) // 100
  integerQueue.Enqueue(300) // 200 - 300 is the new queue
  fmt.Println("The new Queue front is",integerQueue.Front()) // 100
}

Подведение итогов

Очереди представляют собой отличную структуру данных для многих приложений и могут быть очень полезны при решении проблем. Тем не менее, у них есть свои плюсы и минусы, о которых вы должны знать, прежде чем их использовать.

Есть ли у вас опыт использования очередей? Вы использовали их каким-то новым способом? Пожалуйста, поделитесь им в комментариях. Если вы нашли эту статью полезной, поделитесь ею, а если у вас есть какие-либо вопросы об очередях, оставьте комментарий ниже!

Чтобы узнать больше о подобных статьях, следите за мной на Oh my Cod!



Боже мой!
Добро пожаловать в раздел «Боже мой!
, где мы обсуждаем все, что связано с разработкой программного обеспечения, разработкой и технологиями. Мы стремимся предоставить…medium.com»



Спасибо за прочтение!