C/C++ 데이터 구조---단일 연결 리스트 역전(PTA)

홈페이지:

아직 탐색을 기다리는 미지의 요소가 있습니다_데이터 구조, C 언어의 어려움, 소규모 프로젝트-CSDN 블로그

주제 열:

데이터 구조_아직 탐색을 기다리는 알려지지 않은 블로그가 있습니다-CSDN 블로그

목차

I. 소개

2. 제목

기능 인터페이스 정의:

샘플 심판 테스트 절차:

출력 샘플:

3. 이해 + 코드

1. 이해하다

2.분석 

3.코드 


I. 소개

        자료 구조를 처음 배우는 분들은 가장 기본적이고 간단한 예제도 능숙하게 작성해 주시고, 작성하실 때마다 구조에 대한 이해도가 높아지며, 좀 더 어려운 지식을 위한 탄탄한 기초가 다져지실 것입니다. 미래. ! 남의 코드를 무작정 복사해서는 안 되고, 결국은 직접 작성해야 합니다!

2. 제목

이 질문에는 주어진 단일 연결 목록을 뒤집는 함수의 구현이 필요합니다.

기능 인터페이스 정의:

List Reverse( List L );

구조 List는 다음과 같이 정의됩니다.

typedef struct Node *PtrToNode;
struct Node {
    ElementType Data; /* 存储结点数据 */
    PtrToNode   Next; /* 指向下一个结点的指针 */
};
typedef PtrToNode List; /* 定义单链表类型 */

L단일 연결 목록이 주어지면 함수는 Reverse역방향 연결 목록을 반환해야 합니다.

샘플 심판 테스트 절차:

#include <stdio.h>
#include <stdlib.h>

typedef int ElementType;
typedef struct Node *PtrToNode;
struct Node {
    ElementType Data;
    PtrToNode   Next;
};
typedef PtrToNode List;

List Read(); /* 细节在此不表 */
void Print( List L ); /* 细节在此不表 */

List Reverse( List L );

int main()
{
    List L1, L2;
    L1 = Read();
    L2 = Reverse(L1);
    Print(L1);
    Print(L2);
    return 0;
}

/* 你的代码将被嵌在这里 */

5
1 3 4 5 2

출력 샘플:

1
2 5 4 3 1

코드 길이 제한

16KB

시간 제한

400ms

메모리 제한

64MB

3. 이해 + 코드

1. 이해하다

이 질문을 보면, 이전에 배웠던 문자열 반전과 매우 유사한 것처럼 갑자기 매우 친숙하게 느껴질 수도 있습니다.

문자열 반전 에 대한 많은 아이디어가 있습니다 .

1. 비재귀적: 두 개의 변수를 사용합니다. 하나의 변수 left는 문자열의 첫 번째 문자를 가리키고 다른 변수 right는 문자열의 마지막 문자를 가리킨 다음 이를 교환하여 끝 기호를 결정합니다. (키코드는 다음과 같습니다)

while(left<right)
{
    //交换
}

2. 재귀, 재귀의 특성에 따른 역순 구현

#include<stdio.h>
int my_strlen(char* arr)
{
	if (*arr != '\0')
		return 1 + my_strlen(arr + 1);
	else
		return 0;
}
char* rev(char* arr)
{
	char tmp = *arr;
	int len = my_strlen(arr);
	*arr = *(arr + len - 1);
	*(arr + len - 1) = '\0';
	if (my_strlen(arr+1) >=2)
		rev(arr + 1);
	*(arr + len - 1) = tmp;
}
int main()
{
	char arr[] = "abcdef";
	rev(arr);
	printf("%s", arr);
	return 0;
}

질문: 그런데 단일 연결 리스트의 역순도 이런 방식으로 사용할 수 있나요?

답변: 1. 첫 번째 아이디어를 사용하는 경우 마지막 노드에 대한 포인터를 어떻게 앞으로 이동합니까?이렇게 하려면 마지막 노드만 원하는 이전 노드의 주소를 찾는 루프가 필요하므로 더 번거롭습니다. 2. 두 번째 아이디어를 사용한다면 그냥 종이에 적어서 사용하면 될 것 같아요. 모두가 생각해 볼 수 있는 작은 질문이 있습니다. ) 달성).

2.분석 

문자열 반전에 사용된 아이디어 외에도 연결 리스트의 특성을 기반으로 이 단일 연결 리스트의 반전을 완료할 수 있는 방법이 있습니까?

연결리스트를 생성할 때 head 삽입 방식과 tail 삽입 방식 두 가지 방법을 소개했는데, 이 두 가지 방식의 특징은 무엇인가요? 아직도 기억하시나요? (기억나지 않는 링크는 다음과 같습니다.) 데이터 구조---시퀀스 테이블---체인 저장 구조 1(선행 노드 없음)_아직 탐색을 기다리는 알려지지 않은 블로그가 있습니다-CSDN 블로그 

헤드 보간과 테일 보간의 가장 중요한 특징은 데이터 저장 순서와 생성 후 입력 데이터의 순서입니다. 헤드 보간법은 입력 데이터의 순서와 저장 순서가 반대되는 방식이고, 테일 보간법은 입력 데이터의 순서와 저장 순서가 동일한 방식이다.

그러면 헤드 보간(head interpolation)이라는 개념에 따라 단일 연결 리스트의 데이터를 순서대로 하나씩 읽은 후 헤드 보간 방법을 사용하여 새로운 연결 리스트를 생성하여 저장할 수 있을까요? 대답은 '예'입니다. 게다가 이 방법은 이전 아이디어보다 간단하고 연결 목록의 일부 특성을 더 잘 구현합니다.

  //head 삽입 방법은 이전 글에서도 설명한 것처럼 head가 비어 있는지 여부를 판단할 필요가 없습니다.

3.코드 

List Reverse( List L )
{
    List p=L,head=NULL,q;//创建一个头指针
    //头插法不需要对head是否为空进行判断,再之前的文章中也讲解过
    while(p!=NULL)
    {
        q=(List)malloc(sizeof(struct Node));
        q->Next=NULL;
        q->Data=p->Data;
        q->Next=head;
        head=q;
        p=p->Next;
    }
    if(L!=NULL)
        L->Next=NULL;
    return head;
}

 당신의 지원에 감사드립니다!

추천

출처blog.csdn.net/qq_73435980/article/details/133345851