《数据结构与算法设计》实验报告书之栈的存储结构定义及基本操作

《数据结构与算法设计》实验报告书之栈的存储结构定义及基本操作

实验项目
栈的存储结构定义及基本操作
实验目的
. 掌握栈的逻辑特征
. 掌握栈顺序存储结构的特点,熟练掌握顺序栈的基本运算
. 熟练掌握栈的链式存储结构定义及基本操作
. 加深对顺序存储数据结构的理解和链式存储数据结构的理解,逐步培养解决实际问题的编程能力
实验内容
(一)基本实验内容:
1)问题描述:
假设以键盘输入的方式输入一个正整数序列:比如x1, x2, x3,…,xn,要求算法实现:当ai≠0时,将ai进栈;当ai=0时,输出栈顶元素并出栈。用栈结构存储所输入的整数序列,并且要求算法的健壮性及能够应对异常情况(如果是顺序要判断栈满栈空,如果是链式栈要判断栈空等)并给出相应的提示系统信息。
试编程实现该程序。
① 输入的形式和输入值的范围:需要用户以键盘输入的方式输入一个正整数序列
② 输出的形式:通过运行程序后将最后的正整数序列输出。
③ 程序所能达到的功能:通过对栈的使用完成对正整数序列输出
④ 测试数据:13个元素 1203405607809
输出为:13579
(二)实现要求:

  1. 编写函数,实现栈的初始化、入栈、出栈、判断栈空操作。不限顺序栈或者链栈
  2. 编写函数,实现正整数序列输出的操作。
  3. 编写一个主函数,在主函数中设计一个简单的菜单,分别调试上述算法。
    请遵循“清晰第一,效率第二”的良好编程风格,给与必要的注释说明。

算法设计分析

(一)数据结构的定义
顺序栈,即栈的顺序存储结构,是利用一组地址连续的存储单元依次存放自栈底到栈顶的数据元素,同时附设指针top指示栈顶元素在顺序 栈中的位置。为了能实现实验内容的要求,所以先实现栈的初始化、入栈、出栈、判断栈空操作,并且要求算法的健壮性。在后面使用行编辑函数的时候便于调用,以便更好地实现行编辑的功能。
顺序表存储结构定义为:
/定义顺序栈/
#define maxsize 50
typedef struct
{
int stack[maxsize];
int top;
} seqlist;
(二)总体设计
实验总共包括九个函数:主函数,初始化顺序栈函数,顺序栈栈长函数,入栈函数,打印顺序栈函数,出栈函数,逆序输出函数,行编辑1.0函数(实验要求),行编辑2.0函数(附加题要求)。
主函数:统筹调用各个函数以实现相应功能
Int main()
初始化顺序栈函数:将顺序栈的top初始化为-1
Void seqinit ()
顺序栈栈长函数:返回顺序栈的长度
Int listlength()
入栈函数:将输入的数据传入顺序栈中
Void seqbulid()
打印顺序栈函数:将顺序栈数据打印出来
Void seqprinter ()
出栈函数:实现顺序栈种单个元素的弹出
Void seqdelete ()
逆序打印函数:实现顺序栈的逆序打印
void seqsetter()
行编辑1.0函数(实验要求)
int seqlocate1()
行编辑2.0函数(附加题要求)
int seqlocate2()
(三)各函数的详细设计:
主函数main()
主要就是进行功能的实现。

初始化顺序栈函数seqinit ()
简单的对顺序栈的top进行初始化为-1,不然程序会报错。

顺序栈栈长函数listlength()
直接返回顺序栈的长度l->top+1。

顺序栈入栈函数seqbulid()
实行顺序栈的创建,把输入的数据一个一个存进开辟好空间的顺序栈中,并且顺序栈的top进行加加。

打印顺序栈函数seqprinter ()
就是直接将顺序栈打印出来,不过要注意换行

打印顺序栈函数seqsetter()
就是直接将顺序栈逆序的打印出来,不过要注意换行

顺序栈出栈函数seqdelete ()
元素的出栈,因为是栈,遵循着先进后出的原则,所以栈的出栈就显得比较简单了,直接把最后一个元素弹出即可,先用一个变量保留弹出的元素,之后top–,把弹出的元素return就好了。

行编辑1.0函数(实验要求)
实现以键盘输入的方式输入一个正整数序列:比如x1, x2, x3,…,xn,要求算法实现:当ai≠0时,将ai进栈;当ai=0时,输出栈顶元素并出栈。用栈结构存储所输入的整数序列,并且要求算法的健壮性及能够应对异常情况(如果是顺序要判断栈满栈空,如果是链式栈要判断栈空等)并给出相应的提示系统信息。

行编辑2.0函数(附加题要求)
实现以键盘输入的方式输入一个正整数序列:比如x1, x2, x3,…,xn,要求算法实现:当ai≠0时,将ai进栈;当ai=0时,前一个数字加1。用栈结构存储所输入的整数序列,并且要求算法的健壮性及能够应对异常情况(如果是顺序要判断栈满栈空,如果是链式栈要判断栈空等)并给出相应的提示系统信息。
实验测试结果
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
实验总结:(100字到200字)
此部分附上主要程序代码和相关的注释说明、调试数据及过程、问题及解决办法。 (最重要)
(1)调试过程中主要遇到哪些问题?是如何解决的?
答:其实顺序栈的难度不大,遇见的问题只有一个,就是打印,因为打印是用while(l->top>=0)实现,里面的l->top–导致栈里面的数全部弹出,导致后面的实验无法进行,所以,转变一种方法,用for或者用一个变量来代替l->top使之减减,这样问题就解决了。
(2)经验和体会
答:还是那句老话,多敲代码自己练习,有时间把链式栈写一遍,增加自己对栈的理解能力。
附录 实验程序代码(该部分请加注释)
/SeqList.h函数代码/

//#ifndef SEQLIST_H_INCLUDED
//#define SEQLIST_H_INCLUDED

/*定义顺序栈*/
#define maxsize 50
typedef struct
{
    int stack[maxsize];
    int top;//定义顺序栈的栈顶
} seqlist;

/*初始化顺序栈*/
void seqinit(seqlist *l)
{
    l->top=-1;//初始化栈顶为-1
}

/*顺序栈栈长函数listlength()*/
int listlength(seqlist *l)
{
    return l->top+1;//返回顺序栈的长度
}

/*入栈函数seqbulid()*/
int seqbulid(seqlist *l,int x)
{
	l->top++;
	if(l->top >= maxsize){//判断栈是否已满
        std::cout<<"该顺序栈已满!!"<<std::endl;
        return 0;
	}
    l->stack[l->top]=x;
    return 1;
}

/*打印顺序栈函数seqprinter ()*/
void seqprinter(seqlist *l)
{
    if(l->top < 0){//判断栈是否为空
        std::cout<<"该栈为空"<<std::endl;
        return ;
    }
	for(int i=0;i<=l->top;i++)
    {
        std::cout<<"  "<<l->stack[i];
    }
    std::cout<<"\n";
}

/*出栈函数seqdelete ()*/
int seqdelete(seqlist *l)
{
	int x;
	x = l->stack[l->top];//保留被弹出的元素
    l->top--;
    return x;
}

/*逆序输出*/
void seqsetter(seqlist *l)
{
if(l->top < 0){//判断栈是否为空
        std::cout<<"该栈为空"<<std::endl;
        return ;
    }
	for(int i=l->top;i>=0;i--)
    {
        std::cout<<"  "<<l->stack[i];
    }
    std::cout<<"\n";
}

/*行编辑函数1.0版本seqlocate ()*/
int seqlocate1(seqlist *l)
{
	l->top=-1;//清空之前的顺序栈
	std::cout<<"请输入行编辑之前的数据:"<<std::endl;
	int x;
	while(std::cin>>x && x >=0)
	{
		if(x == 0){//判断该元素是否为零,如为零,则将之前的数弹出
			seqdelete(l);
		}else{
			seqbulid(l,x);
		}
	}
	std::cout<<"行编辑之后的数据:"<<std::endl;
	seqprinter(l);
	return 1;
}

/*行编辑函数2.0版本seqlocate ()*/
int seqlocate2(seqlist *l)
{
	l->top=-1;
	std::cout<<"请输入行编辑之前的数据:"<<std::endl;
	int x;
	while(std::cin>>x && x >=0)
	{
		if(x == 0){//判断该元素是否为零,如为零,则将之前的数+1
			l->stack[l->top]++;
		}else{
			seqbulid(l,x);
		}
	}
	std::cout<<"行编辑之后的数据:"<<std::endl;
	seqprinter(l);
	return 1;
}

//#endif // SEQLIST_H_INCLUDED

/主函数代码/

#include <iostream>
#include "SeqList.h"
#include "menu.h"
using namespace std;
int main(){
    void operation();
    operation();
    return 0;
}
void operation(){
    seqlist *l = new seqlist;//申请内存空间
    seqinit(l);//顺序表的初始化
    for(;;){
        char n;
        int x;
        menu();
        cin>>n;
        switch (n){
        case 'a':
            seqinit(l);//顺序表的初始化
            cout<<"请输入数据:\n";
            while(cin>>x && x>=0){
                seqbulid(l,x);//入栈
            }
            break;
        case 'b':
            cout<<"出栈的数据为:"<<seqdelete(l);//出栈
            break;
        case 'c':
            cout<<"打印的顺序栈为:\n";
            seqprinter(l);
            break;
        case 'd':
            cout<<"顺序表逆序之后:\n";
            seqsetter(l);
            break;
        case 'e':
			seqlocate1(l);
            break;
        case 'f':
            cout<<"该顺序栈的栈长为:"<<listlength(l)<<"\n";
            break;
		case 'g':
            seqlocate2(l);
            break;
        case 'h':
            cout<<"本次服务到结束,下次再见!!"<<endl;
            return ;
        default:
            cout<<"输入的字符有问题,请重新输入!!";
            break;
        }
    }
}

/menu.h菜单函数代码/

#ifndef MENU_H_INCLUDED
#define MENU_H_INCLUDED

void menu(){
    std::cout<<"\n";
    std::cout<<" **********************顺序栈的应用**********************\n";
    std::cout<<" *                                                      *\n";
    std::cout<<" *     a:入栈                b:出栈                     *\n";
    std::cout<<" *     c:顺序打印栈          d:逆序打印栈               *\n";
    std::cout<<" *     e:行编辑1.0版本       f:打印顺序栈的长度         *\n";
	std::cout<<" *     g:行编辑2.0版本       h:退出程序                 *\n";
    std::cout<<" *                                                      *\n";
    std::cout<<" ********************************************************\n";
}

#endif // MENU_H_INCLUDED

猜你喜欢

转载自blog.csdn.net/qq_42967398/article/details/83276039
今日推荐