一、简单描述
如果要实现从单链表中获取某个元素
结果:用e返回线性表L中的第i个元素的值
(图源:程杰《大话数据结构(溢彩加强版)》)
二、详细步骤:
1.初始化计数器和指针
j 初始化为1,用与记录当前遍历的节点位置
声明一个节点p指向链表L中的第一个节点
int j=1;
LinkList p;
p=L->next;
2.遍历链表
当j<1的时候遍历链表,让p不断后移,计数器加1
while(p&&j<i) //当p不为空且j<i时
{
p=p->next;
++j;
}
注:j++和++j的区别
int j=5;
int result=j++; //result等于5,j变成6
int j=5;
int result=++j; //result等于6,j变成6
3.判断是否找到第i个节点
如果p为空,说明链表遍历结束还是没有找到第i个节点,操作失败
或者j>i,说明遍历整个链表也没有找到第i个节点,操作失败
if(!p||j>i)
{
return ERROR;
4.将第i个节点的值存储到指针e存储的位置,操作成功
*e=p->data;
return OK;
}
三、核心代码:
int GetElem(LinkList L, int i, ElemType *e) {
int j = 1; /* j 为计数器,用于记录当前遍历的节点位置 */
LinkList p; /* 声明一个节点 p,用于遍历链表 */
p = L->next; /* p 指向链表 L 的第一个节点 */
/* 当 p 不为空并且计数器不等于 i 时,循环继续 */
while (p && j < i) {
p = p->next; /* p 指向下一个节点 */
++j; /* 计数器增加 */
}
/* 如果 p 为空或者计数器大于 i,说明未找到第 i 个元素,返回错误码 ERROR */
if (!p || j > i) {
return ERROR;
}
/* 将找到的第 i 个元素的值赋给指针 e 指向的内存位置 */
*e = p->data;
return OK; /* 返回 OK 表示成功找到并获取第 i 个元素的值 */
}
四、完整代码:
#include <stdio.h>
#include <stdlib.h>
#define OK 1
#define ERROR 0
typedef int ElemType;
typedef struct Node {
ElemType data; //数据域,用来存储节点的数据
struct Node* next; //指针域,用来指向下一个节点的位置
} Node;
typedef Node* LinkList;
int GetElem(LinkList L, int i, ElemType *e) {
int j = 1; // 计数器,用于记录当前节点位置
LinkList p = L->next; // 指针p指向第一个节点(头节点的下一个节点)
// 遍历链表,直到找到第i个节点或者遍历完整个链表
while (p && j < i) {
p = p->next;
++j;
}
// 如果找到第i个节点,将其数据值存储到指针e指向的内存位置,返回OK
if (p && j == i) {
*e = p->data;
return OK;
} else {
// 如果未找到第i个节点,返回ERROR表示操作失败
return ERROR;
}
}
int main() {
// 创建头节点
LinkList L = (LinkList)malloc(sizeof(Node));
if (L == NULL) {
printf("Memory allocation failed\n");
return -1;
}
L->next = NULL; // 头节点的next指针初始化为NULL
// 在链表中插入一些元素(示例)
for (int i = 1; i <= 5; ++i) {
LinkList newNode = (LinkList)malloc(sizeof(Node));
if (newNode == NULL) {
printf("Memory allocation failed\n");
return -1;
}
newNode->data = i;
newNode->next = L->next; // 将新节点插入链表头部
L->next = newNode;
}
// 调用GetElem函数获取第3个元素的值
ElemType element;
if (GetElem(L, 3, &element) == OK) {
printf("Element at position 3: %d\n", element);
} else {
printf("Element not found at position 3\n");
}
// 释放链表中的内存
LinkList p = L->next;
while (p) {
LinkList temp = p;
p = p->next;
free(temp);
}
// 释放头节点
free(L);
return 0;
}