[데이터 구조] 그림과 텍스트로 연결 리스트를 논리도를 통해 쉽게 파악하고, 다양한 인터페이스 기능 구현 (2)

여기에 이미지 설명 삽입

Junxi_의 개인 홈페이지

부지런하고 아무도 기다리지 않는 세월을 격려하십시오

C/C++ 게임 개발

안녕하세요 미나님 Junxi_입니다 앞서 말씀드렸던 시퀀스 테이블에 따라 기본 데이터 구조의 내용을 계속해서 소개하겠습니다 오늘은 링크드 리스트에 대한 기본 지식과 다양한 인터페이스 구현에 대해 알려드리겠습니다 함수의 두 번째 부분 .
자, 더 이상 고민하지 않고 오늘의 공부를 시작하겠습니다!

1. 헤드리스 연결 리스트 구현

  • 마지막 연결 목록의 인터페이스 기능은 꼬리 삽입 및 꼬리 삭제로 구현되었으며 이전 내용에서 연결 목록 학습을 계속할 것입니다.
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
typedef int SLTDataType;
typedef struct SListNode
{
    
    
    SLTDataType Data;
    struct SListNode * next;

}SLTNode;
//打印链表
void SLTPrint(SLTNode* phead);
//初始化链表
SLTNode* BuySListNode(SLTDataType x);
void SLTPushBack(SLTNode** pphead, SLTDataType x);
void SLTPushFront(SLTNode** pphead, SLTDataType x);

void SLTPopBack(SLTNode** pphead);
void SLTPopFront(SLTNode** pphead);
// 找某个数
SLTNode* SLTFind(SLTNode* phead, SLTDataType x);

// 在pos之前插入x
void SLTInsert(SLTNode** pphead, SLTNode* pos, SLTDataType x);

// 在pos以后插入x
void SLTInsertAfter(SLTNode* pos, SLTDataType x);

// 删除pos位置
void SLTErase(SLTNode** pphead, SLTNode* pos);

// 删除pos的后一个位置
void SLTEraseAfter(SLTNode* pos);
//修改pos位置的值
void SLTModify(SLTNode**pphead, SLTNode* pos, SLTDataType x);
// 单链表的销毁
void SListDestroy(SLTNode** pphead);

1. 노드 SLTFind 찾기 및 노드 SLTModify 번호 수정

노드가 존재하는지 찾기

//找某个节点是否存在
SLTNode* SLTFind(SLTNode* phead, SLTDataType x)
{
    
    
    SLTNode* cur = phead;
    while (cur)
    {
    
    
        if (cur->Data == x)
            return cur;
        cur = cur->next;
    }
    printf("该节点不存在\n");
    return NULL;
}
  • 검색을 위해 각 노드에 저장된 데이터가 내가 찾고 있는 x와 같은지 비교하기 위해 연결 리스트를 순회하면 됩니다. 연결 목록.

노드 수 수정

//修改某个节点的值
void SLTModify(SLTNode** pphead, SLTNode* pos, SLTDataType x)
{
    
    
    pos->Data = x;
}

  • 이것은 위의 검색 기능과 연동할 수 있는데 먼저 노드가 존재하는지 먼저 찾아보고 찾을 수 있으면 해당 노드의 Data를 내가 원하는 x로 변경해 보겠습니다.
  • 예는 다음과 같습니다.
void TestSList2()
{
    
    
    int n = 0;
    int x = 0;
    printf("请输入需要定义的链表的长度:\n");
    scanf("%d", &n);
    printf("请输入需要放入链表中的元素,中间用空格隔开\n");
    SLTNode* plist = NULL;

    int val = 0;
    for (size_t i = 0; i < n; i++)
    {
    
    
        scanf("%d", &val);

        SLTPushBack(&plist, val);


    }
    SLTPrint(plist);
    //SLTFind(plist, 5);
    printf("请输入要修改的值\n");
    scanf("%d", &x);
    SLTNode* pos = SLTFind(plist, x);
    if (pos)
    {
    
    
        int m;
        printf("请输入要把该节点修改成什么值:\n");
        scanf("%d", &m);
        SLTModify(&plist, pos, m);
    }
    SLTPrint(plist);
}

여기에 이미지 설명 삽입

2. pos 앞에 값 SLTInsert를 삽입하고 pos 뒤에 값 SLTInsertAfter를 삽입합니다.

pos 앞에 값 삽입

// 在pos之前插入x
void SLTInsert(SLTNode** pphead, SLTNode* pos, SLTDataType x)
{
    
    
    SLTNode* cur = *pphead;
    SLTNode* newnode = BuySListNode(x);
    //如果没有节点时就得头插
    assert(pphead);
    assert(pos);
    if (pos == *pphead)
    {
    
    
        SLTPushFront(pphead, x);
    }
    else {
    
    
        while (cur->next)
        {
    
    
            if (cur->next->Data == pos->Data)
            {
    
    
                cur->next = newnode;
                newnode->next = pos;
            }
            cur = cur->next;

        }
    }
}
  • 특별한 경우 분석:
  • pos를 삽입하기 전에 다음 위치를 고려해야 합니다. 1. pos는 합법적입니까? 2. pphead가 비어 있는지 여부
  • 위의 두 가지를 판단한 후 이제 pos의 특수 삽입을 고려해야 합니다. 만약 우리의 pos가 연결 목록의 선두에 있다면 우리의 pos 앞의 삽입은 우리의 머리 삽입과 같습니다. 그렇지 않다면 우리는 다음을 분석할 것입니다. 논리도를 통한 일반적인 상황
    여기에 이미지 설명 삽입
    여기에 이미지 설명 삽입

pos 뒤에 x 삽입

// 在pos以后插入x
void SLTInsertAfter(SLTNode* pos, SLTDataType x)
{
    
    
    SLTNode* cur = BuySListNode(x);
    cur->next = pos->next;
    pos->next = cur;

}
  • 이 부분은 비교적 간단하게 이전 SLTFind를 통해 pos의 위치를 ​​찾고, 삽입하고자 하는 cur 옆에 있는 다음 노드의 주소를 부여하고, pos의 다음 노드가 cur을 가리키도록 합니다.

3. pos 위치에서 SLTErase 값을 삭제하고 pos의 다음 자리에서 SLTEraseAfter 값을 삭제합니다.

pos 위치 값 삭제

// 删除pos位置
void SLTErase(SLTNode** pphead, SLTNode* pos)
{
    
    
    SLTNode* cur = *pphead;
    assert(pos);
    assert(pphead);
    if (pos == *pphead)
    {
    
    
        SLTPopFront(pphead);
    }
    
    else
    {
    
    
        while (cur)
        {
    
    
            if (cur->next == pos)
            {
    
    
                cur->next = pos->next;
                free(pos);
            }
            cur = cur->next;
        }

    }
        
}
  • assertion의 분석은 위와 동일하며 여기서는 반복하지 않겠습니다. 여기서는 삭제합니다. pos가 헤더에 있을 때 이 노드를 삭제하는 것은 헤더 삭제입니다. 일반적으로 논리 분석 다이어그램은 다음과 같습니다.
    여기에 이미지 설명 삽입

여기에 이미지 설명 삽입

pos의 마지막 자리 값을 삭제합니다.

// 删除pos的后一个位置
void SLTEraseAfter(SLTNode* pos)
{
    
    
    assert(pos);
    //检查是否是尾节点
    assert(pos->next);
    pos->next = pos->next->next;
    free(pos->next);
    pos->next = NULL;
}
  • 이제 우리는 pos를 알았으므로 다음 pos를 삭제하려면 pos의 다음을 다음 노드의 다음 노드로 가리키고 마지막으로 해제(pos->next)한 다음 비워둡니다.

4. 단일 연결 리스트의 소멸

  • 연결된 목록이 모두 사용되면 단일 연결 목록이 동적으로 개발되기 때문에 해제한 다음 비워야 합니다.
// 单链表的销毁
void SListDestroy(SLTNode** pphead)
{
    
    
    assert(pphead);
    SLTNode* cur = *pphead;
    while (cur)
    {
    
    
        SLTNode* next = cur->next;
        free(cur);
        cur = next;
    }
    *pphead = NULL;
}
  • 순회를 통해 각 노드가 해제되고 마지막으로 헤드 포인터가 비어 있는 상태로 설정되고 연결 목록이 소멸됩니다.

요약하다

  • 제한된 공간으로 인해 오늘의 내용은 여기까지입니다. 이 기사에서 우리는 나머지 인터페이스에 대한 이야기를 마쳤습니다. 그 후 연결 목록의 실제 적용에 더 익숙해질 수 있도록 몇 가지 oj 질문을 하도록 안내할 것입니다. . 항상 고수할 수 있다면 연결된 목록에 대한 기본 지식이 충분할 것입니다! 코드를 직접 입력하는 것을 잊지 마세요!

  • 그럼 궁금하신 점은 댓글이나 비밀댓글로 물어봐주세요 다음에 또 만나요!

초보 블로거가 만들기 쉽지 않으니 글의 내용이 도움이 되셨다면 이 초보 블로거를 클릭하셔서 떠나시는 것도 좋을 것 같습니다. 귀하의 지원은 업데이트에 대한 동기 부여입니다! ! !

**(케리 블로거 3연속 응원 부탁드립니다!!! 아래 댓글을 눌러 좋아요를 누르고 케리를 도와주세요)**

여기에 이미지 설명 삽입

Supongo que te gusta

Origin blog.csdn.net/syf666250/article/details/132050386
Recomendado
Clasificación