数据结构基础知识要点.docx
- 文档编号:12153150
- 上传时间:2023-04-17
- 格式:DOCX
- 页数:29
- 大小:173.62KB
数据结构基础知识要点.docx
《数据结构基础知识要点.docx》由会员分享,可在线阅读,更多相关《数据结构基础知识要点.docx(29页珍藏版)》请在冰豆网上搜索。
数据结构基础知识要点
第1章数据结构
1.定义
数据结构就是计算机存储、组织数据得方式。
数据结构就是抽象数据类型得物理实现。
2、数据结构包括如下几个方面:
(1)数据元素之间得逻辑关系,即数据得逻辑结构。
(2)数据元素及其关系在计算机存储器中得存储方式,即数据得存储结构,也称为数据得物理结构。
(3)施加在该数据上得操作,即数据得运算。
2、逻辑结构类型
(1)集合结构。
交通工具得集合,动物得集合
(2)线性结构。
一对一,综合素质测评产生得学生排名
(3)树形结构。
一对多,单位得组织结构图,族谱
(4)图形结构。
多对多,生产流程、施工计划、网络建设图等
3.存储结构类型
(1)顺序存储方法。
数组
(2)链式存储方法。
链表
(3)索引存储方法
(4)散列存储方法
4.算法
通常把具体存储结构上得操作实现步骤或过程称为算法。
C语言里通常表现为解决问题得步骤
程序=算法(加工数据)+数据结构(数据得存储与组织)
5.算法得五个特征
(1)有穷性:
在有穷步之后结束。
(2)确定性:
无二义性。
(3)可行性:
可通过基本运算有限次执行来实现。
(4)有输入:
可有零个或多个。
(5)有输出:
至少有一个输出。
6.算法分析
(1)时间复杂度:
(算法得工作量大小)通常把算法中包含基本运算次数得多少称为算法得时间复杂度,也就就是说,一个算法得时间复杂度就是指该算法得基本运算次数。
算法中基本运算次数T(n)就是问题规模n得某个函数f(n),记作:
T(n)=O(f(n))
(2)空间复杂度:
实现算法所需得存储单元多少
第二章线性表
1、线性表得基本概念
线性表就是具有相同特性得数据元素得一个有限序列。
该序列中所含元素得个数叫做线性表得长度,用n表示,n≥0。
2、线性结构得基本特征为:
(1)集合中必存在唯一得一个“第一元素”;
(2)集合中必存在唯一得一个“最后元素”;
(3)除最后一个元素之外,均有唯一得后继(后件);
(4)除第一个元素之外,均有唯一得前驱(前件)。
3、定义顺序表
线性表逻辑结构
顺序表存储结构
typedefstruct
{
ElemTypedata[MAXCOUNT];//定义存放顺序表元素得数组
intlength;//length为存放线性表得实际长度
}SqList;//顺序表类型
4、顺序表上得运算及其实现
(1)、建立顺序表CreateList
创建一个空得顺序表,要完成线性表所需空间得分配与其她初始化设置。
(2)求线性表得长度ListLength
(3)输出线性表DispList
(4)在线性表中得指定位置插入一个元素InsertElem
(5)根据键值查找指定元素FindElemByNum
(6)获取指定位置得元素信息GetElem
(7)删除指定位置得元素DelElem
(8)释放线性表DestroyList
5、线性表得链式存储——单链表(data域与指针域next)
由于顺序表中得每个元素至多只有一个前驱元素与一个后继元素,即数据元素之间就是一对一得逻辑关系,所以当进行链式存储时,一种最简单也最常用得方法就是:
在每个结点中除包含有数据域外,只设置一个指针域,用以指向其后继结点,这样构成得链接表称为线性单向链接表,简称单链表;
7、单链表得定义
LinkList类型得定义如下:
typedefstructLNode/*定义单链表结点类型*/
{
ElemTypedata;
structLNode*next;/*指向后继结点*/
}LinkList;
8、顺序表上得运算及其实现
1、创建单链表LinkList*CreateList();
2、初始化单链表voidInitList(LinkList*list);
3、释放单链表voidDestroyList(LinkList*list);
4、获取单链表中元素得数量intListLength(LinkList*list);
5、输出单链表中得所有数据voidDispList(LinkList*list);
6、获取单链表中指定位置得元素intGetElem(LinkList*list,intloc,ElemType*pElem);
7、根据键值查找指定元素intFindElemByNum(LinkList*list,char*keyCh,ElemType*pElem);
8、采用头插法向单链表中插入一个元素
intInsertElem_Head(LinkList*list,ElemTypemyElem);
9、采用尾插法向单链表中插入一个元素
intInsertElem_Foot(LinkList*list,ElemTypemyElem);
10、向单链表中得指定位置插入一个元素
ntInsertElem_Loc(LinkList*list,intloc,ElemTypemyElem);
11、删除指定位置得元素
intDelElem(LinkList*list,intloc,ElemType*pElem);
9、线性表得链式存储——双链表(data域指针域next与pre前驱)
对于双链表,采用类似于单链表得类型定义,其DLinkList类型得定义如下:
typedefstructDNode/*定义双链表结点类型*/
{
ElemTypedata;
structDNode*prior;/*指向前驱结点*/
structDNode*next;/*指向后继结点*/
}DLinkList
在双链表中p所指得结点之后插入一个*s结点。
其操作语句描述为:
s->next=p->next;/*将s插入到p之后*/
p->next->prior=s;
s->prior=p;
p->next=s;
归纳起来,删除双链表L中*p结点得后续结点。
其操作语句描述为:
p->next=q->next;
q->next->prior=p;
10、循环链表
循环链表就是另一种形式得链式存储结构。
它得特点就是表中最后一个结点得指针域不再就是空,而就是指向表头结点,整个链表形成一个环。
由此,从表中任一结点出发均可找到链表中其她结点。
带头结点得单向循环链表与双向循环链表如下图
第三章栈与队列
1、栈得定义及基本运算
栈就是限定只能在表尾进行插入与删除得线性表,并将表尾称为栈顶,表头称为栈底。
栈得基本运算如下:
(1)判栈空IsEmpty(S)、若栈为空则返回“真“,否则返回”假“;
(2)入栈操作(压栈)Push(S,x)将新元素压入栈中,使其成为栈顶元素;
(3)出栈操作(弹栈)Pop(S,x)若栈不空则返回栈顶元素,并从栈中删除栈顶元素,否则返回NULL;
(4)取栈顶元素GetTop(s,x)若栈不空则返回栈顶元素,否则返回NULL;
(5)置空栈Clear(s)将当前栈设定为空栈;
2、顺序栈得存储结构及算法实现
1>顺序栈
顺序栈利用一组连续得存储单元存放从栈底到栈顶得诸元素。
typedefstruct
{
int*data;
intcapacity;
inttop;
}Stack;
2>顺序栈得基本运算得实现
(1)入栈操作intPush(StackS,Datatypex);
(2)出栈操作intPop(Stacks,Datatype*x);
(3)取栈顶操作intGetTop(StackS,Datatype*x);
3、栈得链表存储结构
1>栈可以用单链表作为存储结构,链表得结点结构描述如下:
typedefcharElemType;
typedefstructLsnode
{
ElemTypedata;
structLsnode*next;
}Lsnode;//结点得类型标识符
Lsnode*top;
2>栈得相关术语
1.初始化空栈
voidIniStack(Lsnode*top)
{
top->next=NULL;
}
调用此函数之前,在主调函数中(例如main( ))说明一个指针变量后,先为它申请分配一个结点,然后调用初始化函数。
2.入栈操作
链栈入栈操作得含义就是:
将一个元素推入指定得链栈中。
对该操作应设置两个参数,即在参数中指定一个链栈及入栈得元素。
假设指定得链栈top,入栈元素x其类型为ElemType,入栈操作取名为push,则该操作可表示为:
viodPush(Lsnode*top,ElemTypex)
操作得功能为在由top指向得链栈中插入元素x,使x成为栈顶元素。
3、出栈操作
链栈出栈操作得含义就是:
从链栈中弹出栈顶结点并返回该结点中得元素值。
对该操作应设置一个参数,即在参数中指定一个链栈。
假设指定得链栈top,出栈操作取名为pop,则该操作可表示为:
ElemTypePop(Lsnode*top)
操作得功能为从由top指向得链栈中弹出栈顶结点并返回该结点中得元素值。
4、队列得基本操作
进队算法:
根据队列得结构,若队尾指针不在队得最大长度上,则首先队尾指针加1,元素进队,否则就就是队满,无法进队。
ADDQUEUE(queue,r,f,in)
/*在queue队列中进一个元素in,f与r分别就是队首与队尾得标志*/
{
if(r==n)
{
printf("队满");
}
else
{
r++;
queue[r]=in;
}
}
出队算法:
出队首先要判断队列中就是否有元素,即R就是否等于F,R=F可能出现在初态,也可能出现在出队、进队得动态变化中。
DELQUEUE(queue,r,f,out)
/*在queue队列中退出一个元素到out,f与r分别就是队首与队尾得标志*/
{
if(f==r)
{
printf("队空");
}
else
out=queue[++f];
}
5、链队得存储结构及其运算
当队空时,Front=NULL;Rear=NULL;所谓队满,就是指在可利用得空间表中,所有得结点被取完,即AV=NULL时,才表示队满。
根据队列得操作特点,进队与退队分别在表得两端进行,具体表现为“先进先出”。
从链队得结构可瞧出,进队得基本操作步骤为(设进队结点得地址为x):
Rear->next=x;
x->next=NULL;
Rear=x;
第四章串
1、串得基本概念
串结构得形式化定义为:
String=(D,R)
其中,D={ai︱ai∈character,i=1,2…n,n≥0},R={
(1)初始化ClearString(s):
初始化串s。
(2)StrAssign(s,ch):
串赋值。
(3)StrCopy(s,t):
串复制。
(4)StrConcat(t,s1,s2):
串联接。
(5)求串长StrLen(s):
返回s串得元素个数,即s串得长度。
(6)串比较Str(s,t)
(7)求子串SubStr(t,s,pos,len):
返回s串得第pos个字符起始得长度为len得子串。
(8)插入运算StrInsert(s,pos,t):
把串t得值插入到串s得第pos个字符之后。
(9)删除运算StrDel(s,pos,len):
将串s中从第pos字符起始得长度为len得子串删除。
(10)子串定位StrIndex(s,t,pos):
从主串s得第pos个字符起定位串s中就是否存在与串t值相等得子串,若存在,则返回子串t在主串s中第一次出现得位置,否则,返回函数值0。
(11)置换运算StrReplace(s,pos,len,t):
用t串置换s串中第pos字符开始得连续得len个字符。
2、串得定长顺序存储及运算实现
1>定长顺序串得基本运算实现
(1)求串长
(2)串得联接
(3)求子串
(4)子串得插入
(5)子串得删除
(6)串得置换
2>在堆式动态存储分配下得串得几种常见运算得实现。
(1)串赋值StrAssign(t,chars)
(2)串联接StrConcat(t,s1,s2)
(3)求子串SubString(t,s,pos,len)
(4)插入函数StrInsert(s,pos,t)
(5)删除函数StrDelete(s,pos,t)
3、串得块链存储表示
顺序串上得插入与删除操作运算需要移动大量得字符。
因此,可以采用单链表方式来存储串值,串得这种链式存储结构简称为链串。
但在利用链表存储串值时,每个结点既可以存放一个字符,也可以存放多个字符,即存在一个“结点大小”得问题。
结点得大小就是指结点得数据域可存放字符得个数。
第六章树与二叉树
1、树得表示
(1)树形表示法。
这就是树得最基本得表示,使用一棵倒置得树表示树结构,非常直观与形象
(2)文氏图表示法。
使用集合以及集合得包含关系描述树结构。
(3)凹入表示法。
使用线段得伸缩描述树结构。
(4)括号表示法。
将树得根结点写在括号得左边,
除根结点之外得其余结点写在括号中并用逗号
间隔来描述树结构。
2、树得基本术语
1、结点得度与树得度:
树中某个结点得子树得个数称为该结点得度。
树中各结点得度得最大值称为树得度,通常将度为m得树称为m次树。
2、分支结点与叶结点:
度不为零得结点称为非终端结点,又叫分支结点。
度为零得结点称为终端结点或叶结点。
在分支结点中,每个结点得分支数就就是该结点得度。
3、路径与路径长度:
如果一棵树中得一串结点n1,n2,…,nk,有如下关系:
结点ni就是ni+1得父结点(1≤i 4、孩子结点、双亲结点与兄弟结点: 在一棵树中,每个结点得后继,被称作该结点得孩子结点(或子女结点)。 相应地,该结点被称作孩子结点得双亲结点(或父母结点)。 具有同一双亲得孩子结点互为兄弟结点。 进一步推广这些关系,可以把每个结点得所有子树中得结点称为该结点得子孙结点,从树根结点到达该结点得路径上经过得所有结点被称作该结点得祖先结点 5、结点得层次与树得高度: 树中得每个结点都处在一定得层次上。 结点得层次从树根开始定义,根结点为第1层,它得孩子结点为第2层,以此类推,一个结点所在得层次为其双亲结点所在得层次加1。 树中结点得最大层次称为树得高度(或树得深度)。 6、有序树与无序树: 若树中各结点得子树就是按照一定得次序从左向右安排得,且相对次序就是不能随意变换得,则称为有序树,否则称为无序树。 7、森林: n(n>0)个互不相交得树得集合称为森林。 森林得概念与树得概念十分相近,因为只要把树得根结点删去就成了森林。 反之,只要给n棵独立得树加上一个结点,并把这n棵树作为该结点得子树,则森林就变成了树。 3、树得性质 性质1树中得结点数等于所有结点得度数加1。 性质2度为m得树中第i层上至多有mi-1个结点,这里应有i≥1。 性质3高度为h得m次树至多有个结点。 性质4具有n个结点得m次树得最小高度为⎡logm(n(m-1)+1)⎤。 4、树得特点: ①树得根结点没有前驱结点,除根结点之外得所有结点有且只有一个前驱结点。 ②树中所有结点可以有零个或多个后继结点。 5、树得基本运算 树得运算主要分为三大类: 第一类,寻找满足某种特定关系得结点,如寻找当前结点得双亲结点等; 第二类,插入或删除某个结点,如在树得当前结点上插入一个新结点或删除当前结点得第i个孩子结点等; 第三类,遍历树中每个结点,这里着重介绍。 树得遍历运算就是指按某种方式访问树中得每一个结点且每一个结点只被访问一次。 树得遍历运算得算法主要有先根遍历与后根遍历两种。 注意,下面得先根遍历与后根遍历算法都就是递归得。 1、先根遍历 先根遍历过程为: (1)访问根结点; (2)按照从左到右得次序先根遍历根结点得每一棵子树。 2、后根遍历 后根遍历过程为: (1)按照从左到右得次序后根遍历根结点得每一棵子树; (2)访问根结点。 6、二叉树得定义 二叉树(BinaryTree)就是n(n≥0)个结点得有限集合。 它或为空树(n=0),或为非空树;对于非空树有: (1)有一个特定得称之为根得结点; (2)根结点以外得其余结点分别由两棵互不相交得称之为左子树与右子树得二叉树组成。 这个递归定义表明二叉树或为空,或就是由一个根结点加上两棵分别称为左子树与右子树得互不相交得二叉树组成得。 由于左、右子树也就是二叉树,则由二叉树得定义,它们也可以为空。 由此,二叉树可以有五种基本形态 7、二叉树得重要性质 性质1二叉树第i(i≥1)层上至多有2i-1个结点。 性质2深度为k(k≥1)得二叉树至多有2k-1个结点。 性质3在任意二叉树中,若叶子结点(即度为零得结点)个数为n0,度为1得结点个数n1,度为2得结点个数为n2,那么n0=n2+1。 性质4具有n个(n>0)结点得完全二叉树得高度为⎡log2n+1⎤或⎣log2n⎦+1。 性质5若对有n(1≤i≤n)个结点得完全二叉树进行顺序编号,那么,对于编号为i(i≥1)得结点: 当i=1时,该结点为根,它无双亲结点; 当i>1时,该结点得双亲结点编号为⎣i/2⎦; 若2i≤n,则有编号为2i得左孩子,否则没有左孩子; 若2i+1≤n,则有编号为2i+1得右孩子,否则没有右孩子。 满二叉树: 深度为k且含有2k-1个结点得二叉树为满二叉树,这种树得特点就是每层上得结点数都就是最大结点数 在一棵二叉树中,如果所有分支结点都存在左子树与右子树,并且所有叶子结点都在同一层上,这样得一棵二叉树称作满二叉树。 如图所示,(a)图就就是一棵满二叉树,(b)图则不就是满二叉树,因为,虽然其所有结点要么就是含有左右子树得分支结点,要么就是叶子结点,但由于其叶子未在同一层上,故不就是满二叉树 完全二叉树: 深度为k,含有n个结点得二叉树,当且仅当每个结点得编号与相应满二叉树结点顺序号从1到n相对应时,则称此二叉树为完全二叉树 显然,一棵满二叉树必定就是一棵完全二叉树,而完全二叉树未必就是满二叉树。 如图所示(a)为一棵完全二叉树,(b)不就是完全二叉树。 8、二叉树得顺序存储结构 二叉树得顺序存储结构中结点得存放次序就是: 对该树中每个结点进行编号,其编号从小到大得顺序就就是结点存放在连续存储单元得先后次序。 若把二叉树存储到一维数组中,则该 编号就就是下标值加1(注意,C/C++语言中数组得起始下标为0)。 树中各结点得编号与等高度得完全二叉树中对应位置上结点得编号相同 9、二叉树得链式存储结构 data表示值域,用于存储对应得数据元素,lchild与rchild分别表示左指针域与右指针域,用于分别存储左孩子结点与右孩子结点(即左、右子树得根结点)得存储位置 下图(a)给出一棵二叉树得二叉链表存储表示。 二叉链表也可以带头结点得方式存放,如图(b)所示。 二叉链表存储表示可描述为: typedefstructbitnode { datatypedata; structbitnode*lchild;*rchild;/*左右孩子指针域*/ }BiTNode,*BiTree; 定义指针变量,用来存放根结点地址,通常用该指针标识一个二叉树: BiTreet; 10、二叉树遍历得概念 二叉树得遍历就是指按照一定次序访问树中所有结点,并且每个结点仅被访问一次得过程。 它就是最基本得运算,就是二叉树中所有其她运算得基础。 1、先序遍历(DLR) 先序遍历二叉树得过程就是: (1)访问根结点; (2)先序遍历左子树; (3)先序遍历右子树。 voidPreOrder(BiTreebt) { if(bt==NULL)return;/*递归调用得结束条件*/ Visit(bt);/*访问根结点*/ PreOrder(bt->lchild);/*先序递归遍历bt得左子树*/ PreOrder(bt->rchild);/*先序递归遍历bt得右子树*/ } 2、中序遍历(LDR) 中序遍历二叉树得过程就是: (1)中序遍历左子树; (2)访问根结点; (3)中序遍历右子树。 voidInOrder(BiTreebt) { if(bt==NULL)return;/*递归调用得结束条件*/ InOrder(bt->lchild);/*中序递归遍历bt得左子树*/ Visit(bt);/*访问根结点*/ InOrder(bt->rchild);/*中序递归遍历bt得右子树*/ } 3、后序遍历(LRD) 后序遍历二叉树得过程就是: (1)后序遍历左子树; (2)后序遍历右子树; (3)访问根结点。 voidPostOrder(BiTreebt) { if(bt==NULL)return;/*递归调用得结束条件*/ PostOrder(bt->lchild);/*后序递归遍历bt得左子树*/ PostOrder(bt->rchild);/*后序递归遍历bt得右子树*/ Visite(bt);/*访问根结点*/ } 4、层次遍历 其过程就是: 若二叉树非空(假设其高度为h),则: (1)访问根结点(第1层); (2)从左到右访问第2层得所有结点; (3)从左到右访问第3层得所有结点、…、第h层得所有结点。 11、二叉树基本运算概述 (1)创建二叉树CreateBTNode(*b,*str): 根据二叉树括号表示法得字符串*str生成对应得链式存储结构。 **Initiate(bt): 建立一棵空得二叉树bt,并返回bt。 二叉树带不带头结点,可根据具体需要而定。 建立一棵空得带头结点得二叉树 BiTreeInitiate()/*建立一棵空得带头结点得二叉树*/ { BiTNode*bt; bt=(BiTNode*)malloc(sizeof(BiTNode)); bt->lchild=NULL bt->rchild=NULL; returnbt; } 建立一棵空得不带头结点得二叉树 BiTreeInitiate()/*初始建立一棵空得不带头结点得二叉树*/ { BiTNode*bt; bt=NULL; returnbt; } 在主函数中,可以通过如下方式调用Initiate函数: main() { BiTreet;/*定义根结点指针变量*/ t=Initiate(); voidDispBiTNode(BiTreeT) { if(T! =NULL) { printf("%c",T->data); if(T->lchild! =NULL||T->rchild! =NULL) { printf("("); DispBiTNode(T->lchild); printf(","); Dis
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 基础知识 要点