数据结构:线性表的链式表示

继上文《数据结构:线性表的顺序表示》,我们知道线性表的主要操作如下:

  • InitList(&L): 初始化表
  • length(L): 求表长
  • LocateElem(L, e): 按值查找操作
  • GetElem(L, i): 按位查找操作
  • ListInsert(&L,i,e): 插入操作
  • ListDelete(&L,i,&e): 删除操作
  • PrintList(L):输出操作
  • Empty(L):判空操作
  • DestroyList(&L): 销毁操作

本文将讨论如何用链式表示的方法定义线性表

一般来说,默认链表是带头结点的

代码部分

线性表的定义

typedef int ElemType;
typedef struct LNode {
ElemType data;
struct LNode* next;
}LNode, * LinkList;

第二个typedef语句本质上是,先定义一个结构体LNode, 再为LNode*类型取一个别名LinkList;可以说,链式表示用头节点来代表一个线性表。

单链表的初始化

带头结点的单链表初始化时,需先创建一个头结点,并让头指针指向头结点,头结点的next域初始化为NULL

特别的:#include <iostream> 中并不支持malloc语句,因此需要额外引用:#include <cstdlib>

bool InitList(LinkList& L) {
L = (LNode*)malloc(sizeof(LNode)); // 创建头节点
L->next = NULL; // 头节点指向空
return true;
}

关键语句解释:

L = (LNode*)malloc(sizeof(LNode));
sizeof(LNode) 表示 LNode 结构体的大小,即需要多少字节的内存空间来存储这个结构体的数据。
malloc(...) 调用malloc函数,在堆内存中分配指定大小的空间
L = (LNode*)... 是将 malloc 返回的指向分配的内存空间的指针转换为 LNode* 类型,并将其赋值给 L 这个指针变量。

求表长操作

求表长操作是计算单链表中数据结点的个数。

int length(LinkList L) {
int len = 0; // 计数变量
LNode* p = L;
while (p->next != NULL) {
p = p->next;
len++;
}
return len;
}

按序号查找结点

从单链表的第一个结点开始,沿着next域从前向后依次搜索,直到找到第i个结点为止,则返回该结点的指针;若i大于单链表的表长,则返回NULL

LNode* GetElem(LinkList L, int i) {
LNode* p = L; // 指向当前扫描到的节点
int j = 0;
while (p != NULL && j<i) {
p = p->next;
j++;
}
return p; // 返回节点i得指针或NULL
}

按值查找结点

LNode* LocateElem(LinkList L, ElemType e) {
LNode* p = L->next;
while (p != NULL && p->data != e)
p = p->next;
return p;
}

插入结点操作

插入结点操作将值为x的新结点插入到单链表的第i个位置。先检查位置的合法性,然后找到待插入位置的前驱a,插入时遵循下列操作:

  1. 先将新结点指向a的后驱b(b=a->next
  2. 再将前驱a指向新结点
    具体代码如下:
bool ListInsert(LinkList& L, int i, ElemType e) {
LNode* p = L;
int j = 0;
while (p != NULL && j < i - 1) {
p = p->next;
j++;
}
if (p == NULL)
return false; // 位序不合法
LNode* s = (LNode*)malloc(sizeof(LNode));
s->data = e;
s->next = p->next;
p->next = s;
return true;
}

删除结点操作

先检查位置的合法性,然后找到待插入位置的前驱a,删除时遵循如下步骤:

  1. 定义指针q,将待删除的结点指针赋值给q
  2. 将前驱a指向q的下一个结点
  3. 释放指针q指向的内存
bool ListDelete(LinkList& L, int i, ElemType& e) {
LNode* p = L;
int j = 0;
while (p != NULL && j < i - 1) {
p = p->next;
j++;
}
if (p == NULL || p->next == NULL)
return false;
LNode* q = p->next;
e = q->data;
p->next = q->next;
free(q);
return true;
}
posted @   SXWisON  阅读(33)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示