数据结构重点总结Word格式文档下载.docx
《数据结构重点总结Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《数据结构重点总结Word格式文档下载.docx(26页珍藏版)》请在冰豆网上搜索。
=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<
L.length)returnERROR;
e=L.elem[i-1]);
for(j=i;
j<
L.length;
++j)
L.elem[j-1]=L.elem[j]);
--L.length;
单链表定义:
typedefstructLnode{
Elemtypedata;
structLnode*next;
}Lnode,*Linklist;
链式定位插入
StatusListinsert_L(Linklist&
L,inti,Elemtypee)
{
p=L;
j=0;
while(p&
&
i-1)
{p=p->
next;
++j}
if(!
p‖j>
i-1)returnERROR;
new(s);
s->
data=e;
next=p->
p->
next=s;
链式定位删除
StatusListdelete_L(Linklist&
L,inti,Elemtype&
while(p->
next&
{p=p->
++j}
(p->
next)‖j>
q=p->
next;
next=q->
e=q->
data;
free(q);
双向链表结点的存储结构定义
typedefstructDublnode{
Elemtypedata;
structDublnode*prior;
structDublnode*next;
}Dublnode,*Dublinklist;
了解:
有序表的合并
voidMergelist_L(Linklist&
La,Linklist&
Lb,Linklist&
Lc)
pa=La->
pb=Lb->
Lc=pc=La;
while(pa&
pb)
{if(pa->
data<
=pb->
data)
{pc->
next=pa;
pc=pa;
pa=pa->
else
next=pb;
pc=pb;
pb=pb->
pc->
next=pa?
pa:
pb;
free(Lb);
第3章、栈与队列
1、栈的插入,删除,和取栈顶
2、队列的取对头,插入,删除(循环队列)
栈的存储结构定义:
#defineStack_init_size100;
#defineStackincrement10;
typedefstruct{
Selemtype*base;
指向第一个元素(有数)
Selemtype*top;
指向最后一个元素的下一位(为空)
intstacksize;
}Sqstack;
栈的取栈顶
StatusGettop(Sqstacks,Selemtype&
{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;
栈的删除栈顶
StatusPop(Sqstack&
s,Selemtype&
{if(s.top==s.base)returnERROR;
e=*--s.top
队列的顺序存储表示与实现
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;
队的删除
StatusDequeue(sqqueue&
Q,Qelemtype&
{if(Q.front==Q.rear)returnERROR;
e=Q.base[Q.front];
Q.front=(Q.front+1)%Maxsize;
取对头
StatusGetHead(sqqueue&
returnQ.base[Q.front];
第四章串
串的比较、连接,了解串的插入,删除
定义
typedefstruct
{char*ch;
intlength;
}Hstring;
比较
statusstrcompare(S,T)
{for(i=0;
i<
S.length&
T.length;
++i)
if(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);
(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];
第5章数组和广义表
特殊矩阵,稀疏矩阵(明白思路)
对称矩阵aij=aji0≤i,j≤n-1
SA[k]=aijk=i(i+1)/2+j(i>
=j)或k=j(j+1)/2+i(i<
j)
稀疏矩阵一般采用三元组存储一个非零元素。
如:
三元组
(1,5,a)
(2,2,b)
(3,4,c)
(4,7,d)
三元组定义
#defineMaxsize=1000
{inti,j;
elemtypee;
}triple
{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)
{visit(bt->
preorder(bt->
后序
Voidpostorder(bt)
{postorder(bt->
postorder(bt->
树的存储结构(书上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>
;
若<
为有向边,则称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若<
Vi,Vj>
∈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)
typedefstructArcnode//边结点类型
{intvjpos;
//vj的位置
structArcnode*nextarc;
}Arcnode;
typedefstructVnode//顶点结点类型
{vextypedata;
Arcnode*firsttarc;
}Vnode,Adjlist[Max_V_num];
{Adjlistvexs;
}graph
十字链表:
用来表示有向图.有向图中,每一条边用一个结点表示,每个顶点也用一个结点表示.(了解)
深度优先遍历(dfs)
算法思想:
1)访问给定结点;
2)重复对第一个未被访问的邻接点进行深度优先遍历,直到不存在未被访问的邻接点结束.可以用一个数组标识顶点是否被访问过.
voidDFStraverse(GraphG)
{for(v=0;
v<
G.vexnum;
++v)visited[v]=FALSE;
for(v=0;
++v)//保证非连通图的遍历
if(!
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))
visited[w])DFS(G,w);
广度优先遍历(bfs)
1)访问给定结点v;
2)由近至远,依次访问和v有路径相连且长度为1,2,3......的顶点.可以用一个数组标识顶点是否被访问过.用一个队列存放刚访问过的结点.
voidBFStraverse(GraphG)
iniqueue(Q);
//建立空队列Q
visited[v])
{visit(v);
Enqueue(Q,v);
//入队
while(!
Queueempty(Q))
{Dequeue(Q,u);
//出队
for(w=First_Adj(G,u);
w=Next_Adj(G,u,w))
visited[w])
{visit(w);
visited[w]=TRUE;
Enqueue(Q,w);
}//再入队
例如:
深度优先遍历:
abdhecfg
广度优先遍历:
abcdefgh
生成树:
一个连通图的生成树是由n-1条边且包含G的所有顶点的树组成.
可按深度或广度优先遍历来创建生成树.
最小生成树:
对具有n个结点的网,如何选择n-1条边构成的生成树,其权值和最小.权值和最小的生成树即为最小生成树.
最小生成树的性质(MST):
假设N=(V,E)是连通网,UV若<
u,v>
是一条具有最小权值的边,u∈U,v∈V-U,则必然存在一棵包含边<
的最小生成树.
prim算法:
1设U={u0},T={};
2重复执行如下操作:
在所有u∈U,v∈V-U的边<
∈E中找一条代价最小的边<
u’,v’>
并入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章查找
折半查找,了解顺序、索引查找,
二叉排序树的插入删除(算法思路)
哈希表
元素类型定义:
{keytypekey;
其它域定义
}elemtype
顺序存储结构
typedefstruct
{elemtype*elem;
}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)折半查找算法
{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->