在了解C语言数据结构算法之前,我们先来讨论一个基本的概念ADT--抽象数据类型
@-----------------------------------------------------------@
一.抽象数据类型
抽象数据类型(Abstract data type,ADT)是一种操作的集合。对于类似于表,集合和图的操作我们可以看作是一个抽象数据类型,对于ADT,我们有诸如交,并,测大小以及取余等操作。在实现程序时候,我们通过这些基本操作的实现旨在程序中编写一次,而程序中任何部分需要使用时通过简单的函数调用来实现相应的功能。因此,我们即将讨论三大数据结构ADT,首先,我们先讨论最简单的数据结构--表。
@-----------------------------------------------------------@
二.表ADT
将处理的一般形如A1,A2,A3,A4,A5,.........,An的表。我们说,这个表的大小是N。我们将大小为0的表称之为空表。
对于除了空表外的任何表,我们说Ai+1称之为第Ai的后继元,Ai称之为第Ai+1的前驱元【Ai+1后继Ai,Ai前趋Ai+1】(i > 1),观察上面的形式我们不难发现,A1是表中的第一个元素,An是表中的最后一个元素。
当我们从表1--n中任意取一个元素Ai,其位置位于表中的第i个位置。
@-----------------------------------------------------------@
三.线性表
根据上面所讲的表ADT的基础概念后我们来看两种表的类型--线性表和链表,首先,我们先看线性表。
线性表:
1.线性结构是一个数组元素的有序集(次序);
2.线性结构的基本特征:
(1)集合中存在唯一的“第一元素”;
(2)集合中存在唯一的“最后元素”;
(3)集合中必定存在唯一的,除最后元素之外,均有唯一的后继;
(4) 集合中必定存在唯一的,除第一个元素之外,均有唯一的前继。
线性表要求-->存储元素要在一个连续分配的空间中存储。
3.线性表的类型定义
抽象数据类型线性表的定义如下:
ADTList{数据对象,数据关系}
(1)数据对象:D = {ai | ai 属于 ElemSet,i = 1,2,3,4....n,n>= 0}
称n为线性表的表长,称n=0时候的线性表为空表
(2)数据关系:R1 = { <ai-1,ai> | ai-1,ai 属于 D,i = 2,.....,n}
称i为a在线性表中的位序
4.线性表的操作
引入线性表的目的就是解决一些算法问题,因此,对于线性表,我们提出了一下几个操作类型,并会详细讲解每一个操作类型的细节以及相关的配图讲解。
「结构的初始化」 InitList(&L)
-->操作结果:初始化一个线性表,构造了一个空表L
「销毁结构」 DestroyList (&L)
-->操作结果:线性表L存在时,销毁线性表L
「引用型操作」-- 不会改变原来线性表
ListEmpty(L)
-->判断线性表是否为空表,当然前提是表必须存在,如果为空表,则返回为真,如果不为空表则返回为假
ListLength (L)
-->在线性表存在的前提下,返回表的长度,即元素的个数
PirorElem (L,cur_e,&pre_e)
-->在线性表存在的前提下,返回线性表的前驱项,需要判断cur_e是否是线性表中的元素,如果是,则判断是不是第一个元素,如果不是第一个元素则用pre_e返回cur_e的前驱项,否则,失败,pre_e无定义。
NextElem (L,cur_e,&next_e)
-->在线性表存在的前提下,如果cur_e元素在线性表中,并且不是最后一个元素时候,我们返回next_e对于cur_e的后继项,否则,返回失败,next_e无定义。
GetElem (L,i,&e)
-->在线性表存在的前提下,通过比较i和线性表长度的比较进行判断,如果在表长度内,则返回i对应的元素,否则,返回失败。
LocateElem (L,e,compare())
-->在线性表存在的条件下,通过判断e在线性表中有定义,则通过判断条件compare()来对比和e相等的值,并返回下标i的大小,如果不存在,则返回失败。
ListTraverse(L,visit())
-->在线性表存在的前提下,进行遍历visit()线性表,如果visit()失败,则返回操作失败。
「加工型操作」-- 会改变原来的线性表
clearList(&L)
-->在线性表存在的条件下,将L线性表重置为一个空表
putElem(L,i,&e)
-->在线性表存在的条件下,1 < i <LengthList(L),L中第i个值赋予e这个值。
ListInsert(&L,i,e)
-->在线性表存在的前提下,1 < i < LengthList(L) + 1,在L线性表中第i个位置前插入一个新的元素e,同时L线性表的长度增加1。
ListDelete(&L,i,&e)
-->在线性表存在的前提下,1 < i < LengthList(L),删除L线性表的第i个元素,并用e返回其值,L线性表的长度减少1。
@-----------------------------------------------------------@
在列出以上的方法后,具体实现可能不太清楚,别担心,在下一个文章中会进行详细的讲解,我们先来看个例题来热热身。
@-----------------------------------------------------------@
例题1:有两个集合,A和B分别用两个线性表La和Lb表示(线性表中的数据元素表示即为集合中的成员),现在要求一个新的集合A = A ∪ B
将上述问题转换成对线性表进行操作:
扩大线性表La,将存在于线性表Lb中而不存在于线性表La中的数据元素插入到线性表La中去
1.从线性表Lb中一次取得每个数据元素,GetElem(Lb,i) --> e
2.依靠值在线性表La中进行查访,LocateElem(La,e,equal())
3.若在线性表La中不存在,则插入 ListInsert(&La,n+1,e)
void union(List &La,List Lb){
La_len = ListLength(La);
Lb_len = ListLength(Lb); //求线性表的长度
for(int i = 0; i <= Lb_len; ++i){
GetElem(Lb,i,&e); //取出Lb中第一个元素赋给e
if(!LocationElem(La,e,equal())){
ListInsert(La,++La_len,e);
//在La中不存在和e相同的数据元素,则插入
}
}
}//union
@-----------------------------------------------------------@
其余具体每个方法的实现方法,将会在下一篇文章详细讲解。希望能提供有力的帮助,对于知识点有错误的地方可直接评论区纠正!!!