《数据结构与算法 C语言版》—— 3.5典型例题

3.5典型例题

例1设有两个栈S1、S2采用顺序栈方式,并且共享一个数组A[Maxsize],为了尽量利用空间,减少溢出的可能,采用栈顶相向、迎面增长的存储方式。设计S1、S2的有关初始化、入栈和出栈的操作算法。
解两栈共享数组空间,将两栈栈底设在数组的两端,初始时,top[0]=-1,top[1]=Maxsize。两栈顶指针相邻时为栈满。两栈顶相向,迎面增长,两栈顶指针都指向栈顶元素。

#define Maxsize 100//栈空间容量
typedef struct {
ElemType data[Maxsize];
int Top[2];//指向栈顶元素
}Dstack;

初始化、入栈和出栈的操作算法如下。
(1)初始化操作

void InitStack(Dstack &S){
S.Top[0]=-1;S.Top[1]=Maxsize;
}

(2)进栈操作

int Push(Dstack &S,ElemType x,int i){
if(S.Top[0]+1==S.Top[1])return 0;//栈满
switch(i){
case 0:S.Top[0]++;S.data[S.Top[0]]=x;break;
case 1:S.Top[1]--;S.data[S.Top[1]]=x;break;
default:return 0;
}
return 1;
}

(3)出栈操作

int Pop(Dstack &S,ElemType &x,int i){
switch(i){
case 0:if(S.Top[0]==-1)return 0;   x=S.data[S.Top[0]];S.Top[0]--;break;
case 1:if(S.Top[1]==Maxsize)return 0;x=S.data[S.Top[1]];S.Top[1]++;break;
default:return 0;
}
return 1;
}

例2设从键盘输入一个整数序列:a1,a2,…,an。试编写一个算法实现:用栈结构存储输入的整数,当a≠-1时,进栈;当a=-1时,输出栈顶整数并出栈。算法应对异常情况(入栈满等)给出相应的信息。
解算法描述如下:

#define Maxsize 100//栈空间容量
void InOutStack(int S[Maxsize]){
int i,x,n,top=0;
scanf("%d",&n);
for(i=1;i<=n;i++){
scanf("%d",&x);
if(x!=-1)
if(top==Maxsize-1){printf("栈满\\\\n");exit(OVERFLOW);}
else S[++top]=x;
else
if(top==0){printf("栈空\\\\n");exit(OVERFLOW);}
else printf("出栈元素是%d\\\\n",S[top--]);
}
}

例3设结点结构为(data,next),试用一个全局指针p和某种链接结构实现一个队列,并给出入队和出队操作的算法,要求它们的时间复杂度都是O(1)(不计new和delete时间)。
解本题可采用链表结构来实现。但题目中仅给一个全局指针p,且入队和出队的时间复杂度都是O(1),因此我们用只设尾指针的循环链表来实现,算法描述如下。
(1)入队操作

void EnQueue(LinkQueue &P,ElemType x){
Qnode *s;
s=new Qnode;
s->data=x;
s->next=P->next;
P->next=s;P=s;
}

(2)出队操作

void DeQueue(LinkQueue &P,ElemType &x){
Qnode *s;
if(P->next==P){printf("空队列\\\\n");exit(OVERFLOW);}
else{
s=P->next->next;
P->next->next=s->next;
x=s->data;
if(P==s)P=P->next;//只有一个结点的情况
delete s ;
}
}

例4利用两个栈S1和S2来模拟一个队列。已知栈的三个操作如下:Push(S,x),元素x入栈;Pop(S,x),栈顶元素x出栈;StackEmpty(S),判栈是否为空栈。利用栈的操作来实现该队列的三个操作:EnQueue(),插入元素入队列;DeQueue(),删除一个元素出队列;QueueEmpty(),判队列是否为空队列。
解栈的特点是后进先出,队列的特点是先进先出。所以,用两个栈S1和S2来模拟一个队列时,S1作为输入栈,逐个元素入栈,以此模拟队列元素的入队。当需要出队时,将栈S1出栈并逐个压入栈S2中,S1中最先入栈的元素,在S2中处于栈顶。S2出栈,相当于队列的出队,实现了先进先出。显然,只有S2为空且S1也为空时,才算是空队列。算法如下。
(1)入队操作

int EnQueue(Stack &s1,ElemType x){//s1是容量为n的栈,栈元素类型为ElemType。入栈成功返回OK,

//否则返回ERROR
if(s1top==n&&!StackEmpty(s2)){//top是s1的栈顶指针,s1满s2非空,这时s1不能再入栈
printf("栈满\\\\n");
exit(OVERFLOW);
}
if(s1top==n&&StackEmpty(s2))//若s2空,先将s1出栈,元素压入栈s2
while(!StackEmpty(s2)){Pop(s1,x);Push(s2,x);}
Push(s1,x);return(OK);//x入栈,实现了队列元素的入队
}

(2)出队操作
void DeQueue(Stack s1,Stack &s2){//s2是输出栈,将s2栈顶元素出栈,实现队头元素的出队

ElemType x;
if(!StackEmpty(s2)){//栈s2不空,则直接出栈
Pop(s2,x);printf("出队元素为%d\\\\n",x);
}
else//处理s2空栈
if(StackEmpty(s1)){//若输入栈也为空,则判定空队列
printf("队列空\\\\n");
exit(OVERFLOW);
}
else{//先将s1倒入s2,再进行出队操作
while(!StackEmpty(s1)){Pop(s1,x);Push(s2,x);}
Pop(s2,x); //s2出栈相当于队列出队
printf("出队元素为%d\\\\n",x);
}
}

(3)判队列空

int QueueEmpty(){//队列空返回1,否则返回0
if(StackEmpty(s1)&&StackEmpty(s2))return 1;
else return 0;
}
时间: 2024-11-02 07:40:16

《数据结构与算法 C语言版》—— 3.5典型例题的相关文章

《数据结构与算法 C语言版》—— 3.8习题

前言 "数据结构"是计算机程序设计的重要理论技术基础,是计算机学科的核心课程,也是计算机专业考研的必考课程,同时已成为其他理工科专业的热门课程.学好该课程,不仅对学习后续算法设计.数值分析.操作系统.编译原理等课程有很大帮助,而且在实际中有广泛的用途. 数据结构主要研究数据的各种组织形式以及建立在这些结构之上的各种运算的实现.它不仅为用计算机语言进行程序设计提供了方法性的理论指导,还在一个更高的层次上总结了程序设计的常用方法和常用技巧. "数据结构"课程的特点是概念

《数据结构与算法 C语言版》—— 2.4典型例题

2.4典型例题 例1顺序表La和Lb的结点的数据元素是整数,La和Lb中的元素非递减有序,线性空间足够大.试编写一个高效算法,将Lb中的元素合并到La中,使新的La的元素仍非递减有序.高效是指最大限度地避免移动元素. 解顺序表的插入的时间复杂度为O(n),平均移动近一半的元素.顺序表La和Lb合并时,若从第一个元素开始,一定会造成元素后移,这不符合本题"高效算法"的要求.另外,题中"线性空间足够大"也暗示出另外的合并方式,即应从顺序表的最后一个元素开始比较,较大者放

《数据结构与算法 C语言版》—— 3.1栈

3.1栈 3.1.1栈的抽象数据类型定义 栈(stack)是限定仅在表尾进行插入或删除操作的线性表.表尾端称为栈顶,表头端称为栈底.不含元素的栈称为空栈.由于后进栈的元素先出栈,所以栈又称为后进先出(Last In First Out,LIFO)的线性表. 在日常生活中,有很多后进先出的例子.例如,铁路调度站火车的进出是后进先出,人们脱衣服是后穿先脱等.在程序设计中,也常用栈这样的数据结构,实现与保存数据相反的顺序来使用这些数据. 栈的操作有栈的初始化.判空.进栈.出栈及取栈顶元素等.下面给出栈

《数据结构与算法 C语言版》—— 1.1数据结构的研究对象

1.1数据结构的研究对象 自然界中的许多问题是可以用数学工具进行描述的.例如,造桥中的受力问题可描述为线性方程,人口增长的情况可描述为微分方程.但更多的非数值计算问题无法用数学方程加以描述.因此,解决这类问题的关键不再是数学分析和计算方法,而是要设计出合适的数据结构,才能有效地解决问题.请看以下列举的具体问题.例1学生信息检索系统.当我们需要查找某个学生的有关信息或某个专业的情况时,只要建立了相应的数据结构,按照某种算法编写了程序,就可以实现计算机自动检索.由此,可以在学生信息检索系统中建立一个

《数据结构与算法 C语言版》—— 1.4数据类型与抽象数据类型

1.4数据类型与抽象数据类型 1.4.1数据类型 数据类型是和数据结构密切相关的一个概念,它最早出现在高级程序语言中,用以刻画(程序)操作对象的特性.在用高级程序语言编写的程序中,每个变量.常量或表达式都有一个它所属的确定的数据类型.类型显式或隐含地规定了在程序执行期间变量或表达式所有可能的取值范围,以及在这些值上允许进行的操作.因此,数据类型是一个值的集合和定义在此集合上的一组操作的总称.例如,C语言中的整型变量,其值为某个区间上的整数(依赖于机器),定义在其上的操作为加.减.乘.除和取模等算

《数据结构与算法 C语言版》—— 1.5算法与算法分析

1.5算法与算法分析 算法与程序设计和数据结构密切相关.简单地说,算法是解决问题的策略.规则.方法.算法的具体描述形式很多,但计算机程序是对算法的一种精确描述,而且可在计算机上运行.数据结构的操作的实现方法就是一个算法问题,但该问题是针对数据结构的,是在给定的数据结构上进行的.下面从算法的特性.算法描述.算法性能分析与度量等方面对算法进行介绍. 1.5.1算法 算法(algorithm)是对特定问题求解步骤的一种描述,是指令的有限序列.其中,每个指令表示一个或多个操作.一个算法必须满足以下五个重

《数据结构与算法 C语言版》—— 1.8小结

1.8小结 本章介绍了数据结构的研究对象.基本概念与术语.数据类型和抽象数据类型,以及算法.算法的设计原则.算法效率的衡量方法等.主要内容如下.(1)数据结构的研究对象数据结构是一门讨论"描述现实世界实体的数学模型(非数值计算)及其上的操作在计算机中如何表示和实现"的学科.数据结构的内容包括3个"层次"的5个"要素",如表13所示.(2)基本概念与术语简单地说,数据就是计算机操作的对象的总称.数据元素是数据的基本单位,它是数据中的一个"

《数据结构与算法 C语言版》—— 2.6小结

2.6小结 线性表是整个数据结构课程的重要基础,本章的主要内容如下.一个线性表是由n个数据元素构成的有限序列,其特点是数据元素之间存在着线性关系.在计算机中表示这种关系的两种不同的存储结构是顺序存储结构(顺序表)和链式存储结构(链表).1顺序表顺序表是在内存中用一组地址连续的存储单元依次存储线性表的数据元素,借助数组来实现.顺序表中数据元素之间的逻辑关系通过其"存储位置相邻"来表示.对于顺序表,主要有初始化.建立.销毁.插入.删除.按值查找等基本操作.插入和删除操作约需移动一半的元素

《数据结构与算法 C语言版》—— 2.3线性表的链式表示与实现

2.3线性表的链式表示与实现 线性表的顺序存储结构的特点是逻辑关系上相邻的两个元素在物理位置上也相邻,因此可以随机存取表中任一元素,它的存储位置可用一个简单.直观的公式来表示.然而,从另一方面来看,这个特点也造成了这种存储结构的弱点:在作插入或删除操作时,需移动大量元素.本节我们将讨论线性表的另一种表示方法--链式存储结构,其特点是用一组地址任意的存储单元存储线性表中的数据元素.由于它不要求逻辑上相邻的元素在物理位置上也相邻,因此它没有顺序存储结构所具有的弱点,但同时也失去了顺序表随机存取的特点