数据结构重点总结.docx
《数据结构重点总结.docx》由会员分享,可在线阅读,更多相关《数据结构重点总结.docx(26页珍藏版)》请在冰豆网上搜索。
数据结构重点总结
第一章绪论
数据——所有输入计算机中并被计算机处理的符号。
数据元素——数据的基本单位,通常作为一个整体。
数据对象——性质相同的数据元素的集合。
数据结构——数据元素以及之间存在的关系。
1、线性结构;2、集合结构3、树形结构;4、图结构
数据结构的形式定义:
Data--Structure=(D,S)D——数据元素集合S——关系集合
数据的逻辑结构——用形式化方式描述数据元素间的关系。
数据的物理结构——数据在计算机中的具体表示。
数据类型——一种数据结构和定义在其上的一组操作。
可以形式化定义为:
Data--Type=(D,S,P)
算法的定义是对特定问题求解步骤的一种描述,是指令的有限序列。
算法的特性
有穷性——算法必须在执行有穷步之后结束,而且每一步都可在有穷时间内完成。
确定性——每条指令无二义性。
可行性——算法中描述的每一操作,都可以通过已经实现的基本运算来实现。
输入——算法有零至多个输入。
输出——算法有一个至多个输出。
时间复杂度的等级
O
(1)
O(logn)
O(n)
O(n×logn)
O(n2)
O(nK)
O(Xn)
第2章线性表
重点:
1、链式和线性表两种方式的插入与删除
2、单双链表的定义
线性表的定义
#defineList-Init-Size100
#defineListincrement10
typedefstruct{
Elemtype*elem;
intlength;
intlistsize;
}Sqlist;
线性表定位插入
StatusListinsert_Sq(Sqlist&L,inti,Elemtypee)
{if(i<1‖i>L.length+1)returnERROR;
if(L.length>=L.listsize)
{newbase=追加分配新空间
L.elem=newbase;
L.listsize+=Listincrement;
}
for(j=L.length-1;j>=i-1;--j)
L.elem[j+1]=L.elem[j]);
L.elem[i-1]=e;
++L.length;
returnOK;
}
线性表定位删除
StatusListdelete_Sq(Sqlist&L,inti,Elemtype&e)
{
if(i<1‖i>L.length)returnERROR;
e=L.elem[i-1]);
for(j=i;jL.elem[j-1]=L.elem[j]);
--L.length;
returnOK;
}
单链表定义:
typedefstructLnode{
Elemtypedata;
structLnode*next;
}Lnode,*Linklist;
链式定位插入
StatusListinsert_L(Linklist&L,inti,Elemtypee)
{
p=L;j=0;
while(p&&j{p=p->next;++j}
if(!
p‖j>i-1)returnERROR;
new(s);
s->data=e;s->next=p->next;p->next=s;
returnOK;
}
链式定位删除
StatusListdelete_L(Linklist&L,inti,Elemtype&e)
{
p=L;j=0;
while(p->next&&j{p=p->next;++j}
if(!
(p->next)‖j>i-1)returnERROR;
q=p->next;p->next=q->next;
e=q->data;
free(q);
returnOK;
}
双向链表结点的存储结构定义
typedefstructDublnode{
Elemtypedata;
structDublnode*prior;
structDublnode*next;
}Dublnode,*Dublinklist;
了解:
有序表的合并
voidMergelist_L(Linklist&La,Linklist&Lb,Linklist&Lc)
{
pa=La->next;pb=Lb->next;
Lc=pc=La;
while(pa&&pb)
{if(pa->data<=pb->data)
{pc->next=pa;pc=pa;pa=pa->next;}
else
{pc->next=pb;pc=pb;pb=pb->next;}
}
pc->next=pa?
pa:
pb;
free(Lb);
}
第3章、栈与队列
重点:
1、栈的插入,删除,和取栈顶
2、队列的取对头,插入,删除(循环队列)
栈的存储结构定义:
#defineStack_init_size100;
#defineStackincrement10;
typedefstruct{
Selemtype*base;指向第一个元素(有数)
Selemtype*top;指向最后一个元素的下一位(为空)
intstacksize;
}Sqstack;
栈的取栈顶
StatusGettop(Sqstacks,Selemtype&e)
{if(s.top==s.base)returnERROR;
e=*(s.top-1);
returnOk
}
栈的插入
StatusPush(Sqstack&s,Selemtypee)
{if(s.top-s.base>=s.stacksize)
{s.base=追加分配空间;
s.stacksize+=Stackincrement;
}
*s.top++=e;
returnOk
}
栈的删除栈顶
StatusPop(Sqstack&s,Selemtype&e)
{if(s.top==s.base)returnERROR;
e=*--s.top
returnOk
}
队列的顺序存储表示与实现
typedefstruct{
Qelemtype*base;
intfront;指向第一个元素(有数)
intrear;指向最后一个元素的下一位(为空)
}Sqqueue;
队空条件:
Q.front=Q.rear
队满条件:
(Q.rear+1)%Maxsize=Q.front
队列长度:
(Q.rear-Q.front+Maxsise)%Maxsize
队的插入:
StatusEnqueue(sqqueue&Q,Qelemtypee)
{if((Q.rear+1)%Maxsize==Q.front)
returnERROR;
Q.base[Q.rear]=e;
Q.rear=(Q.rear+1)%Maxsize;
returnOK;
}
队的删除
StatusDequeue(sqqueue&Q,Qelemtype&e)
{if(Q.front==Q.rear)returnERROR;
e=Q.base[Q.front];
Q.front=(Q.front+1)%Maxsize;
returnOK;
}
取对头
StatusGetHead(sqqueue&Q,Qelemtype&e)
{if(Q.front==Q.rear)returnERROR;
returnQ.base[Q.front];
}
第四章串
重点:
串的比较、连接,了解串的插入,删除
定义
typedefstruct
{char*ch;
intlength;
}Hstring;
比较
statusstrcompare(S,T)
{for(i=0;iif(S.ch[i]!
=T.ch[i])returnS.ch[i]-T.ch[i];
returnS.length-T.length;
}
连接
Statusconcat(&t,s1,s2)
{if(t.ch)free(t.ch);
if(!
(T.ch=(char*)malloc((s1.length+s2.lengrh)*sizeof(char))))
exit(overflow);
t.ch[0..s1.length-1]=s1.ch[0..s1.length-1];
t.length=s1.length+s2.length;
t.ch[s1.length..t.length-1]=s2.ch[0..s2.length-1];
returnOK;
}
第5章数组和广义表
重点:
特殊矩阵,稀疏矩阵(明白思路)
对称矩阵aij=aji0≤i,j≤n-1
SA[k]=aijk=i(i+1)/2+j(i>=j)或k=j(j+1)/2+i(i稀疏矩阵一般采用三元组存储一个非零元素。
如:
三元组
(1,5,a)
(2,2,b)
(3,4,c)
(4,7,d)
三元组定义
#defineMaxsize=1000
typedefstruct
{inti,j;
elemtypee;
}triple
typedefstruct
{tripledata[Maxsize+1]
intm,n,num;
}TSmatrix
第六章树与二叉树
重点:
1、二叉树的遍历和性质,
2、树的存储结构及遍历
3、哈夫曼树
基本概念
结点的度:
结点拥有子树的数目
叶结点:
结点的度为零的结点
分枝结点:
结点的度非零的结点
树的度:
树中各结点度的最大值
孩子:
j,k,l称为i的孩子
双亲:
i称为j,k,l的双亲
兄弟:
j,k,l互为兄弟
祖先:
树的根结点到某结点j路径上的所有结点,为结点j的祖先
子孙:
结点i下的所有结点,称为结点i的子孙
结点层次:
从根结点到某结点j路径上结点的数目
树的深度:
树中结点的最大层次
有序树:
若树中结点的各子树从左到右是有次序的,称该树为有序树,否则为无序树
森林:
由m棵互不相交的树构成F=(T1,T2,.......Tm)
二叉树的性质
定义:
深度为k且有
个结点的二叉树称为满二叉树
定义:
深度为k且有n个结点的二叉树,当且仅当n个结点都满足满二叉树的位置编号的升序排列结构时,称为完全二叉树
性质1:
在二叉树的i层上至多有
个结点。
(归纳法证明)
性质2:
深度为k的二叉树,至多有
个结点。
(等比求和)
性质3:
对任意二叉树BT,若叶结点数为n0,度为2的结点数为n2,则n0=n2+1
性质4:
具有n个结点的完全二叉树深度为[
]+1(取整)
性质5:
对结点数为n的完全二叉树,第i个结点有如下特征:
(1)若i=1则i为根结点,无双亲
若i>1则双亲为parent(i)=[i/2];
(2)若2i>n则i无孩子,为叶结点否则lchild(i)=2i;
(3)若2i+1>n则i无右孩子否则rchild(i)=2i+1。
遍历的访问顺序有三种:
1>先序访问:
根左子树右子树
2>中序访问:
左子树根右子树
3>后序访问:
左子树右子树根
递归遍历:
中序
Voidinorder(bt)
{if(bt)
{inorder(bt->lchild);
visit(bt->data);
inorder(bt->rchild);
}
}
先序
Voidpreorder(bt)
{if(bt)
{visit(bt->data);
preorder(bt->lchild);
preorder(bt->rchild);
}
}
后序
Voidpostorder(bt)
{if(bt)
{postorder(bt->lchild);
postorder(bt->rchild);
visit(bt->data);
}
}
树的存储结构(书上P135)
1双亲表示法:
用一组连续的空间存放结点,每个结点用一个域表示该结点的双亲.
2孩子表示法:
(1)多叉链表表示法
(2)多重线性链表表示法:
把每个结点的孩子组成一个线性链表.
3孩子兄弟表示法:
用二叉树的左指针指向该结点的第一个孩子,右指针指向该结点的下一个兄弟.
哈夫曼树(最优二叉树)
概念
路径:
从一结点到另一结点上的分支
路径长度:
路径上的分支数目
树的路径长度:
从根到所有结点的路径长度之和
结点的带权路径长度:
从该结点到树根之间的路径长度与结点上权值的乘积.
树的带权路径长度:
树中所有叶子结点的带权路径长度之和.
定义:
设有n个权值{w1,w2,......wn},任意构造有n个叶结点的二叉树,每个叶结点权值为wi。
则其中带权路径长度最小的二叉树称为哈夫曼树(最优二叉树)。
构造方法
(1)根据给定的{w1,w2,......wn},生成n棵树的森林,
F={T1,T2,.......Tm};根结点值为权值;
(2)在F中选择两棵根结点值最小的树Ti,Tj作为左右子树,构成一棵新二叉树Tk,Tk根结点值为Ti,Tj根结点权值之和;
(3)在F中删除Ti,Tj,并把Tk加到F中;
(4)重复
(2)(3),直到F中只含一棵树。
第7章图
重点:
图的定义,数组表示法,邻接表表示法
深度优先遍历,广度优先遍历,生成树
图的定义:
Graph=(V,E),V为顶点集;E为边集。
若E为有向边,称为有向图;若E为无向边,称为无向图。
边一般由顶点对表示:
;
若为有向边,则称vi为尾,vj为头.
有向边也可以表示为:
vivj
无向完全图:
如果在无向图G中,任何两顶点都有一条边相连,边的数目为:
n(n-1)/2
有向完全图:
如果在有向图G中,任何两顶点都有两条方向相反的边相连,边的数目为:
n(n-1)
连通图:
无向图中,任意两点Vi,Vj都有路径相连,称该无向图为连通图.
连通分量:
无向图中极大连通子图.
数组(矩阵)表示法:
设G=(V,E)V={V1,V2,.......Vn}
A[i,j]=1若∈E,i≠j
0否则
A为一n×n矩阵,称为G的邻接矩阵
若G=(V,E)为网,则邻接矩阵可以表示为:
数组表示法定义:
#defineMax_V_num20//最大顶点数
typedefenum{DG,DN,UDG,UDN}Graphkind;//有向无向图网
typedefstruct//图结构
{Vextypevexs[Max_V_num];//顶点数组
Arctypearcs[Max_V_num][Max_V_num];//边矩阵//0,1或权值wij
intvexnum,arcnum;//顶点数,边数
Graphkindkind;//图种类
}graph
邻接表表示法:
每个顶点用一个链表表示(P164)
#defineMax_V_num20//最大顶点数
typedefstructArcnode//边结点类型
{intvjpos;//vj的位置
structArcnode*nextarc;
}Arcnode;
typedefstructVnode//顶点结点类型
{vextypedata;
Arcnode*firsttarc;
}Vnode,Adjlist[Max_V_num];
typedefstruct
{Adjlistvexs;
intvexnum,arcnum;
Graphkindkind;
}graph
十字链表:
用来表示有向图.有向图中,每一条边用一个结点表示,每个顶点也用一个结点表示.(了解)
深度优先遍历(dfs)
算法思想:
1)访问给定结点;
2)重复对第一个未被访问的邻接点进行深度优先遍历,直到不存在未被访问的邻接点结束.可以用一个数组标识顶点是否被访问过.
voidDFStraverse(GraphG)
{for(v=0;vfor(v=0;vif(!
visited[v])DFS(G,v);
}
voidDFS(GraphG,intv)//连通图的遍历
{visit(v);visited[v]=TRUE;
for(w=First_Adj(G,V);w;w=Next_Adj(G,v,w))
if(!
visited[w])DFS(G,w);
}
广度优先遍历(bfs)
算法思想:
1)访问给定结点v;
2)由近至远,依次访问和v有路径相连且长度为1,2,3......的顶点.可以用一个数组标识顶点是否被访问过.用一个队列存放刚访问过的结点.
voidBFStraverse(GraphG)
{for(v=0;viniqueue(Q);//建立空队列Q
for(v=0;vif(!
visited[v])
{visit(v);visited[v]=TRUE;Enqueue(Q,v);//入队
while(!
Queueempty(Q))
{Dequeue(Q,u);//出队
for(w=First_Adj(G,u);w;w=Next_Adj(G,u,w))
if(!
visited[w])
{visit(w);visited[w]=TRUE;Enqueue(Q,w);}//再入队
}
例如:
}
}
深度优先遍历:
abdhecfg
广度优先遍历:
abcdefgh
生成树:
一个连通图的生成树是由n-1条边且包含G的所有顶点的树组成.
可按深度或广度优先遍历来创建生成树.
最小生成树:
对具有n个结点的网,如何选择n-1条边构成的生成树,其权值和最小.权值和最小的生成树即为最小生成树.
最小生成树的性质(MST):
假设N=(V,E)是连通网,UV若是一条具有最小权值的边,u∈U,v∈V-U,则必然存在一棵包含边的最小生成树.
prim算法:
1设U={u0},T={};
2重复执行如下操作:
在所有u∈U,v∈V-U的边∈E中找一条代价最小的边,并入T中,U=U+{v’},直到U=V或T中有n-1条边.
kruscal算法:
(结果也如上图)
1设G=(V,E);T=(v,{});
2从E中选一条最小权值的边,并从E中消除此边
3若属于T中不同的连通分量,则将加入到
T中,重复2,直到T中有n-1条边.
最短路径:
设V0,V1,V2,......Vn-1为n个顶点序列,求V0到各顶点的最短路径.
Dijkstra算法:
令dist[i]表示已经求出的v0到vi的最短路径,S表示已求出最短路径的顶点.
1)令dist[v0]=0;dist[i]=∞|i≠v0;S={v0};
2)求下一条最短路径:
dist[j]=Min{dist[i]+cost[i,k]|vi∈S,vk∈V-S}
3)令S=S+{vj};重复2)直到S=V.
Dijkstra算法的中心思想是采用路径长度递增产生最短路径.
第8章查找
重点:
折半查找,了解顺序、索引查找,
二叉排序树的插入删除(算法思路)
哈希表
元素类型定义:
typedefstruct
{keytypekey;
其它域定义
}elemtype
顺序存储结构
typedefstruct
{elemtype*elem;
intlength;
}SStable
顺序查找算法
intsearch(SStableST,key)
{ST.elem[0].key=key;//0位置本身为空单元
for(i=ST.length;!
EQ(ST.elem[i].key,key);--i);
returni;
}//若存在返回在静态表中的位置i,否则i=0
折半查找
(1)折半查找思想
(2)折半查找算法
intsearch(SStableST,key)
{low=1;high=ST.length;
while(low<=high)
{mid=(low+high)/2;
if(EQ(key,ST.elem[mid].key))returnmid;
elseif(LT(key,ST.elem[mid].key))high=mid-1
elselow=mid+1
}return0
}//O(logn)
注:
EQ()与LT()是比较函数(书P215)
二叉排序树
定义:
二叉排序树或为空树,或为如下性质的二叉树:
1>左子树任意结点的值小于根结点值;
2>右子树任意结点的值大于根结点值;
3>左右子树仍然为二叉排序树.
查找:
StatusSearchBST(BTreeT,keytypekey,BTreef,BTree&p)
//f为T的父结点,
//p返回查找到的结点或
//未查找到的叶结点(待插入的位置)
{if(!
T){p=f;returnFalse;}
elseifEQ(key,T->