双方向の先行リンクリストの追加、削除、チェック、および変更

双方向先行リンクリストの追加、削除、チェック、および変更
双方向リンクリストは、リンクリストの一種である二重リンクリストとも呼ばれます。その中の各データノードには、を指す2つのポインタがあります。それぞれ直接後継者と直接前任者。したがって、二重リンクリスト内の任意のノードから開始して、その先行ノードと後続ノードに簡単にアクセスできます。通常、双方向の循環リンクリストを作成します。

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
typedef int DataType;

//双向链表的建立
typedef struct ListNode
{
    
    
    int val;
    struct ListNode* prev;//指向前一个节点
    struct ListNode* next;//指向后一个节点
}ListNode;

//节点的扩容
ListNode* ListCreate(DataType x)
{
    
    
    ListNode* node = (ListNode*)malloc(sizeof(ListNode));
    node->prev = NULL;
    node->next = NULL;
    node->val = x;
    return node;
}

//头节点的建立(头节点不存储有效数据,为哨兵位节点)
ListNode* ListInit()
{
    
    
    ListNode* phead = ListCreate(0);
    phead->next = phead;
    phead->prev = phead;
    return phead;
}
//链表销毁
void ListDestory(ListNode* phead)
{
    
    
    assert(phead);
    ListNode* cur = phead;
    while (cur != phead)
    {
    
    
        ListNode* Next = cur->next;
        free(cur);
        cur = Next;
    }
    phead->next = phead;
    phead->prev = phead;
}
//链表打印
void ListPrint(ListNode* phead)
{
    
    
    printf("head<->");
    assert(phead);
    ListNode* cur = phead->next;
    while (cur != phead)
    {
    
    
        
        printf("%d<->", cur->val);
        cur = cur->next;
    }
    printf("head");
    printf("\n");
}
//尾插
void ListPushBack(ListNode* phead, DataType x)
{
    
    
    assert(phead);
    ListNode* tail = phead->prev;
    ListNode* newNode = ListCreate(x);
    newNode->prev = tail;
    tail->next = newNode;
    newNode->next = phead;
    phead->prev = newNode;
}
//尾删
void ListPopBack(ListNode* phead)
{
    
    
    assert(phead);
    assert(phead->prev != phead);
    ListNode* tail = phead->prev;
    phead->prev = tail->prev;
    tail->prev->next = phead;
    free(tail);
    tail = NULL;
}
//头插
void ListPushFront(ListNode* phead, DataType x)
{
    
    
    assert(phead);
    ListNode* newNode = ListCreate(x);
    ListNode* first = phead->next;
    phead->next = newNode;
    newNode->prev = phead;

    newNode->next = first;
    first->prev = newNode;
}
//头删
void ListPopFront(ListNode* phead)
{
    
    
    assert(phead);
    assert(phead->prev != phead);
    ListNode* first = phead->next;
    ListNode* second = phead->next->next;
    phead->next = second;
    second->prev = phead;
    free(first);
    first = NULL;
}
//中间插入
void ListInsert(ListNode* pos, DataType x)
{
    
    
    assert(pos);
    ListNode* newNode = ListCreate(x);
    ListNode* posPrev = pos->prev;
    newNode->next = pos;
    pos->prev = newNode;

    posPrev->next = newNode;
    newNode->prev = posPrev;
}
//中间删除
void ListErase(ListNode* pos)
{
    
    
    assert(pos);
    ListNode* posNext = pos->next;
    ListNode* posPrev = pos->prev;
    posPrev->next = posNext;
    posNext->prev = posPrev;
    free(pos);
}

void test1()
{
    
    
    ListNode* phead = ListInit();
    ListPushBack(phead, 4);
    ListPushBack(phead, 3);
    ListPushBack(phead, 2);
    ListPushBack(phead, 1);
    printf("尾插:");
    ListPrint(phead);

    ListPopBack(phead);
    printf("尾删:");
    ListPrint(phead);

    ListPushFront(phead, 3);
    ListPushFront(phead, 2);
    ListPushFront(phead, 1);
    printf("头插:");
    ListPrint(phead);

    ListPopFront(phead);
    printf("头删:");
    ListPrint(phead);

    ListInsert(phead->next->next->next, 0);
    ListInsert(phead->next->next->next->next->next, 0);
    printf("中间插入:");
    ListPrint(phead);

    ListErase(phead->next->next->next->next);
    printf("中间删除:");
    ListPrint(phead);

    ListDestory(phead);
    printf("链表销毁:");
    ListPrint(phead);
}

int main()
{
    
    
    test1();
    return 0;
}

実行中のスクリーンショットは次のとおりです

(2つのヘッドは実際にはノードであり、画像表現用に特別に追加されています)

おすすめ

転載: blog.csdn.net/qq_43745617/article/details/112274346