学习 严蔚敏讲数据结构笔记08

150 篇文章 0 订阅
28 篇文章 0 订阅

例六、实现递归

当在一个函数的运行期间调用另一个函数时,在运行该被调用函数之前,需先完成三件事:

将所有的实在参数、返回地址等信息传递给被调用函数保存;

为被调用函数的局部变量分配存储区;

将控制转移到被调用函数的入口。

从被调用函数返回调用函数之前,应该完成:

保存被调用函数的计算结果;

释放被调用函数的数据区;

依照被调用函数保存的返回地址将控制转移到调用函数。

多个函数嵌套调用的规则是:

后调用先返回此时的内存管理实行“栈式管理”

递归过程指向过程中占用的数据区,称之为递归工作栈

每一层的递归参数合成一个记录,称之为递归工作记录

栈顶记录指示当前层的执行情况,称之为当前活动记录

栈顶指针,称之为当前环境指针

08_002

void hanoi(int n, char x, char y, char z)

{

         //将塔座x上按直径由小到大且至上而下编号为1n

         //n个圆盘按规则搬到塔座z上,y可以用作辅助塔座。

         {

                   if(n  == 1)

                   {

                            move(x,  1, z); //将编号为1的圆盘从x移到z

                   }

                   else

                   {

                            hanoi(n-1,  x, z, y); //x上编号为1n-1的圆盘移动到yz作辅助塔

                            move(x,  n, z); //将编号为n的圆盘从x移到z

                            hanoi(n-1,  y, x, z); //y上编号为1n-1的圆盘移动到zx作辅助塔

                   }

         }

}

 

09

 

 

3.3栈类型的实现

顺序栈

链栈

顺序栈

类似于线性表的顺序映象实现,指向表尾的指针可以作为栈顶指针。

 

09_001

//----栈的顺序存储表示----

#define STACK_INIT_SIZE 100;

#define STACKINCREMENT 10;

typedef struct

{

         SElemType  *base;

         SElemType  *top;

         int  stacksize;

}SqStack;

初始化:top=base

3.4队列的类型定义

ADT Queue

{

         数据对象:D={ai|aiElemSet,i=1,2,…,n,n0}

         数据关系:R1={<ai-1,ai>|ai-1,aiD,i=2,…,n} 约定其中a1端为队列头,an端为队列尾。

         基本操作:

}ADT Queue

基本操作

InitQueue(&Q)

DestoryQueue(&Q)

QueueEmpty(Q)

QueueLength(Q)

GetHead(Q,&e)

ClearQueue(&Q)

EnQueue(&Q,e)

DeQueue(&Q,&e)

 

 

GetHead(Q,&e)

初始条件:Q为非空队列。

操作结果:用e返回Q的对头元素。

DeQueue(&Q,&e)

初始条件:Q为非空队列。

操作结果:删除Q的对头元素,并用e返回其值。

EnQueue(&Q,e)

初始条件:Q为非空队列。

操作结果:插入元素eQ的新的队尾元素。

 

1.5  队列类型的实现

链队列  链式映象

 

09_002

typedef struct QNode

{

         QElemType  data;

         struct  QNode * next;

}QNode, *QueuePtr;

 

typedef struct

{

         QueuePtr  front; //对头指针

         QueuePtr  rear; //队尾指针

}LinkQueue;

循环队列顺序映象

 

09_003

#define MAXQSIZE 100 //最大队列长度

typedef struct

{

         QElemType  *base; //动态分配存储空间

         int  front; //头指针,若队列不空,指向队列头元素

         int  rear; //尾指针,若队列不空,指向队尾元素的下一个位置

}SqQueue;

 

1.      掌握栈和队列类型的特点,并能在相应的应用问题中正确选用它们。

2.      熟练掌握栈类型的两种实现方法,特别应注意栈满和栈空的条件以及它们的描述方法。

3.      熟练掌握循环队列和链队列的基本操作实现算法,特别注意队满和队空的描述方法。

4.      理解递归算法执行过程中栈的状态变化过程。

 

空队列:Q.front = Q.rear

满队列:(Q.rear+1)% MAXQSIZE =Q.front

 

第四章

4.1串的抽象数据类型的定义

4.2 串的表示和实现

4.3 串的模式匹配算法

 

4.1串的抽象数据类型的定义

ADT String{

数据对象:D={ai|aiCharacterSet,i=1,2,…n,n0}

数据关系:R1={<ai-1,ai>|ai-1,aiD,i=2,…,n}

}

基本操作:

StrAssign(&T,chars)

StrCompare(S,T)

StrCopy(&T,S)

StrLength(S)

DestoryString(&S)

Concat(&T,S1,S2)

StrEmpty(S)

 

StrAssign(&T, chars)

初始条件:chars是字符串常量

操作结果:把chars赋为T的值。

StrCopy(&T,S)

初始条件:串S存在。

操作结果:由串S复制得到串T

StrLength(S)

初始条件:串S存在。

操作结果:返回S的元素个数,称为串的长度。

StrEmpty(S)

初始条件:串S存在。

操作结果:若S为空串,则返回TRUE,否则返回FALSE

StrCompare(S,T)

初始条件:串ST存在。

操作结果:若S>T,则返回值>0;S=T,则返回值=0;若S<T,则返回值<0

Concat(&T,S1,S2)

初始条件:串S1S2存在。

操作结果:用T返回由S1S2连接而成的新串。

SubString(&Sub,S,pos,len)

Index(S,T,pos)

ClearString(&s)

Replace(&S,T,V)

StrDelete(&S,pos,len)

StrInsert(&S,pos,T)

 

SubString(&Sub,S,pos,len)

初始条件:串S存在,1<=pos<=StrLength(S)-pos+1

操作结果:用Sub返回串S的第pos个字符起长度为len的子串。

子串:主串(字符序列)中的一个子序列。

Index(S,T,pos)

初始条件:串ST存在,T是非空串,1<=pos<=StrLength(S)

操作结果:若主串S中存在和串T值相同的子串,则返回它在主串S中第pos个字符之后第一次出现的位置;否则函数值为0

SubString(&Sub,S,pos,len)

初始条件:串S存在,1<=pos<=StrLength(S)0<=len<=StrLength(S)-pos+1

操作结果:用Sub返回串S的第pos个字符起长度为len的子串。

Replace(&S,T,V)

初始条件:串S,TV存在,T是非空串。

操作结果:用V替换主串S中出现的所有与T相等的不重叠的子串。

StrInsert(&S,pos,T)

初始条件:串ST存在,1<=pos<=Strlength(S)+1

操作结果:串Spos个字符之前插入串T

StrDelete(&S,pos,len)

初始条件:串S存在,1<=pos<=StrLength(S)-len+1

操作结果:从串S中删除的第pos个字符起长度为len的子串。

串的逻辑结构和线性表极为相似,区别是仅在于串的数据对象约束为字符集,然而,串的基本操作和线性表有很大差别。在线性表的基本操作中,大多以“单个元素”作为操作对象,如:在线性表中查找某个元素,求取某个元素、在某个位置上插入一个元素和删除一个元素等;而在串的基本操作中,通常以“串的整体”作为操作对象,如:在串中查找某个子串、求取第一个子串、在串的某个位置上插入一个子串以及删除一个子串等。

对于串的基本操作集可以说有不同的定义方法,读者在使用高级程序设计语言中的串类型时,应以该语言的参考手册为准,在上述抽象数据类型定义的13中操作中,串赋值StrAssign、串赋值Strcopy、串比较StrCompare、求串长StrLength、串联接Concat以及求子串SubString等六种基本操作构成串类型的最小操作子集。即:这些操作不能利用其它串来实现,反之,其他串操作(除串清除ClearString和串销毁DestoryString外)可在这个最小操作子集上完成。

例如,可利用串比较、求串长和求子串等操作实现定位函数Index(S,T,pos)

算法的基本思想为:在主串S中取从第ii的初值为pos)个字符起、长度和串T相等的子串和串T比较,若相等,则求得函数值为i,否则值i1直至S中不存在和串T相等的子串为止。等价于StrCompare(SubString(S,i,StrLength(T)),T) 0

 

10_001

int Index(String S, String T, int pos)

{

         //T为非空串。若主串S中第pos个字符值之前存在与T相等的子串。则返回第一个

         //这样的子串在S中的位置,否则返回0

         if(pos  > 0)

         {

                   n  = StrLength(S);

                   m  = StrLength(T);

                   i  = pos;

                   while(i  <= n-m+1)

                   {

                            SubString(sub,  S, i, m);

                            if(StrCompare(sub,  T) != 0)

                                     ++  i;

                            else

                                     return  i;

                   }//while

         }//if

         return  0; //S中不存在与T相等的子串

}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值