数据结构.docx

上传人:b****4 文档编号:4345472 上传时间:2022-11-30 格式:DOCX 页数:21 大小:1.34MB
下载 相关 举报
数据结构.docx_第1页
第1页 / 共21页
数据结构.docx_第2页
第2页 / 共21页
数据结构.docx_第3页
第3页 / 共21页
数据结构.docx_第4页
第4页 / 共21页
数据结构.docx_第5页
第5页 / 共21页
点击查看更多>>
下载资源
资源描述

数据结构.docx

《数据结构.docx》由会员分享,可在线阅读,更多相关《数据结构.docx(21页珍藏版)》请在冰豆网上搜索。

数据结构.docx

数据结构

第一章:

基本概念:

数据结构,基本数据结构的总类,存储结构的分类,算法的评价标准

数据结构(DataStructure):

是指相互之间具有(存在)一定联系(关系)的数据元素的集合。

元素之间的相互联系(关系)称为逻辑结构。

①集合:

结构中的数据元素除了“同属于一个集合”外,没有其它关系。

②线性结构:

结构中的数据元素之间存在一对一的关系。

③树型结构:

结构中的数据元素之间存在一对多的关系。

④图状结构或网状结构:

结构中的数据元素之间存在多对多的关系。

存储结构的分类

由此得出两种不同的存储结构:

顺序存储结构和链式存储结构。

顺序存储结构:

用数据元素在存储器中的相对位置来表示数据元素之间的逻辑结构(关系)。

链式存储结构:

在每一个数据元素中增加一个存放另一个元素地址的指针(pointer),用该指针来表示数据元素之间的逻辑结构(关系)。

算法的评价标准

算法(Algorithm):

是对特定问题求解方法(步骤)的一种描述,是指令的有限序列,其中每一条指令表示一个或多个操作。

算法具有以下五个特性

①有穷性:

一个算法必须总是在执行有穷步之后结束,且每一步都在有穷时间内完成。

②确定性:

算法中每一条指令必须有确切的含义。

不存在二义性。

且算法只有一个入口和一个出口。

③可行性:

一个算法是能行的。

即算法描述的操作都可以通过已经实现的基本运算执行有限次来实现。

④输入:

一个算法有零个或多个输入,这些输入取自于某个特定的对象集合。

⑤输出:

一个算法有一个或多个输出,这些输出是同输入有着某些特定关系的量。

一个算法可以用多种方法描述,主要有:

使用自然语言描述;使用形式语言描述;使用计算机程序设计语言描述。

评价一个好的算法有以下几个标准

①正确性(Correctness):

算法应满足具体问题的需求。

②可读性(Readability):

算法应容易供人阅读和交流。

可读性好的算法有助于对算法的理解和修改。

③健壮性(Robustness):

算法应具有容错处理。

当输入非法或错误数据时,算法应能适当地作出反应或进行处理,而不会产生莫名其妙的输出结果。

④通用性(Generality):

算法应具有一般性,即算法的处理结果对于一般的数据集合都成立。

⑤效率与存储量需求:

效率指的是算法执行的时间;存储量需求指算法执行过程中所需要的最大存储空间。

一般地,这两者与问题的规模有关

1简要回答术语:

数据,数据元素,数据结构,数据类型。

数据:

是客观事物的符号表示。

数据元素(DataElement):

是数据的基本单位,在程序中通常作为一个整体来进行考虑和处理。

数据结构:

有一定联系的数据元素集合。

数据类型:

指的是一个值的集合和定义在该值集上的一组操作的总称。

2数据的逻辑结构?

数据的物理结构?

逻辑结构与物理结构的区别和联系是什么?

逻辑结构:

数据元素之间逻辑关系的描述;

物理结构:

数据元素在计算机中的存储及其逻辑关系的表现称为数据的存储结构或物理结构;

逻辑结构,物理结构.

顺序表的时候,

链表

3数据结构的主要运算包括哪些?

数据结构的主要运算包括:

⑴建立(Create)一个数据结构;

⑵消除(Destroy)一个数据结构;

⑶从一个数据结构中删除(Delete)一个数据元素;

⑷把一个数据元素插入(Insert)到一个数据结构中;

⑸对一个数据结构进行访问(Access);

⑹对一个数据结构(中的数据元素)进行修改(Modify);

⑺对一个数据结构进行排序(Sort);

⑻对一个数据结构进行查找(Search)。

4算法分析的目的是什么?

算法分析的主要方面是什么?

5分析以下程序段的时间复杂度,请说明分析的理由或原因。

第二章:

线性表的概念,顺序存储结构的特点,链式存储结构的特点,单线性链表的插入与删除算法

线性表的概念:

线性表(LinearList):

是由n(n≧0)个数据元素(结点)a1,a2,…an组成的有限序列。

该序列中的所有结点具有相同的数据类型。

其中数据元素的个数n称为线性表的长度。

顺序存储结构的特点:

顺序存储:

把线性表的结点按逻辑顺序依次存放在一组地址连续的存储单元里。

用这种方法存储的线性表简称顺序表。

顺序存储的线性表的特点:

◆线性表的逻辑顺序与物理顺序一致;

◆数据元素之间的关系是以元素在计算机内“物理位置相邻”来体现。

链式存储结构的特点:

链式存储:

用一组任意的存储单元存储线性表中的数据元素。

用这种方法存储的线性表简称线性链表。

存储链表中结点的一组任意的存储单元可以是连续的,也可以是不连续的,甚至是零散分布在内存中的任意位置上的。

链表中结点的逻辑顺序和物理顺序不一定相同。

单线性链表的插入与删除算法

第三章:

栈和队列

栈的概念和特点

队列的概念和特点

顺序队列的进队,出队过程(图)

循环静态队列的进队,出队过程

栈的概念和特点

栈(Stack):

是限制在表的一端进行插入和删除操作的线性表。

又称为后进先出LIFO(LastInFirstOut)或先进后出FILO(FirstInLastOut)线性表。

队列的概念和特点

队列(Queue):

也是运算受限的线性表。

是一种先进先出(FirstInFirstOut,简称FIFO)的线性表。

只允许在表的一端进行插入,而在另一端进行删除。

队首(front):

允许进行删除的一端称为队首。

队尾(rear):

允许进行插入的一端称为队尾。

利用一组连续的存储单元(一维数组)依次存放从队首到队尾的各个元素,称为顺序队列

设立一个队首指针front,一个队尾指针rear,分别指向队首和队尾元素。

◆初始化:

front=rear=0。

◆入队:

将新元素插入rear所指的位置,然后rear加1。

◆出队:

删去front所指的元素,然后加1并返回被删元素。

◆队列为空:

front=rear。

◆队满:

rear=MAX_QUEUE_SIZE-1或front=rear。

循环静态队列的进队,出队过程

将为队列分配的向量空间看成为一个首尾相接的圆环,并称这种队列为循环队列(CircularQueue)。

第五章:

求元素的存储位置

对称矩阵的存储位置

广义表基本概念:

表头,广度,深度

设有二维数组a[6][8],每个元素占相邻的4个字节,存储器按字节编址,已知a的起始地址是1000,试计算:

①数组a的最后一个元素a[5][7]起始地址;

②按行序优先时,元素a[4][6]起始地址;

③按行序优先时,元素a[4][6]起始地址。

1000+47*4;

//32+6

1000+38*4

36+4

100+40*4

01234567

1

2

3

46

5

对称矩阵的存储位置

广义表是线性表的推广和扩充,在人工智能领域中应用十分广泛。

广义表(Lists,又称为列表):

是由n(n≧0)个元素组成的有穷序列:

LS=(a1,a2,…,an)

◆a1(表中第一个元素)称为表头;

◆其余元素组成的子表称为表尾;(a2,a3,…,an)

◆广义表中所包含的元素(包括原子和子表)的个数称为表的长度。

◆广义表中括号的最大层数称为表深(度)。

有关广义表的这些概念的例子如表5-2所示。

第六章:

树,二叉树

二叉树的几个性质

二叉树的遍历的思想,算法,遍历过程

二叉树遍历的应用:

层次树

树的存储结构:

符合链表的孩子链表,树向二叉树的转换,哈夫曼树的结构过程

性质1:

在非空二叉树中,第i层上至多有2i-1个结点(i≧1)。

性质2:

深度为k的二叉树至多有2k-1个结点(k≧1)。

性质3:

对任何一棵二叉树,若其叶子结点数为n0,度为2的结点数为n2,则n0=n2+1。

满二叉树的特点:

◆基本特点是每一层上的结点数总是最大结点数。

◆满二叉树的所有的支结点都有左、右子树。

◆可对满二叉树的结点进行连续编号,若规定从根结点开始,按“自上而下、自左至右”的原则进行。

性质4:

n个结点的完全二叉树深度为:

㏒2n+1。

其中符号:

x表示不大于x的最大整数。

x表示不小于x的最大整数。

层次遍历二叉树,是从根结点开始遍历,按层次次序“自上而下,从左至右”访问树中的各结点。

#defineMAX_NODE50

voidLevelorderTraverse(BTNode*T)

{BTNode*Queue[MAX_NODE],*p=T;

intfront=0,rear=0;

if(p!

=NULL)

{Queue[++rear]=p;/*根结点入队*/

while(front

{p=Queue[++front];visit(p->data);

if(p->Lchild!

=NULL)

Queue[++rear]=p;/*左结点入队*/

if(p->Lchild!

=NULL)

Queue[++rear]=p;/*左结点入队*/

}

}

}

满二叉树:

#defineMAX_NODE50

typedefstructBTNode

{chardata;

structBTNode*Lchild,*Rchild;

}BTNode;

BTNode*Create_BTree(void)

/*建立链式二叉树,返回指向根结点的指针变量*/

{BTNode*T,*p,*s[MAX_NODE];

charch;inti,j;

while

(1)

{scanf(“%d”,&i);

if(i==0)break;/*以编号0作为输入结束*/

else

{ch=getchar();

p=(BTNode*)malloc(sizeof(BTNode));

p–>data=ch;

p–>Lchild=p–>Rchild=NULL;s[i]=p;

if(i==1)T=p;

else

{j=i/2;/*j是i的双亲结点编号*/

if(i%2==0)s[j]->Lchild=p;

elses[j]->Rchild=p;

}

}

}

return(T);

}

按先序遍历方式建立

算法实现:

#defineNULLKY‘?

#defineMAX_NODE50

typedefstructBTNode

{chardata;

structBTNode*Lchild,*Rchild;

}BTNode;

BTNode*Preorder_Create_BTree(BTNode*T)

/*建立链式二叉树,返回指向根结点的指针变量*/

{charch;

ch=getchar();getchar();

if(ch==NULLKY)

{T=NULL;return(T);}

else

{T=(BTNode*)malloc(sizeof(BTNode));

T–>data=ch;

Preorder_Create_BTree(T->Lchild);

Preorder_Create_BTree(T->Rchild);

return(T);

}

}

当希望创建图6-10(a)所示的二叉树时,输入的字符序列应当是:

ABD?

?

E?

G?

?

CF?

?

?

2求二叉树的叶子结点数

可以直接利用先序遍历二叉树算法求二叉树的叶子结点数。

只要将先序遍历二叉树算法中vist()函数简单地进行修改就可以。

算法实现:

#defineMAX_NODE50

intsearch_leaves(BTNode*T)

{BTNode*Stack[MAX_NODE],*p=T;

inttop=0,num=0;

if(T!

=NULL)

{stack[++top]=p;

while(top>0)

{p=stack[top--];

if(p->Lchild==NULL&&p->Rchild==NULL)num++;

if(p->Rchild!

=NULL)

stack[++top]=p->Rchild;

if(p->Lchild!

=NULL)

stack[++top]=p->Lchild;

}

}

return(num);

}

3求二叉树的深度

利用层次遍历算法可以直接求得二叉树的深度。

算法实现:

#defineMAX_NODE50

intsearch_depth(BTNode*T)

{BTNode*Stack[MAX_NODE],*p=T;

intfront=0,rear=0,depth=0,level;

/*level总是指向访问层的最后一个结点在队列的位置*/

if(T!

=NULL)

{Queue[++rear]=p;/*根结点入队*/

level=rear;/*根是第1层的最后一个节点*/

while(front

{p=Queue[++front];

if(p->Lchild!

=NULL)

Queue[++rear]=p;/*左结点入队*/

if(p->Lchild!

=NULL)

Queue[++rear]=p;/*左结点入队*/

if(front==level)

/*正访问的是当前层的最后一个结点*/

{depth++;level=rear;}

}

}

}

树中每个结点有多个指针域,每个指针指向其一棵子树的根结点。

有两种结点结构。

⑴定长结点结构

指针域的数目就是树的度。

其特点是:

链表结构简单,但指针域的浪费明显。

结点结构如图6-14(a)所示。

在一棵有n个结点,度为k的树中必有n(k-1)+1空指针域。

⑵不定长结点结构

树中每个结点的指针域数量不同,是该结点的度,如图6-14(b)所示。

没有多余的指针域,但操作不便。

⑶复合链表结构

对于树中的每个结点,其孩子结点用带头结点的单链表表示,表结点和头结点的结构如图6-15所示。

n个结点的树有n个(孩子)单链表(叶子结点的孩子链表为空),而n个头结点又组成一个线性表且以顺序存储结构表示。

数据结构类型定义如下:

#defineMAX_NODE100

typedefstructlistnode

{intchildno;/*孩子结点编号*/

structlistno*next;

}CTNode;/*表结点结构*/

typedefstruct

{ElemTypedata;

CTNode*firstchild;

}HNode;/*头结点结构*/

typedefstruct

{HNodenodes[MAX_NODE];

introot;/*根结点位置*/

intnum;/*结点数*/

}CLinkList;/*头结点结构*/

图6-13所示的树T的孩子链表表示的存储结构如图6-16所示。

3孩子兄弟表示法(二叉树表示法)

以二叉链表作为树的存储结构,其结点形式如图6-17(a)所示。

两个指针域:

分别指向结点的第一个子结点和下一个兄弟结点。

结点类型定义如下:

typedefstructCSnode

{ElemTypedata;

structCSnode*firstchild,*nextsibing;

}CSNode;

图6-17(b)所示树的孩子兄弟表示的存储结构如图6-17(c)。

树向二叉树的转换:

1树转换成二叉树

对于一般的树,可以方便地转换成一棵唯一的二叉树与之对应。

将树转换成二叉树在“孩子兄弟表示法”中已给出,其详细步骤是:

⑴加虚线。

在树的每层按从“左至右”的顺序在兄弟结点之间加虚线相连。

⑵去连线。

除最左的第一个子结点外,父结点与所有其它子结点的连线都去掉。

⑶旋转。

将树顺时针旋转450,原有的实线左斜。

⑷整型。

将旋转后树中的所有虚线改为实线,并向右斜。

该转换过程如图6-19所示。

2二叉树转换成树

对于一棵转换后的二叉树,如何还原成原来的树?

其步骤是:

⑴加虚线。

若某结点i是其父结点的左子树的根结点,则将该结点i的右子结点以及沿右子链不断地搜索所有的右子结点,将所有这些右子结点与i结点的父结点之间加虚线相连,如图6-20(a)所示。

⑵去连线。

去掉二叉树中所有父结点与其右子结点之间的连线,如图6-20(b)所示。

⑶规整化。

将图中各结点按层次排列且将所有的虚线变成实线,如图6-20(c)所示。

哈夫曼树的结构过程

6.6.1最优二叉树(Huffman树)

1基本概念

①结点路径:

从树中一个结点到另一个结点的之间的分支构成这两个结点之间的路径。

②路径长度:

结点路径上的分支数目称为路径长度。

③树的路径长度:

从树根到每一个结点的路径长度之和。

例图6-23的树。

A到F:

结点路径AEF;路径长度(即边的数目)2;树的路径长度:

31+52+23=19

④结点的带权路径长度:

从该结点的到树的根结点之间的路径长度与结点的权(值)的乘积。

权(值):

各种开销、代价、频度等的抽象称呼。

⑤树的带权路径长度:

树中所有叶子结点的带权路径长度之和,记做:

WPL=w1l1+w2l2+⋯+wnln=∑wili(i=1,2,⋯,n)

其中:

n为叶子结点的个数;wi为第i个结点的权值;li为第i个结点的路径长度。

⑥Huffman树:

具有n个叶子结点(每个结点的权值为wi)的二叉树不止一棵,但在所有的这些二叉树中,必定存在一棵WPL值最小的树,称这棵树为Huffman树(或称最优树)。

第七章:

图的主要概念,度与顶点的主要关系,图的存储结构:

图,数组,链接结构。

最小生成树:

(算法),思想,实现过程

图结构:

是研究数据元素之间的多对多的关系

图的主要概念

一个图(G)定义为一个偶对(V,E),记为G=(V,E)。

其中:

V是顶点(Vertex)的非空有限集合,记为V(G);E是无序集V&V的一个子集,记为E(G),其元素是图的弧(Arc)。

度与顶点

顶点的度、入度、出度:

对于无向图G=(V,E),viV,图G中依附于vi的边的数目称为顶点vi的度(degree),记为TD(vi)。

显然,在无向图中,所有顶点度的和是图中边的2倍。

即∑TD(vi)=2ei=1,2,…,n,e为图的边数。

对有向图G=(V,E),若viV,图G中以vi作为起点的有向边(弧)的数目称为顶点vi的出度(Outdegree),记为OD(vi);以vi作为终点的有向边(弧)的数目称为顶点vi的入度(Indegree),记为ID(vi)。

顶点vi的出度与入度之和称为vi的度,记为TD(vi)。

TD(vi)=OD(vi)+ID(vi)

图的存储结构:

图,数组,链接结构

图的常用的存储结构有:

邻接矩阵、邻接链表、十字链表、邻接多重表和边表。

如果连通图是一个带权图,则其生成树中的边也带权,生成树中所有边的权值之和称为生成树的代价。

最小生成树(MinimumSpanningTree):

带权连通图中代价最小的生成树称为最小生成树。

最小生成树在实际中具有重要用途,如设计通信网。

设图的顶点表示城市,边表示两个城市之间的通信线路,边的权值表示建造通信线路的费用。

n个城市之间最多可以建n(n-1)/2条线路,如何选择其中的n-1条,使总的建造费用最低?

构造最小生成树的算法有许多,基本原则是:

构造最小生成树的算法有许多,基本原则是:

◆尽可能选取权值最小的边,但不能构成回路;

◆选择n-1条边构成最小生成树。

以上的基本原则是基于MST的如下性质:

设G=(V,E)是一个带权连通图,U是顶点集V的一个非空子集。

若u∈U,v∈V-U,且(u,v)是U中顶点到V-U中顶点之间权值最小的边,则必存在一棵包含边(u,v)的最小生成树。

第九章查找

折半查找的思想,算法,实现过程

二叉排序树的概念,构造过程,插入删除节点的过程

二叉排序树的查询算法

哈希表的概念,构造

折半查找又称为二分查找,是一种效率较高的查找方法。

前提条件:

查找表中的所有记录是按关键字有序(升序或降序)。

查找过程中,先确定待查找记录在表中的范围,然后逐步缩小范围(每次将待查记录所在区间缩小一半),直到找到或找不到记录为止。

1查找思想

用Low、High和Mid表示待查找区间的下界、上界和中间位置指针,初值为Low=1,High=n。

⑴取中间位置Mid:

Mid=(Low+High)/2;

⑵比较中间位置记录的关键字与给定的K值:

①相等:

查找成功;

②大于:

待查记录在区间的前半段,修改上界指针:

High=Mid-1,转⑴;

③小于:

待查记录在区间的后半段,修改下界指针:

Low=Mid+1,转⑴;

直到越界(Low>High),查找失败。

二叉排序树(BST)的定义

二叉排序树(BinarySortTree或BinarySearchTree)的定义为:

二叉排序树或者是空树,或者是满足下列性质的二叉树。

(1):

若左子树不为空,则左子树上所有结点的值(关键字)都小于根结点的值;

(2):

若右子树不为空,则右子树上所有结点的值(关键字)都大于根结点的值;

(3):

左、右子树都分别是二叉排序树。

结论:

若按中序遍历一棵二叉排序树,所得到的结点序列是一个递增序列。

BST仍然可以用二叉链表来存储,如图9-4所示。

结点类型定义如下:

typedefstructNode

{KeyTypekey;/*关键字域*/

…/*其它数据域*/

structNode*Lchild,*Rchild;

}BSTNode;

9.3.2BST树的查找

1查找思想

首先将给定的K值与二叉排序树的根结点的关键字进行比较:

若相等:

则查找成功;

①给定的K值小于BST的根结点的关键字:

继续在该结点的左子树上进行查找;

②给定的K值大于BST的根结点的关键字:

继续在该结点的右子树上进行查找。

2算法实现

⑴递归算法

BSTNode*BST_Serach(BSTNode*T,KeyTypekey)

{if(T==NULL)return(NULL);

else

{if(EQ(T->key,key))return(T);

elseif(LT(key,T->key))

return(BST_Serach(T->Lchild,key));

elsereturn(BST_Serach(T->Rchild,key));

}

}

哈希函数:

在记录的关键字与记录的存储地址之间建立的一种对应关系叫哈希函数。

哈希函数是一种映象,是从关键字空间到

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 解决方案 > 学习计划

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1