[Структура данных] Основные операции односвязного списка (создание, вставка и удаление узла)

Оглавление:

Единый список

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

1. Определение связанного списка

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

typedef struct ListNode {
    
    
    int data;
    struct ListNode *next;
}LNode,*List;

Значение val в приведенном выше коде — это поле данных, используемое для хранения данных, а следующее — поле указателя, используемое для хранения адреса следующего узла.
И код использует typedef для определения псевдонима LNode, который используется для ссылки на узел связанного списка.Список — это указатель связанного списка, который используется для указания на первый узел связанного списка.

2. Создание связанного списка (инициализация)

Существует два способа создания связанного списка: один — с ведущим узлом, а другой — без ведущего узла.

2.1. Связанный список без головного узла

Связный список без головного узла создается следующим образом:

void InitList(List *L)
{
    
    
    *L=NULL;
}

То есть следующий узел связанного списка пуст.

2.2. Связанный список с ведущим узлом

Связанный список с головным узлом создается следующим образом:

void InitList(List *L)
{
    
    
    *L=(List)malloc(sizeof(LNode));
    if(L==NULL)
    {
    
    
        return ;//此时表示创建头结点失败
    }
    (*L)->next=NULL;//头结点指向的下一个节点为空
}

Преимущество головного узла в том, что когда нам нужно выполнить операцию над связным списком, нам не нужно выполнять специальные операции над первым узлом связного списка, достаточно написать фиксированную функцию для всех кодов и передать разные. Значение может реализовывать конкретную функцию высоты.

3. Вставка и удаление связанных списков

3.1. Вставка в битовом порядке

3.1.1 Ведущий узел

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

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

bool ListInsert(List *L,int i,int e)
{
    
    
    if(i<1)
    {
    
    
        return false;
    }
    LNode *p; //p表示当前指向的是哪个节点
    int j=0; //j表示的是当前指向节点的位置
    p=(*L); //目前先让p指向头节点
    while(p!=NULL&&j<i-1) //循环找到要插入节点的前一个节点
    {
    
    
        p=p->next;
        j++;
    }
    LNode *s=(LNode *)malloc(sizeof(LNode));
    s->data=e;
    s->next=p->next;
    p->next=s;
    return true;
}
3.1.2 Нет ведущего узла

Вставка узла без заголовка аналогична вставке узла с головой, но более громоздка, чем вставка узла с головой.

bool ListInsert(List *L,int i,int e)
{
    
    
    if(i<1)
    {
    
    
        return false;
    }
    if(i==1)
    {
    
    
        LNode *q=(LNode *)malloc(sizeof(LNode));
        q->data=e;
        q->next=L;
        *L=q;
    }
    LNode *p; //p表示当前指向的是哪个节点
    int j=0; //j表示的是当前指向节点的位置
    p=L; //目前先让p指向头节点
    while(p!=NULL&&j<i-1) //循环找到要插入节点的前一个节点
    {
    
    
        p=p->next;
        j++;
    }
    LNode *s=(LNode *)malloc(sizeof(LNode));
    s.data=e;
    s->next=p->next;
    p->next=s;
    return true;
}

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

3.2. Операция после вставки указанного узла

Операция вставки узла после данного узла относительно проста.Пример кода выглядит следующим образом:

bool InsertNextNode(LNode *p,int x)
{
    
    
    if(p==NULL)
    {
    
    
        return false;
    }
    LNode *s=(LNode *)malloc(sizeof(LNode));
    s->next=p->next;
    p->next=s;
    s->data=x;
    return true;
}

3.3. Вставка указанных элементов вперед

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

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

bool InsertPriorNode(LNode *p,int x)
{
    
    
    if(p==NULL)
    {
    
    
        return false;
    }
    LNode *s=(LNode *)malloc(sizeof(LNode));
    s->next=p->next;
    p->next=s;
    s->data=p->data;
    p->data=x;
    return true;
}

3.4. Удаление в битовом порядке

3.4.1 Ведущий узел

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

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

Пример кода выглядит следующим образом:

bool ListDelete(List L,int i,int x)
{
    
    
    if(i<1)
    {
    
    
        return false;
    }
    LNode *p;
    int j=0;
    p=L;
    while(p!=NULL;j<i-1)
    {
    
    
        p=p->next;
        j++;
    }
    if(p==NULL)
    {
    
    
        return false;
    }
    if(p->next==NULL)
    {
    
    
        return false;
    }
    LNode *q=p->next;
    x=q->data;
    p->next=q->next;
    free(q);
}
3.4.2 Нет ведущего узла

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

3.5.Операция удаления указанных элементов

Операция удаления аналогична операции ведущего узла, а вставка указанного элемента аналогична операции указанного элемента, поэтому я не буду здесь вдаваться в подробности!

Acho que você gosta

Origin blog.csdn.net/qq_34168477/article/details/133353385
Recomendado
Clasificación