중화사전망 - 자전 검색 - 교육 요청: c++ 에서 클래스를 사용하여 간단한 단방향 연결된 목록을 구현하는 방법
교육 요청: c++ 에서 클래스를 사용하여 간단한 단방향 연결된 목록을 구현하는 방법
그러나 집주인의 문제를 보면 체인리스트를 이해하지 못하는 것 같다. 여기에는 객체 지향이 포함되지 않습니다.
담호강의 C 프로그래밍에서 몇 가지 자료를 드리겠습니다.
제가 /c 에 도착할 수 있을까요? M = 9d78d513d9d437a84f9ae4690 c66c0161e43f1652bd66c 7 e2ac 26520775 d 0d 20b1616d9484b9ef00p = 85769 a44c e9711 사용자 = 바이두
보세요, 이 코드는 더 자연스러울 겁니다.
10.7 포인터로 연결된 목록 처리
10.7. 1 체인 레이블 개요
연결된 목록은 일반적이고 중요한 데이터 구조입니다. 스토리지를 동적으로 할당하는 구조입니다. 아시다시피, 데이터를 배열로 저장할 때,
고정 길이 (즉, 요소 수) 를 미리 정의해야 합니다. 예를 들어, 어떤 반에는 100 명의 학생이 있고, 어떤 반에는 30 명의 학생만 있다. 서로 다른 클래스의 학생 데이터를 동일한 배열로 연속적으로 저장하려면 길이가 100 인 배열을 정의해야 합니다. 한 반의 최대 대학생 수를 미리 결정하기가 어렵다면 배열을 충분히 크게 설정해야 한다. 모든 반의 학생 데이터를 저장하기 위해서, 분명히 이렇게 하면 메모리가 낭비될 것이다. 연결된 목록에는 이러한 단점이 없으므로 필요에 따라 메모리 장치를 엽니 다. 그림 10. 1 1 은 연결된 목록의 가장 간단한 구조 (단방향 연결된 테이블) 를 나타냅니다. 연결된 목록에는 head 로 표시된 "head pointer" 변수가 있으며, 이 변수에는 주소가 저장됩니다.
주소는 요소를 가리킵니다. 연결된 목록의 각 요소를 "노드" 라고 하며 각 노드에는 두 개의 섹션이 포함되어야 합니다. 하나는 사용자가 실제로 필요로 하는 데이터이고 다른 하나는 다음 노드의 주소입니다. 보시다시피 head 는 첫 번째 요소를 가리키고 있습니다. 첫 번째 요소는 두 번째 요소를 가리킵니다. 더 이상 다른 요소를 가리키지 않는 마지막 요소를 "바닥글" 이라고 하며 주소 섹션에 "NULL" (빈 주소) 을 배치합니다. 연결된 목록은 여기서 끝납니다.
연결된 목록의 각 요소가 스토리지에 연속적으로 저장되지 않을 수 있음을 알 수 있습니다. 요소를 찾으려면 먼저 이전 요소를 찾은 다음 제공하는 다음 요소의 주소를 기준으로 다음 요소를 찾을 수 있습니다.
"헤드" 를 제공하지 않으면 전체 체인 테이블에 액세스할 수 없습니다. 체인리스트는 같은 체인과 같고, 한 고리는 고리로 묶여져 있고, 중간은 끊을 수 없다. 통속적인 예를 들어 유치원 선생님은 아이들을 데리고 산책을 나가고, 선생님은 첫 번째 아이의 손을 잡고, 첫 번째 어린이는 다른 손으로 두 번째 아이를 잡고. 이것은' 체인' 이고, 마지막 아이는 하나가 있다.
이 연결된 목록의 데이터 구조는 포인터 변수를 사용하여 구현해야 한다는 것을 알 수 있습니다.
즉, 한 노드에 다음 노드의 주소를 저장하는 포인터 변수가 있어야 합니다.
구조 변수는 이전에 여러 멤버를 포함하는 구조 변수에 대해 설명했습니다. 이러한 멤버는 숫자 유형, 문자 유형, 배열 유형 또는 포인터 유형일 수 있습니다. 이 포인터 유형은 다른 구조 유형을 가리키는 데이터이거나 해당 유형이 있는 구조 유형을 가리킬 수 있습니다. 예를 들면 다음과 같습니다.
구조학생
{int num
부동 점수
구조 학생 * 다음;
Next 는 멤버 이름이고 struct student 유형의 데이터 (next 가 있는 구조 유형) 를 가리키는 포인터 유형입니다. 이렇게 하면 연결된 목록을 만들 수 있습니다. 그림 10. 12 를 참조하십시오.
각 노드는 struct student 유형이며 멤버 next 는 다음 노드의 주소를 저장하므로 프로그래머는 주소 값을 구체적으로 알 필요가 없습니다.
다음 노드의 주소가 이전 노드의 다음 구성원에 있는지 확인하기만 하면 됩니다.
단 하나의 struct student 유형만 위에 정의되어 있으며 실제로 스토리지 공간이 할당되지 않았습니다. 앞서 언급했듯이 연결된 목록 구조는 필요에 따라 노드의 스토리지 장치를 여는 스토리지를 동적으로 할당합니다. 스토리지 장치를 동적으로 열고 해제하려면 어떻게 해야 합니까? C 언어 컴파일 시스템의 라이브러리 함수는 다음과 같은 관련 함수를 제공합니다.
1.malloc(size) 는 메모리의 동적 저장소 영역에 크기가 인 연속 공간을 할당합니다.
이 함수의 값 ("반환 값") 은 할당 필드의 시작 주소인 포인터입니다. 함수 실행이 실패하면 반환 값은 0 입니다.
2.calloc(n, size) 는 메모리의 동적 영역 저장소에 size 길이의 n 개의 연속 공간을 할당합니다. 이 함수는 할당 도메인의 초기 주소를 반환합니다. 할당에 실패하면 0 을 반환합니다.
3.free(ptr) ptr 이 가리키는 메모리 영역을 해제합니다. Ptr 은 ca 1 1 또는 ma 1 1oc 함수를 마지막으로 호출한 값입니다.
위의 세 가지 함수 중 매개변수 n 과 size 는 정수이고 ptr 은 문자 포인터입니다.
C 버전에서 제공하는 많은 malloc 및 call0c 함수는 문자 데이터를 가져오는 포인터입니다. 새 표준 c 에서 제공하는 ma 1 10c 및 ca 1 1oc 함수는 void* 유형으로 정의됩니다.
이 섹션에서 설명하는 예비 지식을 통해 연결된 목록 작성, 연결된 목록에서 노드 삽입 또는 삭제 등 아래 연결된 목록을 조작할 수 있습니다. ). 일부 개념은 후기 응용에서 점진적으로 확립되고 숙달되어야 한다.
10.7.2 연결된 목록 작성
체인 테이블 빌드란 0 부터 시작하는 체인 테이블을 구성하는 것입니다. 즉, 각 노드에 대한 데이터를 하나씩 입력하여 전후 단계 관계를 설정하는 것입니다. 다음은 연결된 목록을 만드는 방법의 예입니다.
[예 10.7] 5 명의 학생의 데이터로 단방향 링크리스트를 만드는 함수를 작성합니다.
먼저 이 요구 사항을 구현하는 알고리즘을 고려해 보십시오 (그림 10 참조). 13).
Head, p 1, p2 의 세 가지 포인터 변수를 설정하여 모두 구조 유형 데이터를 가리킵니다. 먼저 mal 1oc 함수를 사용하여 p 1, p2 가 가리키는 노드를 엽니다.
그런 다음 키보드에서 학생의 데이터를 pl 이 가리키는 노드로 읽습니다. 우리는 학생 수가 0 이 되지 않는다는 것에 동의한다. 학번을 0 으로 입력하면 연결된 목록을 만드는 프로세스가 완료되며 해당 노드는 연결된 테이블에 연결하지 않아야 합니다. 먼저 head 의 값을 NULL (0) 로 지정합니다. 이는 연결된 테이블이 "null" 인 경우 (즉, head 가 어떤 노드도 가리키지 않고 연결된 테이블에 노드가 없는 경우) head 가 해당 노드를 가리키도록 노드를 추가합니다.
Pl >: num 이 0 이 아닌 경우 첫 번째 노드 데이터 (n= 1) 를 입력할 때 head=p 1 을 설정합니다.
즉, p 1 값을 머리에 할당합니다. 즉, 머리도 새로 열린 노드를 가리키게 합니다 (그림 10. 14). P 1 가리키는 새로 열린 노드가 연결된 목록의 첫 번째 노드가 됩니다. 그런 다음 다른 노드를 열어 p 1 을 가리키고 이 노드의 데이터 (그림 65438 참조) NUM 을 읽습니다! =0, 두 번째 노드 (n=2) 에 연결해야 합니다. n! = 1, p 1 값은 p2->; 다음으로 첫 번째 노드의 다음 구성원이 두 번째 노드를 가리키도록 합니다 (10. 15(b) 그림 참조). 그런 다음 p2=p 1 을 설정합니다.
즉, 10. 15(c) 와 같이 p2 가 방금 만든 노드를 가리키게 합니다. 그런 다음 다른 노드를 열어 pl 이 해당 노드를 가리키고 해당 노드의 데이터를 읽도록 합니다 (예: 10. 16(a)). 세 번째 기간에서 n=3(n! = 1), pl 값이 p2->; 다음으로 세 번째 노드를 두 번째 노드에 연결하여 p2=p 1 을 만들고 p2 가 마지막 노드를 가리키도록 합니다 (그림 10. 16(b 참조)
그런 다음 새 노드를 열고 pl 이 해당 노드를 가리키도록 합니다.
이 노드에 대한 데이터를 입력합니다 (그림 10. 17(a) 참조). 왜냐하면 pl->; Num 값이 0 이면 루프가 더 이상 실행되지 않으며 새 노드가 연결된 목록에 연결되지 않아야 합니다. 이 시점에서 NULL 은 p2->; 다음 그림은 10. 17(b) 과 같습니다. 연결된 목록을 만드는 과정은 이것으로 끝납니다. Pl 이 마지막으로 가리키는 노드는 연결된 목록에 링크되지 않고 세 번째 노드의 다음 멤버 값은 NULL 이며 어떤 노드도 가리키지 않습니다. Pl 이 새로 열린 노드를 가리키지만 연결된 목록에서 찾을 수 없습니다.
연결된 목록을 만드는 기능은 다음과 같습니다.
# 정의 NULL 0
#define LEN sizeof (구조 학생)
구조학생
{1ONG num;
부동 점수
구조 학생 * 다음;
}
Int n;;
Struct student *creat ()
/* 이 함수는 연결된 헤더에 대한 포인터를 반환합니다 */
{구조 학생 * 머리;
Struct student *p 1, * p2
N = 0;;
P 1=p2= (구조학생 *) mal1oc (len); /* 새 모듈 만들기 */
Scanf("%ld, %f ",& ampPl 1 > 숫자 & ampPl 1 > 점수);
Head=NULL:
While (pl->; Num! =0)
{n=n 101;
If (n = =1) head = pl;
Elsep2-> next = p1;
P2 = pl
Pl= (구조학생 *) 말론 (len);
Scanf("% 1d, %f ",& ampp1->; 숫자 & ampPl 1 > 점수);
}
P2 one > next = NULL;;
반환 (머리);
}
다음 사항에 유의하십시오.
(1) 첫 번째 행은 #define 명령줄입니다. 여기서 NULL 은 0 을 나타내고' 빈 주소' 를 나타냅니다. 두 번째 행은 struct student 구조 유형의 데이터 길이를 나타내는 LEN 입니다.
Sizeof 는 바이트 수를 찾는 데 사용되는 연산자입니다.
(2) 9 행은 포인터 유형인 creat 함수를 정의합니다. 즉, 이 함수는 struct student 유형의 데이터를 가리키는 포인터 값을 반환합니다. 실제로 이 creat 함수는 sizeof(struct student) 로 정의된 체인 (3)malloc(LEN) 을 가져와 구조 struct student 의 길이인 LEN 길이의 메모리 영역을 엽니다. 일반 시스템에서 CREAT 함수는 체인 (LEN) 을 반환합니다.
P 1, p2 는 struct student 유형의 데이터에 대한 포인터 변수이며, 서로 다른 유형의 데이터를 참조하므로 허용되지 않습니다. 따라서 malloc (LEN) 앞에 "(struct student*)" 를 추가하여 유형 변환을 강제하는 방법을 사용해야 합니다. 이는 malloc 에서 반환한 포인터를 struct student 유형의 데이터에 대한 포인터로 변환하는 데 사용됩니다. *' 번호는 생략할 수 없습니다. 그렇지 않으면 포인터 유형 대신 struct student 유형으로 변환됩니다.
(4) 마지막 행에서 반환된 인수는 head 입니다 (head 는 이미 struct student 유형의 데이터를 가리키는 포인터 변수로 정의됨). 따라서 함수는 연결된 목록의 헤더 주소인 head 의 값을 반환합니다.
(5)n 은 노드 수입니다.
(6) 이 알고리즘은 pl 이 새로 열린 노드를 가리키고, p2 가 연결된 목록의 마지막 노드를 가리키고, pl 이 가리키는 노드를 p2 가 가리키는 노드 뒤에 연결하고 "P2->; Next=pl "입니다.
연결된 목록 작성 프로세스에 대해 자세히 설명합니다.
독자가 연결된 목록을 만드는 과정을 잘 알고 있다면 아래에 설명된 삭제 및 삽입 과정을 쉽게 이해할 수 있습니다.
10.7.3 체인 밀 출력
연결된 목록의 각 노드에 대한 데이터를 차례로 출력합니다. 이 문제는 비교적 잘 처리한다. 먼저 연결된 목록 head 요소의 주소, 즉 head 의 값을 알아야 합니다. 그런 다음 포인터 변수 P 를 설정하여 첫 번째 노드를 가리키고 P 가 가리키는 노드를 출력한 다음 연결된 테이블의 끝 노드까지 P 를 한 노드 뒤로 이동시킵니다.
[예 10.8] 출력 체인 테이블의 함수 print 를 작성합니다.
무효 인쇄 (헤더)
구조 학생 * 머리;
{structstudent * p;
Printf(" \n 이제 이러한% d 레코드는 다음과 같습니다. \ n ",n);
P = 머리;
만약! = 비어 있음)
하다
{printf("%ld%5. 1f\ ",p->; Num, p-> 점수);
P=p one > 다음;
}while(p! = null);
이 알고리즘은 그림 10. 18 로 나타낼 수 있습니다.
이 절차는 10. 19 와 같이 나타낼 수 있습니다. P 는 첫 번째 노드를 가리키고 첫 번째 노드가 출력되면 P 는 그림의 대시 위치로 이동하여 두 번째 노드를 가리킵니다. 프로그램에서 p = p->; Next 의 역할은 p 가 처음에 가리키는 노드의 next 값을 p 에 할당하는 것입니다.
그리고 p->; Next 값은 두 번째 노드의 시작 주소입니다. P 에 할당한다는 것은 p 가 두 번째 노드를 가리킨다는 것을 의미합니다.
Head 의 값은 인수를 통해 전달됩니다. 즉, 기존 연결된 목록의 헤더 포인터를 호출된 함수에 전달하고 노드는 인쇄 함수에서 head 가 가리키는 첫 번째 노드부터 순차적으로 출력됩니다.
10.7.4 체인 밀 삭제
연결된 목록이 있습니다. 노드 중 하나를 삭제하고 싶습니다. 이 문제에 대한 알고리즘을 어떻게 고려할지, 먼저 예를 들어 봅시다.
한 무리의 아이들 (a, b, c, d, e) 이 손을 잡고 있다. 아이 (C) 가 어떤 일 때문에 팀을 떠나야 하는데 포메이션이 변하지 않는다면 양쪽에서 C 의 손을 풀기만 하면 B 는 D 와 손을 잡고 대체할 수 있다. 그림 10.20. 그림 10.20(a) 은 그림 665 와 같이 원래 팀입니다.
마찬가지로, 연결된 목록에서 노드를 제거하는 것은 실제로 메모리에서 지우는 것이 아니라 연결된 목록에서 노드를 분리하는 것입니다. 즉, 링크 관계가 변경됩니다.
[예 10.9] 함수를 작성하여 지정된 노드를 삭제합니다.
지정된 학번을 노드 삭제 기호로 사용합니다. 예를 들어 89 103 을 입력하면 학번이 89 103 인 노드를 삭제해야 합니다. 문제를 해결하는 방법은 P 가 가리키는 첫 번째 노드부터 시작하여 이 노드의 num 값이 삭제해야 할 학번과 같은지 확인하는 것입니다. 같으면 노드를 삭제합니다. 그렇지 않은 경우 p 를 한 노드로 다시 이동하는 등. 테이블 끝에 닿을 때까지 아래로 가세요.
P 1 이 첫 번째 노드를 먼저 가리키도록 두 개의 포인터 변수 P 1 및 p2 를 설정할 수 있습니다 (그림 10.5438+0 (a)). 제거할 첫 번째 노드가 아닌 경우
그런 다음 pl 을 다음 노드로 다시 가리킵니다 (pl->; 다음은 P 1) 에 할당됩니다. 이전에는 p2 가 방금 검사한 노드 (예: 10.2 1(b)) 를 가리키도록 pl 값을 p2 에 지정해야 했습니다. 따라서 P 는 제거할 노드를 찾거나 전체 링크 목록을 검사하여 제거할 노드를 찾을 수 없을 때까지 계속 뒤로 이동합니다. 노드가 제거된 것을 발견하면 두 가지 상황을 구분해야 한다: ①. 다음은 책임자에게 배정됩니다. 그림 10.438+0 (c) 을 참조하십시오.
이제 머리가 원래의 두 번째 노드를 가리킵니다. 첫 번째 노드는 여전히 존재하지만 연결된 목록에 요소나 머리 포인터가 없기 때문에 연결된 목록에서 분리됩니다. P 1 은 여전히 그것을 가리키거나 두 번째 노드를 가리키지만 여전히 쓸모가 없습니다. 이제 연결된 목록의 첫 번째 노드는 원래의 두 번째 노드이고 원래 첫 번째 노드는 "누락" 됩니다. ② 첫 번째로 삭제된 노드가 아니면 pl 1 입니다. Next 는10.21(d) .p2->; Next 는 원래 pl 이 가리키는 노드 (그림의 두 번째 노드) 를 가리키고 지금은 p2->; 다음으로 p1->; 다음 가리키는 노드
가리키는 노드. Pl 은 더 이상 연결된 목록의 일부가 아닙니다.
연결된 목록이 비어 있고 (노드 없음) 연결된 목록에 제거할 노드가 없는 경우에도 고려해야 합니다.
그림 10.22 는 이 문제를 해결하는 알고리즘을 보여 줍니다.
노드 삭제 함수 del 은 다음과 같습니다.
Struct student *del (헤드, 수)
구조 학생 * 머리;
1ONG num;
{struct student *p 1, * p2
If (head = = null) {printf ("\ n list null! \ n "); 끝으로 이동 }
P 1 = 머리;
Whi 1e (번호! = plone > num&& pl-gt; 다음! A NULL)/*pl 은 찾고자 하는 노드를 가리키지 않습니다. 노드 점 */
{p2 = p1; Pl = pl->; 다음으로, }/* 한 노드 뒤로 이동 */
If (num = = pl->; Num) /* 찾음 */
{if (n1= = 헤드) 헤드 = pl->; 다음으로, /* pl 이 헤드 노드를 가리키면 두 번째 노드 주소를 head*/
E1sep2->; Next = pl one > next/* 그렇지 않으면 다음 노드 주소를 이전 노드 주소에 할당합니다 * \
Printf ("삭제:% LD \ n", num);
N = n-1;
}
Else printf("%ld 을 (를) 찾을 수 없습니다! \n ",번호); /* 노드를 찾을 수 없음 */
끝:
반환 (머리);
}
이 함수의 유형은 struct student 유형의 데이터에 대한 포인터입니다.
그 값은 연결된 목록의 헤드 포인터입니다. 삭제할 함수 매개 변수 head 및 학번 num.head 의 값은 함수 실행 중에 변경할 수 있습니다 (첫 번째 노드를 삭제할 때).
10.7.5 연결된 목록의 삽입 작업
노드를 기존 연결된 목록에 삽입합니다. 기존 연결된 목록에 있는 각 노드의 멤버 항목 num (학번) 을 학번이 작은 것부터 큰 것까지 순서대로 정렬하도록 합니다.
포인터 변수 P0 을 사용하여 삽입할 노드를 가리키고 pl 을 사용하여 첫 번째 노드를 가리킵니다. 그림 10.23(a) 을 참조하십시오.
P0 a >: Num 및 pl->; Num, P0 >:num & gt;; Pl-gt; Num, 삽입할 노드는 pl 이 가리키는 노드 앞에 삽입해서는 안 됩니다. 이제 pl 이 뒤로 이동하고 p2 가 10.23(b) 과 같이 pl 이 방금 가리키는 노드를 가리킵니다. 그런 다음 p1>; Num 및 P0 > Num 비율. 그래도 P0->; Num 이 크면 pl 은 P0->; 누넘. 이때 pl 에서 참조하는 노드 앞에 P0 에서 참조하는 노드가 삽입됩니다. 그러나 p 1 이 바닥글 노드를 참조하는 경우 pl 이 뒤로 이동하지 않아야 합니다. P0->; Num 은 모든 노드의 수보다 큽니다.
그런 다음 P0 으로 표시된 노드는 연결된 목록의 끝에 삽입해야 합니다.
삽입 위치가 첫 번째 노드 앞이나 바닥글 노드 뒤에 있지 않은 경우 P0 의 값이 p2->; 다음으로 p2 가 >: Next 가 삽입할 노드를 가리키고 P0->; 다음으로, P0 > Next 가 pl 이 가리키는 변수를 얻더라도. 그림 10.23(c) 을 참조하십시오. 표시된 대로 첫 번째 노드와 두 번째 노드 사이에 새 노드가 삽입됩니다.
삽입 위치가 첫 번째 노드 앞에 있는 경우 (즉, pl 이 head 와 같은 경우) ,
그런 다음 P0 을 head 에 할당하고 p 1 을 P0->; 다음. 그림 10.23(d) 참조. 바닥글 뒤에 삽입하려면 P0 을 pl->; 다음으로 NULL 은 P0->; 다음으로 그림 10.23(e) 을 참조하십시오.
위의 알고리즘은 그림 10.24 로 나타낼 수 있습니다.
[예 10. 10] 노드를 삽입하는 insert 함수는 다음과 같습니다.
구조 학생 * 삽입 (머리, 스터드)
구조 학생 * 머리, * 스터드:
{struct student *p0, *p 1, * p2
Pl = 머리; /* pl 이 첫 번째 노드를 가리키도록 설정 */
P0 = 스터드; /*p0 삽입할 노드를 가리킵니다 */
If (head==NULL)/* 결과는 빈 테이블 */
{head = p0p0i > next = NULL;; }/* P0 이 가리키는 노드를 첫 번째 노드로 사용 */
기타
{while((P0 > num>;; Pl-gt; Num)& amp;; & amp(pl I > 다음! =NULL))
{p2 = p1; P1= pl->; 다음으로, }/*p2 는 pl 이 방금 가리킨 노드를 가리키고 p 1 한 노드 뒤로 이동 */
만약 (P0-& gt;; Numnext = p0/* p2 가 가리키는 노드 뒤에 */
P0-> Next = p1; }
기타
{pl I > next = p0p0i > next = NULL;; }}/* 마지막 노드 뒤에 */
N = n+1; /* 노드 수와 1*/
반환 (머리);
}
함수 인수는 head 및 stud.stud 이며 삽입할 노드의 주소가 실제 인수에서 stud 로 전송되는 포인터 변수입니다. 문 p0=stud 는 P0 이 삽입할 노드를 가리키게 하는 역할을 합니다.
함수 유형은 포인터 유형이고 함수 값은 연결된 테이블의 시작 주소 헤더입니다.
위의 생성, 출력, 삭제, 삽입 등의 기능을 하나의 프로그램으로 구성하여 주 함수를 주 함수로 사용합니다. 너는 아래의 메인 함수를 쓸 수 있다.
주 ()
{struct 학생 * 헤드, stu
1ONG de1_ num;
Printf ("입력 레코드: \ n");
Head = creat (); /* 헤드 포인터 반환 */
인쇄 (머리); /* 모든 노드 내보내기 */
Printf(" \ n 삭제된 0 번 입력: ");
Scanf("%ld ",& ampde1_ μ m); /* 삭제할 학번 입력 */
Head=del(head, de1_ num); /* 삭제된 제목 주소 */
인쇄 (머리); /* 모든 노드 내보내기 */
Prinif ("/put the inserted record:")/* 삽입할 레코드 입력 */
Scanf("%ld, %f ",& ampstu.num & Stu.score);
Head = insert(head & amp;; Stu); /* 회신 주소 */
인쇄 (머리);
}
이 프로그램의 실행 결과는 정확하다.
하나의 노드만 삭제하고 하나의 노드를 삽입합니다. 그러나 다른 노드를 삽입하려면 프로그램의 마지막 네 줄을 반복합니다. 즉, * * * 두 노드를 삽입합니다. 실행 결과가 잘못되었습니다.
레코드 입력: (연결된 목록 생성)
89 10 1,90
89 103,98
89 105,76
0,0
자, 이 세 가지 기록은 다음과 같습니다.
89 10 1 90.0
89 103 98.0
89 105 76.0
삭제된 번호 입력:
89 103 (삭제됨)
삭제: 89 103
자, 이 두 기록은 다음과 같습니다.
8910190.0 89105 76.0
삽입된 레코드 입력: 89 102
90 (첫 번째 노드 삽입)
자, 이 세 가지 기록은 다음과 같습니다.
89 10 1 90.0
89 102 90.0
89 105 76.0
삽입된 레코드 입력: 89104,99/(두 번째 노드 삽입)
자, 이 네 가지 기록은 다음과 같습니다.
89 10 1 90.0
89 104 99.0
89 104 99.0
89 104 99.0
...
...
(출력 노드 데이터 89 104 종료 없음)
독자에게 main 과 insert 함수를 결합하여 이러한 실행 결과가 발생하는 이유를 조사하도록 요청합니다.
위의 결과는 stu 가 고정 주소가 있는 변수이기 때문입니다. Stu 노드는 처음으로 연결된 목록을 삽입하고, 두 번째는 두 번째 노드를 삽입하는 데 사용되며, 첫 번째 노드의 데이터는 지워집니다.
실제로 두 개의 노드가 만들어지지 않았습니다. 독자는 이제 insert 함수에 따라 연결된 목록을 그릴 수 있습니다. 이 문제를 해결하려면 각 노드가 삽입될 때 새 저장소를 만들어야 합니다. Main 함수를 수정하여 삭제할 학번이 0 이 될 때까지 여러 노드를 삭제하고 삽입할 학번이 0 이 될 때까지 여러 노드를 삽입합니다.
주요 기능은 다음과 같습니다.
주 ()
{struct student * head *, stu
1ONG de1_ num;
Printf ("입력 레코드:/n");
Head = creat ();
인쇄 (머리);
Printf("/n 삭제된 번호 입력: ");
Scanf("% 1d ",& ampdel _ num);
While (de 1_num! =0)
{head = del (헤드, del _ num);
인쇄 (머리);
Printf ("삭제된 번호 입력:");
Scanf("%ld ",& ampdel _ num);
Printf(" \ n 삽입된 레코드 입력: ");
Stu= (구조학생 *) malloc (len);
Scanf("% 1d, %f, ",& ampstu I > num & amp;; Stu I > SCOR) :
While (stu I > num! =0)
{head = insert (헤드, stu):
인쇄 (머리);
Prinif ("삽입된 레코드 입력:");
Stu= (구조학생 *) malloc (len);
Scanf("% 1d, %f, & ampstu I > num & amp;; Stu I > 점수);
}
}
Sum 은 포인터 변수로 정의됩니다. 삽입이 필요한 경우 먼저 malloc 함수를 사용하여 메모리 영역을 열고 유형 변환 후 stu 에 시작 주소를 지정한 다음 이 구조 변수에 각 멤버의 값을 입력합니다. Stu 의 값은 삽입 객체마다 다르며 한 번에 하나의 새 구조 변수를 가리킵니다. 삽입 함수를 호출할 때 인수는 head 와 stu 입니다. 설정된 연결된 목록의 시작 주소를 insert 함수의 쉐이프 매개변수에 전달하고 stu (새로 열린 셀의 주소) 를 쉐이프 매개변수 stud 에 전달합니다. 함수 값은 삽입 후 연결된 목록의 헤더 포인터 (주소) 를 반환합니다.
작업은 다음과 같습니다.
레코드 입력:
89 10 1,99
89 103,87
89 105,77
0,0
이 세 가지 기록은.
89 10 1 99.0
89 103 87.0
89 105 77.0
삭제 번호 입력: 89 103
삭제: 89 103
자, 이 두 기록은 다음과 같습니다.
89 10 1 99.0
89 105 77.0
De 1 전체 번호 89 105 를 입력합니다
삭제: 89 105
이제 이러한 l 레코드는 다음과 같습니다.
89 10 1 99.0
De 1 전체 숫자: 0 을 입력합니다
1 삽입된 레코드 입력: 89104,87
자, 이 두 기록은 다음과 같습니다.
89 10 1 99.0
89 104 87.0
삽입된 레코드 입력: 89106,65
자, 이 세 가지 기록은 다음과 같습니다.
89 10 1 99.0
89 104 87.0
89 106 65.0
삽입된 레코드 입력: 0,0
이 프로그램을 자세히 소화해 주세요.
포인터는 단방향 링크 테이블, 링 링크 테이블, 양방향 링크 테이블, 대기열, 트리, 스택, 그림 등의 데이터 구조 등 다양한 용도로 사용됩니다.
이러한 문제에 대한 알고리즘의 경우 "데이터 구조 >:>" 에서 과정을 자세히 소개하지 않을 수 있습니다.