学习流程主要包括分为11个部分
- 绪论
- 线性表
- 栈和队列
- 递归和分治思想
- 串(KMP算法)
- 数组和广义表
- 树和二叉树
- 图
- 动态存储管理
- 查找
- 排序
目录
2.3.1 线性表的单链表存储结构(C 语言中用结构指针表示):
二 线性表
上节中,线性表的顺序存储结构的特点是:逻辑关系上相邻的两个元素在物理位置上也相邻。它的弱点很明显,在进行插入和删除操作时,需要移动大量的元素。本节讨论链式存储结构,它不要求逻辑相邻的元素物理上也相邻,所以它没有顺序结构的弱点,但也失去了顺序表可以随机存储(在给定元素位置的情况下,顺序表可以在常数时间内(时间复杂度))的优点。
2.3 线性表的链式表示
特点:用一组任意的存储单元存储线性表的数据元素(连续与否都可)。
所以为了表示和直接后继
之间的逻辑关系,除了存储
的信息,还需要存储直接后继
的信息(存储位置)。两部分组成
的存储映像,称为结点。
它包括两个域,数据域和指针域(其中存储的信息成为指针或者链)。个结点
的存储印象,链结成一个链表,即为线性链表或单链表。
线性链表的存储必须从头指针(指示链表中第一个结点的存储位置)开始进行。由于最后一个元素没有直接后继,则线性链表最后一个节点的指针为NULL。

2.3.1 线性表的单链表存储结构(C 语言中用结构指针表示):
#include <stdio.h>
#include <stdlib.h>
//- - - - - 线性表的单链表存储结构 - - - - -
// 线性表的单链表存储结构体
typedef struct ListNode{
int data; // 数据域,存储节点的数据元素
struct ListNode *next; // 指针域,指向下一个节点的指针 next:结构体指针变量,指向结构体的地址
} ListNode, *LinkList; // ListNode用于表示struct ListNode结构体,简化了结构体类型的引用
// LinkList这个别名表示指向struct ListNode的结构体类型的指针,它
// 使得可以直接使用LinkList来声明指向链表节点的指针变量
假设L是单链表的头指针,它指向表中的第一个结点。若L为空(L=NULL),则表示线性表为空。单链表通常以一个特殊的结点作为头结点,头结点的数据与可以不存储任何信息,也可以存储线性表长度等附加信息,头结点的指针域指向第一个结点的指针。
虽然单链表中的两个元素之间没有固定联系,但是每个元素的存储位置包含在前驱结点的信息中。所以我们有:假设是指向线性表中第
个元素(结点
)的指针,则
是指向
元素(结点
)的指针。则有
;
。所以单链表中,取得第i个元素,必须从头指针开始寻找,所以单链表是非随机存储的存储结构。下面是单链表的初始化和获取单链表的第i个元素的函数实现。
2.3.2 单链表的初始化
// 初始化单链表(初始化为空链表)
void InitList(LinkList* L) { // 链表接受一个指向指针LinkList的指针LinkList* L 这样可以在函数内部修改指针的值
*L = (LinkList)malloc(sizeof(ListNode)); // *L是L指针变量的解引用,表示获取指针变量LinkList的值,指针变量
// LinkList存储的是struct ListNode的首地址
// malloc函数,动态分配内存,接受一个参数,返回指向分配内存起始地址的指针。
// (LinkList)类型甄嬛。它将malloc函数返回的通用指针 void *类型转化为LinkList类型(struct ListNode)的指针
if (!(*L)) {
printf("内存分配失败!\n");
exit(-1);
}
(*L)->next = NULL;
}
2.3.3 单链表-获取单链表的第i个元素的函数实现
// 获取单链表的第i个元素
int GetElem(LinkList* L, int i) { // 链表接受一个指向指针LinkList的指针LinkList* L
int j = 1; //计数器
LinkList p = (*L)->next; // 初始化p指向第一个结点 其中L->next表示下一个结点的地址
while (p && j < i) { //指针向后查找,直到p指向第i个元素,或p不存在
p = p->next;
j++;
}
if (!p || j > i) { //当p不存在时,j>i 有两种可能链表中元素的数量小于i或者i<=0
printf("第%d个元素不存在!\n", i);
exit(-1);
}
return p->data; // 返回结点的值
}
在获取单链表的第i个元素的函数中,其基本操作为while循环中的循环条件p指针的存在和比较i,j的大小,还有后移指针p。while循环中语句的频度与被查元素在表中的位置有关,若,则频度为
(因为要编译到第
个元素的前一个结点),否则频度为
(如果
超出了有效范围(小于1或者大于
),那么就需要遍历整个链表直到最后一个节点,循环的频度就是
)。因此该算法的时间复杂度为
。


1180

被折叠的 条评论
为什么被折叠?



