数据结构个人整理.docx
- 文档编号:5335326
- 上传时间:2022-12-15
- 格式:DOCX
- 页数:64
- 大小:576.89KB
数据结构个人整理.docx
《数据结构个人整理.docx》由会员分享,可在线阅读,更多相关《数据结构个人整理.docx(64页珍藏版)》请在冰豆网上搜索。
数据结构个人整理
基本概念和术语解释
什么是数据结构:
数据结构的内容可归纳为三个部分:
逻辑结构、存储结构和运算集合。
按某种逻辑关系组织起来的一批数据,按一定的映象方式把它存放在计算机的存储器中,并在这些数据上定义了一个运算的集合,这就是一个数据结构。
数据结构的相关概念和术语
数据(data)是信息的载体,是对客观事物的符号表示,它能够被计算机识别、存储和加工处理。
可以说,数据是计算机程序加工的“原料”。
目前,象图像、声音、视频等都可以通过编码而由计算机处理,因此它们也属于数据的范畴。
数据元素(dataelement)是数据的基本单位,通常在计算机程序中作为一个整体进行考虑和处理。
数据元素也称为元素、结点或记录。
有时,一个数据元素可以由若干个数据项(也称字段、域),数据项是数据不可分割的最小单位。
例如张三的就餐预定信息。
数据项(DataItem)是数据结构中讨论的最小单位,一般将其看作是不能再分解的数据。
一个数据元素可由若干个数据项组成。
数据对象(dataobject)是性质相同的数据元素的集合,它是数据的一个子集。
例如,张三、李四、王五就餐预定信息的集合作为订餐人员数据对象;大写字母字符数据对象是集合C={‘A’,‘B’,…,‘Z’}。
数据类型(datatype)是计算机程序中的数据对象以及定义在这个数据对象集合上的一组操作的总称。
例如,C语言中的整数类型是区间
[-maxint,maxint]上的整数,在这个集合上可以进行加、减、乘、整除、求余等操作。
逻辑结构
数据的逻辑结构是指数据元素之间逻辑关系的描述。
根据数据元素之间关系的不同特性
存储结构(又称物理结构)是逻辑结构在计算机中的存储映象,是逻辑结构在计算机中的实现(或存储表示),它包括数据元素的表示和关系的表示。
逻辑结构与存储结构的关系为:
存储结构是逻辑结构的映象与元素本身的映象。
逻辑结构是抽象,存储结构是实现,两者综合起来建立了数据元素之间的结构关系。
数据结构在计算机中的映象,包括数据元素映象和关系映象。
关系映象在计算机中可用顺序存储结构或非顺序存储结构两种不同方式来表示。
运算集合
讨论数据结构的目的是为了在计算机中实现所需的操作,施加于数据元素之上的一组操作构成了数据的运算集合,因此运算集合是数据结构很重要的组成部分。
以物流配送货单信息为例,该表的数据元素与数据元素之间是一种简单的线性关系,所以逻辑结构采用线性表。
存储结构既可采用顺序存储结构,也可采用非顺序存储结构。
当货物配送以后要删除相应的数据元素,有配送顾客时要增加数据元素,发现配送信息输入错误时要修改。
这里的增加、删除、修改就构成了数据的操作集合。
二、算法
算法的定义:
用比较通俗的语言说,算法是解题的步骤。
严格地讲,算法是一个有穷的规则集合,这些规则为解决某一特定任务规定了一个运算序列。
算法的描述方法:
自然语言
程序设计语言(或类程序设计语言)
流程图(包括传统流程图和N-S结构图)
算法的五大特性
有穷性:
一个算法必须在有穷步之后结束,即必须在有限时间内完成
确定性:
算法的每一步必须有确切的定义,无二义性。
可行性:
算法中的每一步都可以通过已经实现的基本运算的有限次执行得以实现。
输入:
一个算法具有零个或多个输入,这些输入取自特定的数据对象集合。
输出:
一个算法具有一个或多个输出,这些输出同输入之间存在某种特定的关系。
算法分析
在算法满足正确性的前提下,如何评价不同算法的优劣呢?
通常主要考虑算法的时间复杂度和空间复杂度这两方面。
一般情况下,鉴于运算空间(内存)较为充足,所以把算法的时间复杂度作为重点分析。
空间复杂度:
主要是看循环的嵌套次数,一级循环复杂度O(n),二级循环就是O(n^2),三级就是O(n^3).
线性表实例:
F的集合:
创建一个空的线性表(准备一张白纸)
插入一个新的元素(书写一个新货单的信息)
删除一个元素(划掉一个已配送的货单信息)
查找指定的元素(在划掉的信息之前,需要查找有关的信息是否存在)
清空线性表(将纸张销毁或存档)
线性表的定义
线性表是具有相同类型的n个数据元素组成的有限序列,通常记为(a1,a2,…ai-1,ai,ai+1,…an)
其中,ai是表中元素,n是表的长度,当n=0时线性表为空表。
当n≠0时,a1是第一个元素,也称为表头元素,an是最后一个元素,也称为表尾元素。
a1是a2的直接前驱元素,a2是a3的直接前驱元素,而a2是a1的直接后继元素,a3是a2的直接后继元素。
顺序表的定义
数据结构在内存中的表示通常有两种形式,即顺序存储表示和链式存储表示。
线性表的顺序存储是指用一组地址连续的存储单元依次存储线性表的数据元素,线性表的顺序存储表示又称为顺序表。
顺序表的描述:
typedefintElemType;
typedefstruct
{ElemTypeElement[MaxSize];/*存储线性表内容的数组*/
intLength;/*线性表的长度*/
}SeqList;/*说明List数据类型*/
SeqListList,*L_pointer;/*定义顺序表List*/
构造一个空表
voidInit_SeqList(SeqList*L_pointer)/*构造一个空表*/
{L_pointer->Length=0;
}
插入一个元素(尾插)
intInsert_Last(SeqList*L_pointer,ElemTypex)
{if(L_pointer->Length==MaxSize)
{printf("表满");
returnOverFlow;
}
else
{L_pointer->Element[L_pointer->Length]=x;
/*在表尾插入一个元素*/
L_pointer->Length++;/*线性表长度加1*/
returnOK;/*插入成功,返回*/
}
}
查找指定元素
intLocation_SeqList(SeqList*L_pointer,ElemTypex)
/*查找指定元素*/
{inti=0;
while(i
=x)
i++;
if(i==L_pointer->Length)return-1;/*查找失败*/
elsereturni+1;/*返回x的逻辑位置*/
}
删除一个元素(删除线性表的第i个元素)
intDelete_SeqList(SeqList*L_pointer,inti)
{intj;
if(i<1||i>L_pointer->Length)
/*判断参数的正确性*/
{printf("不存在第i个元素");
returnError;
}
for(j=i-1;j<=L_pointer->Length-1;j++)/*删除*/
L_pointer->Element[j]=L_pointer->Element[j+1];
/*向左移动*/
L_pointer->Length--;/*线性表长度减1*/
returnOK;
}
遍历线性表
voidShow_SeqList(SeqList*L_pointer)
{intj;
printf("\n");
if(L_pointer->Length==0)
printf("空表(NULL)!
\n");
else
for(j=0;j
printf("%d",L_pointer->Element[j]);
}
清空线性表
voidSetNull_SeqList(SeqList*L_pointer)
/*清空线性表*/
{L_pointer->Length=0;
}
第三章线性表的链式存储
数据域:
存放结点数据信息值,例如配送顾客数据信息。
指针域:
存放结点的直接后继的地址(位置)。
注意:
(1)、链表通过每个结点的链域将线性表的n个结点按其逻辑顺序链接在一起的。
(2)、每个结点只有一个链域的链表称为单链表(SingleLinkedList)。
单链表定义的一般形式:
由分别表示a1,a2,…,an,的n个结点依次相链构成的链表,称为线性表的链式存储表示,由于此类链表的每个结点中只包含一个指针域,故称为单链表或线性链表。
静态链表特点:
用数组来存储元素的值和地址。
程序运算过程中,数组元素的个数固定不变
链表的存储特点:
1、用一组任意的存储单元来存放线性表的结点(这组存储单元既可以是连续的,也可以是不连续的),例如三个配送顾客的配送数据信息的存储空间是可以定义在任意的存储区域。
2、链表中结点的逻辑次序和物理次序不一定相同。
为了能正确表示结点间的逻辑关系,在存储每个结点值的同时,还必须存储指示其后继结点的地址(或位置)信息,三个配送顾客的配送数据的逻辑次序与物理存储次序不相同。
存储结构C语言定义如下定义顾客信息数据类型:
typedefstruct
{charnumber[10];
charid[10];
charname[10];/*姓名*/
charaddr[20];/*地址*/
}ElemType;
定义结点类型:
typedefstructnode
{ElemTypedata;/*数据域*/
intnext;/*指针域*/
}SLNode;
定义静态单链表:
SLNodeletter[100];
动态链表结点定义一般形式:
typedefstructnode
{ElemTypedata;/*数据域*/
structnode*next;/*指针域*/
}LNode,*LinkList;
使用链表的原因:
第一,如果系统不能提供足够大的地址连续的内存空间时,可以考虑使用链表;
第二,需要对线性表频繁地进行插入和删除操作时,也考虑使用链表。
动态链表的实现:
定义元素数据类型
typedefstruct
{charnumber[7];/*序号*/
charid[10];/*配送编号*/
charname[10];/*姓名*/
charaddr[10];/*地址*/
}ElemType;
定义变量:
Structnodex,*Head;
/*结点变量x,结点指针变量Head*/
或
LNodex,*Head;
/*结点变量x,结点指针变量Head*/
或
LinkListHead;
/*结点指针变量Head*/
头结点及作用:
头结点是在链表的开始结点之前附加一个结点。
它具有两个优点:
(1)由于开始结点的位置被存放在头结点的指针域中,所以在链表的第一个位置上的操作就和在表的其它位置上操作一致,无须进行特殊处理;
(2)无论链表是否为空,其头指针都是指向头结点的非空指针(空表中头结点的指针域空),因此空表和非空表的处理也就统一了。
注意:
头结点数据域的阴影表示该部分不存储信息。
在有的应用中可用于存放表长等附加信息。
构造一个空表
intInit_LinkList(LinkListHead)/*构造一个空表*/
{LinkListp;
p=(LinkList)malloc(sizeof(LNode));/*分配一个结点*/
if(p==NULL)
returnOverFlow;/*分配失败*/
Head=p;/*头指针指向新结点*/
returnOK;/*构造成功,返回*/
子函数参数说明:
typedefstructnode
{
ElemTypedata;/*数据域*/
structnode*next;/*指针域*/
}LNode,*LinkList
查找指定元素x(查找姓名字段,类型为字符数组)。
LNode*Location_LLinkList(LinkListHead,char*name)
/*查找指定关键字信息*/
{
Node*p;
p=Head->next;
while(p!
=NULL)/*未到链尾*/
{/*关键字姓名相等*/
if(strcmp(p->data.name,name)==0)
returnp;/*找到返回指针*/
else
p=p->next;/*p取后继结点的地址*/
}
returnNULL;/*未找到,返回空指针*/
}
删除线性表中值为x的元素(删除姓名字段,类型为字符数组)。
intDelete_LLinkList(LinkListHead,char*name)
{Node*p,*q;
q=Head;/*q指向头结点*/
p=q->next;/*p取其后继结点的地址*/
while(p!
=NULL)/*p不为空*/
{if(strcmp(p->data.name,name)==0)/*找到被删除元素*/
{q->next=p->next;/*q所指结点的指针设置为p所指结点的指针*/
free(p);/*释放p所指结点*/
returnOK;/*删除成功*/
}
q=p;p=p->next;/*q取p的值,p取其后继结点的地址*/
}
returnError;/*删除失败*/
}
遍历带表头结点的单循环链表
voidShow_LLinkList(LinkListHead)/*遍历线性表*/
{
LNode*p;
printf("\n");
p=Head->next;/*p指向第一个结点(非头结点)*/
if(p==NULL)
printf("\n空表!
NULL");
while(p!
=NULL)/*未结束遍历*/
{printf("%s%s%s%s\n",p->data.number,
p->data.id,p->data.name,p->addr);/*输出数据*/
p=p->next;/*p取后继结点的地址*/
}
}
清空带表头结点的单循环链表。
voidSetNull_LLinkList(LinkListHead)/*清空线性表*/
{LNode*p,*q;
q=Head;
p=q->next;/*p取头指针*/
while(p!
=NULL)
{q=p;/*q指向p的前驱结点*/
p=p->next;/*p指向其后继结点*/
free(q);
}
Head->next=NULL;/*设置头结点/*/
}
计算带表头结点的单循环链表的长度。
intLength_LLinkList(LinkListHead)/*计算线性表的长度*/
{LNode*p;
intsum=0;
p=Head->next;/*p取头指针的后继*/
while(p!
=NULL)/*p与Head不相等*/
{sum++;/*累加器加1*/
p=p->next;/*p指向其后继结点*/
}
returnsum;
}
插入一个元素(在最后一个结点之后插入,带表头结点的单链表)
intInsertL_Last(LinkListHead,ElemTypex)/*在最后一个结点后面插入*/
{LNode*p,*q;intk=0;
p=(LinkList)malloc(sizeof(LNode));/*分配一个结点*/
if(p==NULL)
returnOverFlow;/*分配失败*/
/*数据域赋值*/
strcpy(p->data.number,x.number);/*输入序号*/
strcpy(p->data.id,x.id);/*输入配送编号*/
strcpy(p->data.name,x.name);/*输入姓名*/
strcpy(p->data.addr,x.addr);/*输入地址*/
p->next=NULL;
q=Head;
while(q->next!
=NULL)/*q指向最后一个元素*/
q=q->next;/*q取后继元素的指针*/
q->next=p;/*设置第i个结点的指针域指向新结点*/
returnOK;
}
插入一个元素(在头结点之后插入,带表头结点的单链表)
intInsertL_First(LinkListHead,ElemTypex)/*在头结点后面插入*/
{LNode*p;
p=(LinkList)malloc(sizeof(Node));/*分配一个结点*/
if(p==NULL)
returnOverFlow;/*分配失败*/
/*数据域赋值*/
strcpy(p->data.number,x.number);/*输入序号*/
strcpy(p->data.id,x.id);/*输入配送编号*/
strcpy(p->data.name,x.name);/*输入姓名*/
strcpy(p->data.addr,x.addr);/*输入地址*/
p->next=Head->next;
Head->next=p;
returnOK;
}
链式存储结构循环链表
特点:
是表中最后一个结点的指针不再是空,而是指向头结点(带头结点的单链表)或第一个结点(不带头结点的单链表),整个链表形成一个环,这样从表中任一结点出发都可找到其它的结点。
注意:
判断空链表的条件是head==head->next;
算法设计:
LinkListConnect(LinkListA,LinkListB)
{//假设A,B为非空循环链表的尾指针
LinkListp=A->next;//①保存A表的头结点位置
A->next=B->next->next;//②B表的开始结点链接到A表尾
free(B->next);//③释放B表的头结点
B->next=p;//④
returnB;//返回新循环链表的尾指针
}
栈的定义
栈(Stack)是限制仅在表的一端进行插入和删除运算的线性表。
(1)通常称插入、删除的这一端为栈顶(Top),另一端称为栈底(Bottom)。
(2)当表中没有元素时称为空栈。
(3)栈为后进先出(LastInFirstOut)的线性表,简称为LIFO表。
栈的基本运算
(1)InitStack(S):
构造一个空栈S。
(2)StackEmpty(S):
判栈空。
若S为空栈,则返回TRUE,否则返回FALSE。
(3)StackFull(S):
判栈满。
若S为满栈,则返回TRUE,否则返回FALSE。
注意:
该运算只适用于栈的顺序存储结构。
(4)Push(S,x):
进栈。
若栈S不满,则将元素x插入S的栈顶。
(5)Pop(S):
退栈。
若栈S非空,则将S的栈顶元素删去,并返回该元素。
(6)StackTop(S):
取栈顶元素。
若栈S非空,则返回栈顶元素,但不改变栈的状态。
(7)SetNull_SeqStack(S):
清空一个栈。
顺序栈的类型定义如下
#defineStackSize100
typedefstruct
{ElemTypeElement[MaxSize];
intTop;/*栈顶*/
}SeqStack;/*说明SeqStack*/
SeqStackListStack;/*定义顺序栈ListStack*/
顺序栈的类型定义只需将顺序表的类型定义中的长度属性改为top即可。
创建一个空栈
voidInit_SeqStack(SeqStack*S_pointer)
/*构造一个空栈*/
{S_pointer->Top=-1;
}
S_pointer指针指向由数组空间Element和Top两个
成员构成的结构体变量。
init_SeqStack(&ListStack);
ListStack是定义为SeqStack类型的变量。
判栈空
intEmpty_SeqStack(SeqStack*S_pointer)
/*判栈空*/
{if(S_pointer->Top==-1)returnTrue;
elsereturnFalse;
}
调用方式:
if(Empty_SeqStack(&ListStack)==True)
printf("空栈\n");
判栈满
intFull_SeqStack(SeqStack*S_pointer)
/*判栈满*/
{if(S_pointer->Top==MaxSize-1)
returnTrue;
/*返回栈满标记*/
elsereturnFalse;/*返回栈空标记*/
}
进栈
intPush_SeqStack(SeqStack*S_pointer,ElemTypex)
/*进栈*/
{if(Full_SeqStack(S_pointer)==True)/*判栈满*/
returnOverFlow;/*栈满则返回操作失败标记*/
else
{S_pointer->Top++;/*栈顶位置加1*/
S_pointer->Element[S_pointer->Top]=x;
/*元素x赋值到栈顶位置*/
returnOK;/*返回操作成功标记*/
}
}
退栈
intPop_SeqStack(SeqStack*S_pointer,ElemType
*x_pointer)/*退栈*/
{
if(Empty_SeqStack(S_pointer)==True)
/*判栈空*/
returnUnderFlow;/*栈空则操作失败*/
else
{*x_pointer=S_pointer->Element[S_pointer->Top];
/*取栈顶元素到x_pointer所指的空间*/
S_pointer->Top--;/*栈顶位置减1*/
returnOK;/*返回操作成功标记*/
}
}
取栈顶元素
intGetTop_SeqStack(SeqStack*S_pointer,ElemType*x_pointer)
/*取栈顶元素*/
{if(Empty_SeqStack(S_pointer)==True)
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 个人 整理