• 栈的表示和实现


    // c3-1.h 栈的顺序存储结构(见图3.1)
    #define STACK_INIT_SIZE 10 // 存储空间初始分配量
    #define STACK_INCREMENT 2 // 存储空间分配增量
    struct SqStack
    {
    	SElemType *base; // 在栈构造之前和销毁之后,base的值为NULL
    	SElemType *top; // 栈顶指针
    	int stacksize; // 当前已分配的存储空间,以元素为单位
    }; // 顺序栈

    // bo3-1.cpp 顺序栈(存储结构由c3-1.h定义)的基本操作(9个)
    void InitStack(SqStack &S)
    { // 构造一个空栈S(见图3.2)
    	if(!(S.base=(SElemType *)malloc(STACK_INIT_SIZE*sizeof(SElemType))))
    		exit(OVERFLOW); // 存储分配失败
    	S.top=S.base;
    	S.stacksize=STACK_INIT_SIZE;
    }
    void DestroyStack(SqStack &S)
    { // 销毁栈S,S不再存在(见图3.3)
    	free(S.base);
    	S.base=NULL;
    	S.top=NULL;
    	S.stacksize=0;
    }
    void ClearStack(SqStack &S)
    { // 把S置为空栈
    	S.top=S.base;
    }
    Status StackEmpty(SqStack S)
    { // 若栈S为空栈,则返回TRUE;否则返回FALSE
    	if(S.top==S.base)
    		return TRUE;
    	else
    		return FALSE;
    }
    int StackLength(SqStack S)
    { // 返回S的元素个数,即栈的长度
    	return S.top-S.base;
    }
    Status GetTop(SqStack S,SElemType &e)
    { // 若栈不空,则用e返回S的栈顶元素,并返回OK;否则返回ERROR
    	if(S.top>S.base)
    	{
    		e=*(S.top-1);
    		return OK;
    	}
    	else
    		return ERROR;
    }
    void Push(SqStack &S,SElemType e)
    { // 插入元素e为新的栈顶元素(见图3.4)
    	if(S.top-S.base>=S.stacksize) // 栈满,追加存储空间
    	{
    		S.base=(SElemType *)realloc(S.base,(S.stacksize+STACK_INCREMENT)*sizeof(SElemType));
    		if(!S.base)
    			exit(OVERFLOW); // 存储分配失败
    		S.top=S.base+S.stacksize;
    		S.stacksize+=STACK_INCREMENT;
    	}
    	*(S.top)++=e;
    }
    Status Pop(SqStack &S,SElemType &e)
    { // 若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;
    	// 否则返回ERROR(见图3.5)
    	if(S.top==S.base)
    		return ERROR;
    	e=*--S.top;
    	return OK;
    }
    void StackTraverse(SqStack S,void(*visit)(SElemType))
    { // 从栈底到栈顶依次对栈中每个元素调用函数visit()
    	while(S.top>S.base)
    		visit(*S.base++);
    	printf("
    ");
    }

    // main3-1.cpp 检验bo3-1.cpp的主程序
    #include"c1.h"
    typedef int SElemType; // 定义栈元素类型,此句要在c3-1.h的前面
    #include"c3-1.h"
    #include"bo3-1.cpp"
    void print(SElemType c)
    {
    	printf("%d ",c);
    }
    void main()
    {
    	int j;
    	SqStack s;
    	SElemType e;
    	InitStack(s);
    	for(j=1;j<=12;j++)
    		Push(s,j);
    	printf("栈中元素依次为");
    	StackTraverse(s,print);
    	Pop(s,e);
    	printf("弹出的栈顶元素e=%d
    ",e);
    	printf("栈空否:%d(1:空0:否)
    ",StackEmpty(s));
    	GetTop(s,e);
    	printf("栈顶元素e=%d 栈的长度为%d
    ",e,StackLength(s));
    	ClearStack(s);
    	printf("清空栈后,栈空否:%d(1:空0:否)
    ",StackEmpty(s));
    	DestroyStack(s);
    	printf("销毁栈后,s.top=%u s.base=%u s.stacksize=%d
    ",s.top,s.base, s.stacksize);
    }

    代码运行的结果:

    /*
    栈中元素依次为1 2 3 4 5 6 7 8 9 10 11 12
    弹出的栈顶元素e=12
    栈空否:0(1:空0:否)
    栈顶元素e=11 栈的长度为11
    清空栈后,栈空否:1(1:空0:否)
    销毁栈后,s.top=0 s.base=0 s.stacksize=0
    Press any key to continue
    
    */

    /*
    栈也是线性表,是操作受限的线性表。栈的操作是线性表操作的子集。因此,也可以
    将线性表的结构作为栈的结构。例如,可把不带头结点的线性单链表结构(见图212)作
    为链栈的结构,如图36 所示。这样,线性单链表的一些基本操作(在bo2-8.cpp 中)就
    可以直接用于链栈的操作了。例如,初始化链表
    和初始化链栈的操作是一样的,就不必定义
    InitStack() 函数, 可通过“ #define InitStack
    InitList ” 命令直接把InitList() 函数当作
    InitStack()函数使用。同时把栈元素SElemType
    定义为线性表元素ElemType。线性表的另一些
    基本操作,如ListInsert()也可以作为栈的基本操作Push()来使用(取特例i=1,即在第1 个
    元素之前插入)。由于栈的操作被限定仅在栈顶进行,显然,令表头为栈顶可简化栈的操
    作。教科书对栈的定义是:限定仅在表尾进行插入或删除操作的线性表(教科书44 页)。
    */



  • 相关阅读:
    迭代器相关整理
    闭包的功能举例
    函数参数相关整理
    python中进制转换及IP地址转换
    dD Geometry Kernel ( Geometry Kernels) CGAL 4.13 -User Manual
    2D and 3D Linear Geometry Kernel ( Geometry Kernels) CGAL 4.13 -User Manual
    Monotone and Sorted Matrix Search ( Arithmetic and Algebra) CGAL 4.13 -User Manual
    Algebraic Kernel ( Arithmetic and Algebra) CGAL 4.13 -User Manual
    数论中的环概念
    QT的配置及目录结构
  • 原文地址:https://www.cnblogs.com/KongkOngL/p/3945968.html
Copyright © 2020-2023  润新知