本章重点
线性表的定义,顺序表和链表的定义与特点,顺序表和链表的插入删除查找移动等基本操作
n-i+1
个元素,平均时间复杂度:O(n)
。ai~an
都向前移动一个位置,共移动n-i
个元素,平均时间复杂度:O(n)
。O(1)
;(n+1)/2
,时间复杂度O(n)
。单链表:通过指针连接各数据元素,不需要使用物理地址连续的存储单元,非随机存取
js//线性表的单链表存储结构:
typedef struct LNode{
ElemType data;
struct LNode *next;
}LNode, *LinkList;
结点(node):结点构成链表,由数据域和指针域(存储后续位置)构成,结构为:
数据域(data) | 指针域(next) |
---|
头指针:用来标识单链表,指向链表中第一个结点的存储位置。头指针为NULL
时为空表。
头结点:为了方便操作,在单链表的第一个结点之前设置一个数据域不存储任何信息、指针域指向第一结点的指针的结点。
带头结点的优点:
基本操作
头插法建表:从空表开始将新结点插入当前链表的头结点后。
读入数据的顺序与生成链表中元素的顺序相反。时间复杂度为O(n)
核心代码:
jss->next = L->next; //1⃣先用新结点S的指针指向原链表的第一个结点;
L->next = s; //2⃣再将头结点的指针L指向新结点。
尾插法:将新结点插入当前表尾,使用尾指针r始终指向尾结点。
读入数据的顺序与生成链表中元素的顺序一致。时间复杂度为O(n)
核心代码:
jsr->next = s; //1⃣原尾结点指向新的结点;
r = s; //2⃣插入的结点成为新的尾结点。
查找:按值查找和按序号查找;链表非随机存取,两种查找方式都需要从头结点开始遍历查找。时间复杂度为O(n)
插入:将数据域为x的新结点S插入第i个位置。时间复杂度为O(n)
核心代码:
jsp = GetElem(L, i-1); //1⃣找到插入的位置;
s->next = p->next; //2⃣新结点s指向插入位置的下一结点;
p->next = s; //3⃣结点P指向S
删除:删除链表中的第i个结点。时间复杂度为O(n)
核心代码:
jsp = GetElem(L, i-1);
q = p->next;
p->next = q->next
注
插入删除时注意顺序,插入时要让新结点先指向插入位置的后一个结点,删除时要先让前驱结点指向删除位置的后继结点,避免链表断开结点丢失。
本文作者:Handy Zhang
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!