1、信息学奥赛自学材料第一章 什么是数据结构1.1 基本概念和术语1.2 数据的逻辑结构和物理结构1.1 基本概念和术语1.数据(data): 是对客观事物的符号的表示,是所有能输入到计算机中并被计算机程序处理的符号的总称。2.数据元素(data element):是数据的基本单位,在计算机程序中通常作为一个整体来处理。一个数据元素由多个 数据项(data item)组成,数据 项是数据不可分割的最小单位。 3.数据结构(data structure): 是相互之间存在一种或多种特定关系的数据元素的集合。数据结构是一个二元组,记为: data_structure=(D,S).其中D为数据元素的集合
2、,S是D上关系的集合。 数据元素相互之间的关系称为结构(structure)。根据数据元素之间关系的不同特性,通常由下列四类基本结构: (1)集合:数据元素间的关系是同属一个集合。(图1) (2)线性结构:数据元素间存在一对一的关系。(图2) (3)树形结构:结构中的元素间的关系是一对多的关系。(图3) (4)图(网)状结构:结构中的元素间的关系是多对多的关系。(图4) 图1 图2 图3 图4 1.2 数据的逻辑结构和物理结构逻辑结构:数据元素之间存在的关系(逻辑关系)叫数据的逻辑结构。 物理结构:数据结构在计算机中的表示(映象)叫数据的物理结构。 一种逻辑结构可映象成不同的存储结构:顺序存储
3、结构和非顺序存储结构(链式存储结构和散列结构)。 第二章 线性表2.1 线性表的逻辑结构及基本运算2.2 线性表的顺序存储结构2.3 线性表的链式存储结构2.1 线性表的逻辑结构及基本运算1.线性表简单的定义n个数据元素的的有限序列其特点是除了表头和表尾外,表中的每一个元素有且仅有唯一的前驱和唯一的后继,表头有且只有一个后继,表尾有且只有一个前驱。2.线性表的基本运算length(L)返回表L的长度,即元素个数。IsEmpty(L)如果表L为空表(长度为0)则返回true,否则返回false。next(L,p)这是一个函数,函数值为表L中位置p的后继位置。如果p是L中结束元素的位置,则L.Ne
4、xt(p)=L.end。当L中没有位置p或p=L.end时,该运算无定义。prev(L,p)这是一个函数,函数值为表L中位置p的前驱位置。当L中没有位置p或p是L中开始元素的位置时,该运算无定义。get(L,p)这是一个函数,函数值为L中位置p处的元素。当p=L.end或L中没有位置p时,该运算无定义。insert(L,x,p)在表L的位置p处插入元素x,并将原来占据位置p的元素及其后面的元素都向后推移一个位置。例如,设L为a1,a2,an,那么在执行insert(L,x,p)后,表L变为a1,a2,ap-1,x,ap,an 。若p为L.end,那么表L变为a1,a2,an,x 。若表L中没有
5、位置p,则该运算无定义。delete(L,p)从表L中删除位置p处的元素。例如,当L为a1,a2,an时,执行delete(L,p)后,L变为a1,a2,ap-1,ap+1,an 。当L中没有位置p或p=L.end时,该运算无定义。locate(L,x)这是一个函数,函数值为元素x在L中的位置。若x在L中重复出现多次,则函数值为x第一次出现的位置。当x不在L中时,函数值为0MakeEmpty(L)这是一个将L变为空表的方法。例1 假设两个线性表LA,LB分别代表两个集合A和B:求A=A U Bproc union(var la:linear_list;lb:linear_list);begin
6、n:=length(la);for i:=1 to length(lb) do x:=get(lb,i);k:=locate(la,x);if k=0 then begin insert(la,n+1,x);n:=n+1 end;end例2 已知线性表la,lb中的数据元素按值非递减有序排列,现要求将la,lb归并为一个新的线性表lc且lc按值非递减。proc merge(la,lb:linear_list;var lc:linear_list);begini:=1;j:=1;k:=0;while (i=length(la) and (j=length(lb) do if get(la,i)=
7、get(lb,j) then begin insert(lc,k+1,get(la,i);k:=k+1;i:=i+1 end else begin insert(lc,k+1,get(lb,j);k:=k+1;j:=j+1 endwhile i=length(la) do begin insert(lc,k+1,get(la,i);k:=k+1;i:=i+1; endwhile j1时,表示第i个位置的位置变量pi的值是数组alist中存储表L的第i-1个元素next值,用p:=alist(p).next后移。照此,我们虽然是用数组来存储表中的元素,但在作表的插人和删除运算时,不需要移动元素,
8、只要修改游标,从而保持了用指针实现表的优点。因此,有时也将这种用游标实现的表称为静态链表。 3.循环链表我们在用指针实现表时,表中最后一个元素所在单元的指针域(next)为空指针nil。如果将这个空指针改为指向表头单元的指针就使整个链表形成一个环。这种首尾相接的链表称为循环链表。在循环链表中,从任意一个单元出发可以找到表中其他单元。图6所示的是一个单链的循环链表或简称为单循环链表。图6单循环链表在单循环链表上实现表的各种运算的算法与单链表的情形是类似的。它们仅在循环终止条件上有所不同:前者是p或p.next指向表头单元;后者是p或p.next指向空(nil)。在单链表中我们用指向表头单元的指针
9、表示一个表L,这样就可以在O(1)时间内找到表L中的第一个元素。然而要找到表L中最后一个元素就要花O(n)时间遍历整个链表。在单循环链表中,我们也可以用指向表头单元的指针表示一个表L。但是,如果我们用指向表尾的指针表示一个表L时,我们就可以在O(1)时间内找到表上中最后一个元素。同时通过表尾单元中指向表头单元的指针,我们也可以在O(1)时间内找到表L中的第一个元素。在许多情况下,用这种表示方法可以简化一些关于表的运算。4.双链表单循环链表中,虽然从任一单元出发,可以找到其前驱单元,但需要O(n)时间。如果我们希望能快速确定表中任一元素的前驱和后继元素所在的单元,可以在链表的每个单元中设置两个指
10、针,一个指向后继,另一个指向前驱,形成图8所示的双向链表或简称为双链表。图8 双链表由于在双链表中可以直接确定一个单元的前驱单元和后继单元,我们可以用一种更自然的方式表示元素的位置,即用指向双链表中第i个单元而不是指向其前一个单元的指针来表示表的第i个位置。双链表的单元类型定义如下。 type dupointer=celltype celltype=record data:datatype; next,previous:dupointer; end; dulist=dupointer;和单链的循环表类似,双链表也可以有相应的循环表。我们用一个表头单元将双链表首尾相接,即将表头单元中的previ
11、ous指针指向表尾,并将表尾单元的next指针指向表头单元,构成如图9所示的双向循环链表。图9 双向循环链表下面仅以双向循环链表为例给出三种基本运算的实现。(1)在双向循环链表L的位置p处插入一个新元素x的过程Insert可实现如下。 procedure Insert(x:datatdata;p:pointer;var L:duList);Var q:integerbegin new(q); q.data:=x; q.previous:=p.previous; q.next:=p; p.previous.next:=q; p.previous:=q;end; 上述算法对链表指针的修改情况见图1
12、0。图10 在双向循环链表中插入一个元素算法Insert中没有检查位置p的合法性,因此在调用Insert之前应保证位置p的合法性。由于插入通常是在表的头尾两端进行的,所以容易检查位置p的合法性。(2)从双向循环链表L中删除位置p处的元素可实现如下: procedure Delete(p:integer;var L:duList);begin if (pnil)and(pL) then begin p.previous.next:=p.next; p.next.previous:=p.previous; dispose(p); end;end; 上述算法对链表指针的修改情况见图11。图11 从双
13、向循环链表中删除一个元素5.链表的应用 例1:求 (A-B)U(B-A)其中A,B代表两个集合(用静态链表)program jtlb;const maxsize=20;type jid=record data:integer; next:integer; end;jtlist=array0.maxsize of jid;var a:jtlist;last,i,k,pre,x,m,n:integer;beginfor i:=0 to maxsize-1 do ai.next:=i+1;amaxsize.next:=-1;readln(m,n);for i:=1 to m do begin rea
14、d(x);ai.data:=x; end;readln;last:=m;for i:=1 to n do begin read(x); k:=1;pre:=0; while (ak.datax) and (kalast.next) do begin pre:=k;k:=ak.next; end; if k=alast.next then begin ak.data:=x;last:=k end else begin apre.next:=ak.next;if k=last then last:=pre end end;writeln;i:=0;repeat i:=ai.next; write(
15、ai.data, );until i=last;end.例2 求p1(x)+p2(x) (两个多项式的和)program dxshi;type link=node;node=record coef:real; exp:integer; next:linkend;poly=link;var p, pa,pb:poly;procedure jl(var a:poly);var p,q:poly; co:real;ex:integer;beginp:=nil;repeat read(co,ex); new(q);q.coef:=co;q.exp:=ex;q.next:=p;p:=q;until (e
16、x=-1) and (co=-1);a:=p;readln;end;procedure add_poly(var a:poly;b:poly);var p,q,u,pre:poly; x:real;beginp:=a.next;q:=b.next;pre:=a;while (pnil) and (qnil) do if p.expq.exp then begin pre:=p;p:=p.next end else if p.exp=q.exp then begin x:=p.coef+q.coef; if x0 then begin p.coef:=x;pre:=p;end else begi
17、n pre.next:=p.next; dispose(p) end; p:=pre.next;u:=q;q:=q.next;dispose(u); end else begin u:=q.next;q.next:=p;pre.next:=q;pre:=q;q:=u end;if qnil then pre.next:=q;dispose(b);end;begin jl(pa);jl(pb); add_poly(pa,pb); p:=pa;p:=p.next; while pnil do begin writeln(p.coef:8:2,p.exp:5); p:=p.next; endend.
18、练习题:1.约瑟夫问题:有M个猴子围成一圈,每个有一个编号,编号从1到M。打算从中选出一个大王。经过协商,决定选大王的规则如下:从第一个开始,每隔N个,数到的猴子出圈,最后剩下来的就是大王。要求:从键盘输入M,N,编程计算哪一个编号的猴子成为大王。(程序)2.求多项式的减与乘法.(程序)3.第三章 栈3.1 栈的概念(逻辑结构)及运算3.2 栈的存储与实现3.3 栈的应用3.1 栈的概念及运算 栈的定义:栈是一种特殊的表这种表只在表头进行插入和删除操作。因此,表头对于栈来说具有特殊的意义,称为栈顶。相应地,表尾称为栈底。不含任何元素的栈称为空栈。 栈的逻辑结构:假设一个栈S中的元素为an,an
19、-1,.,a1,则称a1为栈底元素,an为栈顶元 素。栈中的元素按a1 ,a2,.,an-1,an的次序进栈。在任何时候,出栈的元素都是栈顶元素。换句话说,栈的修改是按后进先出的原则进行的,如图1所示。因此,栈又称为后进先出(Last In First Out)表,简称为LIFO表。所以,只要问题满足LIFO原则,就可以使用栈。 图1栈的运算:为一种抽象数据类型,常用的栈运算有:运算含义inistack(S)使S成为一个空栈。getTop(S)这是一个函数,函数值为S中的栈顶元素。Pop(S)从栈S中删除栈顶元素,简称为抛栈。Push(S,x)在S的栈顶插入元素x,简称为将元素x入栈。Empt
20、y(S)这是一个函数。当S为空栈时,函数值为true,否则函数值为false。3.2 栈的存储与实现栈的数组实现:由于栈是一个特殊的表,我们可以用数组来实现栈。考虑到栈运算的特殊性,我们用一个数组elements1.maxlength来表示一个栈时,将栈底固定在数组的底部,即elements1为最早入栈的元素,并让栈向数组上方(下标增大的方向)扩展。同时,我们用一个游标top来指示当前栈顶元素所在的单元。当top=0时,表示这个栈为一个空栈。在一般情况下,elements中的元素序列elementstop,elementstop-1,.,elements1就构成了一个栈。这种结构如图2所示。 图 2利用上述结构,我们可以形式地定义栈类型TStack如下:TypeTStack=Record top:integer; element:array1.maxlength of TElement; End;在这种表示法下,栈的5种基本运算可实现如下。procedure inistack(Var S:TStack);beginS.top:=0;end;function Empty(var S:Stack):Boolean;
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1