数据结构读书笔记.docx
《数据结构读书笔记.docx》由会员分享,可在线阅读,更多相关《数据结构读书笔记.docx(31页珍藏版)》请在冰豆网上搜索。
数据结构读书笔记
“数据结构”读书笔记示例:
第2章 线性表
学习线索:
逻辑结构→基本运算定义→存储结构→基本运算实现(复杂度分析→应用实例)
1.逻辑结构:
是由n(n≥0)个数据元素组成的有限序列。
2.基本运算定义:
(P.16)
(1)Init_List(L),线性表初始化;
(2)Length_List(L),求线性表的长度;
(3)Get_List(L,i),取表元;
(4)Locate_List(L,x),按值查找;
(5)Insert_List(L,x,i);插入操作;
(6)Delete_List(L,i),删除操作。
3.存储结构:
(1)顺序表:
把线性表的结点按逻辑次序存放在一组地址连续的存储单元里。
顺序存储的结构体定义:
typedefstruct
{datatypedata[MAXSIZE];/*一维数组子域*/
intlast;/*表长度子域*/
}SeqList;/*顺序存储的结构体类型*/
4-1.顺序表的基本运算的实现(算法及其复杂度分析、应用实例:
顺序表的划分、合并、比较大小)
(2)单链表:
只有一个链域的链表称单链表。
结点结构:
Data(节点值)
Next(后继结点地址)
其中data是数据域,next是指针域
链式存储的结构体定义:
typedefstructlnode
{datatypedata;/*数据子域*/
structlnode*next;/*指针子域*/
}LNode,*LinkList;/*链式存储的结点结构类型*/
4-2.单链表的基本运算的实现(算法及其复杂度分析、应用实例:
链表逆置、归并)
单链表的发展:
循环链表、双向链表
顺序表和链表的比较
1)基于空间:
2)基于时间:
“数据结构”读书笔记(线性结构部分)
第1章绪论
1.数据:
信息的载体,能被计算机识别、存储和加工处理。
2.数据元素:
数据的基本单位,可由若干个数据项组成,数据项是具有独立含义的最小标识单位。
3.数据结构:
数据之间的相互关系,即数据的组织形式。
它包括:
(1)数据的逻辑结构,从逻辑关系上描述数据,与数据存储无关,独立于计算机;
(2)数据的存储结构,是逻辑结构用计算机语言的实现,依赖于计算机语言。
(3)数据的运算(基本操作),定义在逻辑结构上,每种逻辑结构都有一个运算集合。
常用的运算:
检索/插入/删除/更新/排序。
4.数据的逻辑结构可以看作是从具体问题抽象出来的数学模型。
数据的存储结构是逻辑结构用计算机语言的实现。
5.数据类型:
一个值的集合及在值上定义的一组操作的总称。
分为:
原子类型和结构类型。
6.抽象数据类型:
抽象数据的组织和与之相关的操作。
优点:
将数据和操作封装在一起实现了信息隐藏。
7.抽象数据类型ADT:
是在概念层上描述问题;类:
是在实现层上描述问题;在应用层上操作对象(类的实例)解决问题。
8.数据的逻辑结构,简称为数据结构,有:
(1)线性结构,若结构是非空集则仅有一个开始和终端结点,并且所有结点最多只有一个直接前趋和后继。
(2)非线性结构,一个结点可能有多个直接前趋和后继。
9.数据的存储结构有:
(1)顺序存储,把逻辑相邻的结点存储在物理上相邻的存储单元内。
(2)链接存储,结点间的逻辑关系由附加指针字段表示。
(3)索引存储,存储结点信息的同时,建立附加索引表,有稠密索引和稀疏索引。
(4)散列存储,按结点的关键字直接计算出存储地址。
10.评价算法的好坏是:
算法是正确的;执行算法所耗的时间;执行算法的存储空间(辅助存储空间);易于理解、编码、调试。
11.算法的时间复杂度T(n):
是该算法的时间耗费,是求解问题规模n的函数。
记为O(n)。
时间复杂度按数量级递增排列依次为:
常数阶O
(1)、对数阶O(log2n)、线性阶O(n)、线性对数阶O(nlog2n)、平方阶O(n^2)、立方阶O(n^3)、……k次方阶O(n^k)、指数阶O(2^n)。
12.算法的空间复杂度S(n):
是该算法的空间耗费,是求解问题规模n的函数。
13.算法衡量:
是用时间复杂度和空间复杂度来衡量的,它们合称算法的复杂度。
14.算法中语句的频度不仅与问题规模有关,还与输入实例中各元素的取值相关。
第2章 线性表
1.线性表:
是由n(n≥0)个数据元素组成的有限序列。
2.线性表的基本运算有:
(1)InitList(L),构造空表,即表的初始化;
(2)ListLength(L),求表的结点个数,即表长;
(3)GetNode(L,i),取表中第i个结点,要求1≤i≤ListLength(L);
(4)LocateNode(L,x)查找L中值为x的结点并返回结点在L中的位置,有多个x则返回首个,没有则返回特殊值表示查找失败。
(5)InsertList(L,x,i)在表的第i个位置插入值为x的新结点,要求1≤i≤ListLength(L)+1;
(6)DeleteList(L,i)删除表的第i个位置的结点,要求1≤i≤ListLength(L);
3.顺序表:
把线性表的结点按逻辑次序存放在一组地址连续的存储单元里。
4.顺序表结点的存储地址计算公式:
Loc(ai)=Loc(a1)+(i-1)*C;1≤i≤n
5.顺序表上的基本运算
(1)插入
voidinsertlist(seqlist*L,datatypex,inti)
{
intj;
if(i<1||i>L->length+1)
error(“positionerror”);
if(L->length>=listsize)
error(“overflow”);
for(j=L->length-1;j>=i-1;j--)
L->data[j+1]=L->data[j];结点后移
L->data[i-1]=x;
L->length++;
}
在顺序表上插入要移动表的n/2结点,算法的平均时间复杂度为O(n)。
(2)删除
voiddelete(seqlist*L,inti)
{
intj;
if(i<1||i>L->length)
error(“positionerror”);
for(j=i;j<=L->length-1;j++)
L->data[j-1]=L->data[j];结点前移
L->length--;
}
在顺序表上删除要移动表的(n+1)/2结点,算法的平均时间复杂度为O(n)。
6.单链表:
只有一个链域的链表称单链表。
在结点中存储结点值和结点的后继结点的地址,结点结构如下:
Data(节点值)
Next(后继结点地址)
其中data是数据域,next是指针域
(1)建立单链表。
时间复杂度为O(n)。
加头结点的优点:
1)链表第一个位置的操作无需特殊处理;2)将空表和非空表的处理统一。
(2)查找运算。
时间复杂度为O(n)。
1)按序号查找。
Listnode*getnode(linklisthead,inti)
{
intj;
listnode*p;
p=head;j=0;
while(p->next&&j
p=p->next;指针下移
j++;
}
if(i==j)
returnp;
else
returnNULL;
}
2)按值查找。
Listnode*locatenode(linklisthead,datatypekey)
{
listnode*p=head->next;
while(p&&p->data!
=key)
p=p->next;
returnp;
}
(3)插入运算。
时间复杂度为O(n)。
Voidinsertlist(linklisthead,datatypex,inti)
{
listnode*p;
p=getnode(head,i-1);
if(p==NULL);
error(“positionerror”);
s=(listnode*)malloc(sizeof(listnode));
s->data=x;
s->next=p->next;
p->next=s;
}
(4)删除运算。
时间复杂度为O(n)。
Voiddeletelist(linklisthead,inti)
{
listnode*p,*r;
p=getnode(head,i-1);
if(p==NULL||p->next==NULL)
error(“positionerror”);
r=p->next;
p->next=r->next;
free®;
}
7.循环链表:
是一种首尾相连的链表。
特点是无需增加存储量,仅对表的链接方式修改使表的处理灵活方便。
8.空循环链表仅由一个自成循环的头结点表示。
9.很多时候表的操作是在表的首尾位置上进行,此时头指针表示的单循环链表就显的不够方便,改用尾指针rear来表示单循环链表。
用头指针表示的单循环链表查找开始结点的时间是O
(1),查找尾结点的时间是O(n);用尾指针表示的单循环链表查找开始结点和尾结点的时间都是O
(1)。
10.在结点中增加一个指针域,prior|data|next。
形成的链表中有两条不同方向的链称为双链表。
1)双链表的前插操作。
时间复杂度为O
(1)。
Voiddinsertbefore(dlistnode*p,datatypex)
{
dlistnode*s=malloc(sizeof(dlistnode));
s->data=x;
s->prior=p->prior;
s->next=p;
p->prior->next=s;
p->prior=s;
}
2)双链表的删除操作。
时间复杂度为O
(1)。
Voidddeletenode(dlistnode*p)
{
p->prior->next=p->next;
p->next->prior=p->prior;
free(p);
}
11.顺序表和链表的比较
1)基于空间的考虑:
顺序表的存储空间是静态分配的,链表的存储空间是动态分配的。
顺序表的存储密度比链表大。
因此,在线性表长度变化不大,易于事先确定时,宜采用顺序表作为存储结构。
2)基于时间的考虑:
顺序表是随机存取结构,若线性表的操作主要是查找,很少有插入、删除操作时,宜用顺序表结构。
对频繁进行插入、删除操作的线性表宜采用链表。
若操作主要发生在表的首尾时采用尾指针表示的单循环链表。
12.存储密度=(结点数据本身所占的存储量)/(整个结点结构所占的存储总量)
存储密度:
顺序表=1,链表<1。
第3章 栈和队列
1.栈是限制仅在表的一端进行插入和删除运算的线性表又称为后进先出表(LIFO表)。
插入、删除端称为栈顶,另一端称栈底。
表中无元素称空栈。
2.栈的基本运算有:
1)initstack(s),构造一个空栈;
2)stackempty(s),判栈空;
3)stackfull(s),判栈满;
4)push(s,x),进栈;
5)pop(s),退栈;
6)stacktop(s),取栈顶元素。
3.顺序栈:
栈的顺序存储结构称顺序栈。
4.当栈满时,做进栈运算必定产生空间溢出,称“上溢”。
当栈空时,做退栈运算必定产生空间溢出,称“下溢”。
上溢是一种错误应设法避免,下溢常用作程序控制转移的条件。
5.在顺序栈上的基本运算: