现在的计算机存储着处理字符、表格和图像等具有一定结构的数据,但是呢,要分清数据的内在联系,合理地组织数据,高效地处理数据,这就是“数据结构”主要研究的问题。
数据
是客观事物的符号表示,是所有能输入到计算机中并被计算机程序处理的符号的总称。
数据元素
是数据的基本单位,在计算机中通常作为一个主题进行考虑和处理。有些情况下,数据元素也称为元素、记录。
数据项
是组成数据元素的、有独立含义的、不可分割的最小单位。
数据对象
是性质相同的数据元素的集合,是数据的一个子集。
数据结构是相互之间存在一种或几种特定关系的数据元素的集合。这样子理解,数据结构是带“结构”的数据元素的集合,“结构”就是数据元素之间存在的关系。结构可分为逻辑结构和物理结构。
数据的逻辑结构有两个要素:一是数据元素,二是关系。数据元素的含义如前所述,关系是指数据元素之间的关系。
通常有四类基本结构:
数据对象再计算机中的存储表示称为数据的存储结构,也称为物理结构。
数据类型是高级程序设计语言中的基本概念,是一个值的集合和定义在这个值集上的一组操作的总称。
数据类型反映了程序设计语言的数据描述和处理能力。
抽象是抽取出实际问题的本质。
抽象数据类型一般指由用户定义的、表示应用为标题的数学模型,以及定义在这个模型上的一组操作的总称。具体包括三个部分:数据对象、数据对象上的关系的集合以及对数据对象的基本操作的集合。
ATD 抽象数据类型名{
数据对象:<数据对象的定义>
数据关系:<数据关系的定义>
基本操作:<基本操作的定义>
}ATD 抽象数据类型名
在涉及运算时,总要联系到该算法处理的对象和结果的数据。为了描述实习某些操作,常常需要设计算法,因而算法时研究数据结构的重要途经。
算法是为了解决某类问题而规定的一个有限长的操作序列。
五个特性:
算法效率分析的目的是看算法实际是否可行,并在同一问题存在多个算法中可进行时间和空间性能上的比较,以便从中挑选出较忧算法。
类似于算法的时间复杂度,采用渐近空间复杂度作为算法所需存储空间的度量,简称空间复杂度。记作:
S(n) = O(f(n))
一般情况下,一个程序在机器上执行时,除了需要寄存本身所用的指令、常数
变量和输入数据外,还需一些对数据进行操作的辅助存储空间。
线性结构的基本特点时除了第一个元素无直接前驱,最后一个元素无直接后继之外,其他元素都有一个前驱和一个后继。
由n(n>0)个数据特性相同的元素构成的有限序列称为线性表
特点有:
线性表的顺序表示指的是用一组地址连续的存储单元依次存储线性表的数据元素,这种也称作线性表的顺序存储结构或顺序映像。线性表的特点是,逻辑上相邻的数据元素,其物理次序也是相邻的
//顺序表的存储结构
#define MAXSIZE 100
typedef struct
{
ElemType *elem; //存储空间的基地址
int length; //当前长度
}SqList; //顺序表的结构类型为SqList
Status InitLIst(SqList & L)
{ //构造一个空的顺序表
L.elem = new ElemType[MAXSIZE]; //为顺序表分配一个大小为MAXSIZE的数组空间、
if(!elem) exit (OVERFLOW); //存储失败退出
L.length = 0; //空表长度为0
return ok;
}
Status GetElem(SqList L,int i,ElemType &e)
{
if (i<1 || i>L.length) return ERROR; //判断i值是否合理,
e = L.elem[i-1]; //elem[i-1]单元存储第i个数据元素
return ok;
}
int LocatElem(SqList L,ElemType e)
{
for(i=0;i<length;i++)
if(L.elem[i == e) rteurn i+1;
return o;
}
Status ListInser(SqList &L,int i,ElemType e)
{
if((i<1)||(i>L.length+1)) return ERROR; //i值不合法
if(L.length == MAXSIZE) return ERROR; //当前存储空间已满
for(j=L.length-1;j>=i-1;j--)
L.elem[j+1] =L.elem[j]; //插入位置及之后的元素后移
L.elem[i-1e; //将新元素e放入第i个元素
++L.length; //表长加1
return ok;
}
Status ListDelete(SqList &L,int i)
{
if((i<1)|| (i>L.length)) return ERROR;
for(j=i;j<=.length-1;j++)
L.elem[j-1] = L.elem[j];
--L.elemth;
return ok;
}
线性表链式存储结构的特点:用一组任意的存储单元存储线性表的数据元素。
Status IntList(LinkList &L)
{
L = new LNode;
L->next = NULL; //生成新结点作为头结点
return ok; //头结点的指针置空
}
Status GetElem(LinkList L,int i, ElemType &e)
{
p = L->next ; //初始化,p指向首元结点,
j=1; //计数器j初值赋为1
while(p&&j<i) //顺链域向后扫描,直到p为空或p指向第i个元素
{
p=p->next; //p指向下一个节点
++j; //计数器加1
}
if(!p||j>i) return ERROR; //i值不合法i>n或i<0
e = p->data; //去第i个节点的数据域
return ok;
}
LNode *LocateElem(LinkList L,ElemType e)
{
p = L->next; //初始化,p指向首元结点
while(p && p->data!=e) //顺着链域扫描,直到p为空或p所指的的数据域等于e
p=p->next; //p指向下一个结点
return p;
}
Status ListInsert(LinkList &L,int i ,ElemType e)
{
p=L;j=0;
while(p&& (j<i-1))
{
p = p ->next; //查找第i-1个结点,p指向该结点
++j;
}
if(!p || j>i-1) return ERROR; //i > n+1 或者 i<1
s = new LNode; //生成新结点*s
s ->data = e; // 将结点*s 的数据域置为e
s ->next = p->next; //将结点*s的数据域指向结点a(i)
p ->next =s; //将结点*p的指针域指向结点*s
return ok;
}
Status ListDelete (LinkList &L,int i)
{
p = L;j=0;
while((p ->next) && (j<i-1)) //查找第i-1个结点,p指向该结点
{
p =p ->next; ++j;
}
if(!
(p ->next) || (j>i-1)) rteurn ERROR;
q = p ->next;
delete q;
return ok;
}
循环链表市另一种形式的链式存储结构,其特点是表中最后一个结点的指针域指向头结点,整个链表形成一个环,语句:
p = B ->next ->next;
B ->next = A ->next;
A ->next =p;
在双向链表的结点中有两个指针域,一个指向直接后继,另一个指向直接前驱
比较项目 | 顺序表 | 链表 |
---|---|---|
存储空间 | 预先分配,会导致空间闲置或溢出现象 | 动态分配,不会导致空间闲置或溢出现象 |
存储密度 | 不用为表示结点间的逻辑关系而增加额外的存储开销,存储密度等于1 | 需要借助指针来体现元素间的逻辑关系,存储密度小于1 |
存储元素 | 随机存取,按位置访问元素的时间复杂度为O(1) | 顺序存储,按位置访问元素时间复杂度为O(n) |
插入、删除 | 平均移动约表中一半元素,时间复杂度为O(n) | 不需要移动元素,确定插入、删除位置后时间复杂度为O(1) |
适用情况 | 表变化不大,且 能事先确定变化的范围;很少进行插入或删除操作,经常按元素位置序号访问数据元素。 | 长度变化比较大,频繁进行插入或删除操作 |
栈是限定于仅在表尾进行插入和删除操作的线性表,表尾称栈顶,表头叫栈尾,栈的修改是按先进先出的原则进行的。
顺序栈是指利用顺序存储结构实现的栈,即利用一组地址连续的存储单元依次存放自栈底到栈顶的数据元素,同时附设指针top指示栈顶元素在顺序栈中的位置。
Statys IntStack(SqStack &s)
{
s.base = new SElemTyoe[MAXSIZE]; //动态分配数组
if(!S.base) exit(OVERFLOW); //存储动态失败
S.top = S.base; //top初始为base,空栈
S.stacksize = MAXSIZE; //栈的容量为,MAXSIZE
return ok;
}
Status Push(SqStack &S, SElemType e)
{
if(S.top-S.base == S.atacksize) ERROR;
*S.top++=;
return ok;
}
Status Pop(SqStack &S,SElemTyep &e)
{
if(S.top ==S.base) return ERROR;
e = *--S.top;
return ok;
}
SElemType GetTop(SqStack S)
{
if(S.top!= S.base)
return *(S.top-1);
}
采用链式存储结构实现的栈。
Status IntStack(LinkStack &s)
{
S= NULL;
return ok;
}
Stataus Push(LinkStack &S,SElemType e)
{
p = new StackNode; //生成新结点
p -> data =e; //将新结点数据域置为e
p ->next = S; //将新结点插入栈顶
S = p; //修改栈顶元素指针为p
return ok;
}
Stataus Push(LinkStack &S,SElemType e)
{
if(S == NULL) RETURN ERROR;
e = S ->data;
p = S ;
S =S ->next;
delete p;
return ok;
}
ps:现在先写到这,后面会继续完成编写工作,谢谢各位点进来学习交流。