数据结构第三章C语言———栈

1.什么是栈

(stack)是仅能在表尾进行删除和增加的线性表
对栈来说,表尾段叫做栈顶。相应的表头段叫做栈尾

在这里插入图片描述
像洗盘子的时候叠盘子和取盘子就像栈的使用。
又可以分为顺序栈链栈

2.顺序栈的表示和实现

2.1栈的定义

#define MAXSIZE 300
typedef struct
{
	int  StackSize;  //栈可用的最大容量
	SElemType *top; //栈顶指针
	SElemType *base; //栈尾指针
}

在这里插入图片描述

2.2栈的初始化

步骤:
1>把一个大小为MAXSIZE的数组空间分配给栈,使base指向这段空间的基地址,即栈底
2>把top指向base代表栈此时为空
3>将栈的最大容量置为MAXSIZE

int InitStack (SqStacak &S)
{
	S.base = new SElemType[MAXSIZE];//1>把一个大小为MAXSIZE的数组空间分配给栈,使base指向这段空间的基地址,即栈底
	if(!S.base) exit (ERROR);
	S.top = S.base;//把top指向base代表栈此时为空
	S.stacksize =  MAXSIZE;//将栈的最大容量置为MAXSIZE
	return OK;
}

2.2入栈

步骤:
1>判断栈是否满,满返回ERROR。
2>不满就把新元素加到栈顶,top值加一

int Push (SqStack &s,SElemType e)
{	
	if(s.top-s.base == MAXSIZE)//1>判断栈是否满,满返回ERROR。
	return ERROR;
	else
		*S.top++ = e;//2>不满就把新元素加到栈顶,top值加一
		return OK;
}

2.3出栈

步骤:
1>判断栈是否为空,是则返回ERROR
2>不为空就栈顶指针减一并使栈顶元素出栈

int Pop(SqStack &S,SElemType &e)
{
	if(S.top == S.base)		return ERROR;//判断栈是否为空,是则返回ERROR
	else e = *S.top--;//不为空就栈顶指针减一并使栈顶元素出栈
	return OK;
}

2.4获取栈顶

步骤和出栈一样的,只不过不用栈顶指针减一

int GetTop(SqStack S)
{
	if(S.top == S.base)		return ERROR;
	return  *(S.top-1);//减一是因为上面提到过的top总是在栈顶上面那一个位置
}

顺序栈的完全表示

#include <stdio.h>
#include <stdlib.h>

#define MAX_SIZE 5    /* 栈最大容量 */
#define Empty 0        /* 空 */
#define Full 1        /* 满 */
#define Avail -1    /* 可用 */

typedef struct sta
{
    int *top;            /* 栈顶指针 */
    int *bottom;        /* 栈底指针 */
    int stack_size;        /* 栈的最大容量 */
}stack;
stack Push (stack p);        /* 入栈 */
void DisplyStack (stack p);    /* 遍历栈中元素 */
stack Pop (stack p);        /* 出栈 */
stack InitStack (stack p);    /* 初始化栈 */
int StackEmpty (stack p);    /* 判断栈是否为空 */
int StackFull (stack p);    /* 判断栈是否为满 */

int main()
{
    stack p;
    char ch;
    
    p.stack_size = MAX_SIZE;
    p = InitStack (p);    /* 初始化栈 */
    printf("Do you want to push to stack?(Y/N)");
    scanf(" %c", &ch);
    while (ch == 'Y' || ch == 'y')
    {
        p = Push (p);    /* 入栈 */
        DisplyStack (p);/* 打印栈中元素 */
        printf("Do you want to push to stack?(Y/N)");
        scanf(" %c", &ch);
    }
    printf("Do you want to pop (Y/N)");
    scanf(" %c", &ch);
    while (ch == 'Y' || ch == 'y')
    {
        p = Pop (p);
        DisplyStack (p);
        printf("Do you want to pop (Y/N)");
        scanf(" %c", &ch);
    }

    return 0;
}
/* Function:判断栈是否为空 */
int StackEmpty (stack p)
{
    if (p.top == p.bottom)
    {
        return Empty;
    }
    else
    {
        return Avail;
    }
}
/* Function:判断栈是否为满 */
int StackFull (stack p)
{
    if (p.top - p.bottom == p.stack_size)
    {
        return Full;
    }
    else
    {
        return Avail;
    }
}
/* Function:入栈 */
stack Push (stack p)
{
    int data;
    if (StackFull(p) == Full)
    {
        printf("栈空间已满,无法入栈");
        return p;
    }
    printf("Please input data");
    scanf("%d", &data);
    *p.top = data;
    p.top++;

    return p;
}
/* Function:出栈 */
stack Pop (stack p)
{
    if (StackEmpty(p) == Empty)
    {
        printf("栈为空栈,无法出栈 ");
        return p;
    }
    p.top--;
    printf("出栈元素为:%d\n", *p.top);

    return p;
}
/* Function:栈的初始化 */
stack InitStack (stack p)
{
    p.bottom = (int *)malloc(p.stack_size * sizeof(int));
    if (p.bottom == NULL)
    {
        printf("初始化栈失败\n");
        exit(0);
    }
    p.top = p.bottom;
    p.stack_size = MAX_SIZE;

    return p;
}
/* Function:遍历栈中元素,从栈顶到栈底*/
void DisplyStack (stack p)
{
    if (StackEmpty(p) == Empty)
    {
        printf("栈为空栈,无法遍历\n");
        return;
    }
    printf("栈中元素为:");
    printf("顶端[");
    while (p.top != p.bottom)
    {
        p.top--;
        printf("%d-", *p.top);
    }
    printf("]底端\n");
}

3.链栈的表示和实现

因为顺序栈在满员是重新增加容量可以实现但是很复杂,所以我们用链栈来完善这个功能

3.1栈的表示

typedef struck
{
	Elemtype data;
	struct StackNode *next;
}StackNode.*LinkStacak;

在这里插入图片描述

3.2栈的初始化

链栈的初始化就是构造一个空栈,因为没必要在搞头结点,所以就让栈顶指针置空即可

int InitStack(LinkStack &S)
{
	S = NULL;//构造一个空栈
	return OK;
}

3.3入栈

因为它用链表表示的很方便,所以不需要再判断是否为满
直接分配一个新结点即可
步骤:
1>为新元素e分配空间,用指针p指向。
2>将新结点数据域置为e
3>将新结点插入栈顶
4>修改栈顶指针为p

int Push(LinkStack &S,SElemType e)
{
	p = new StackNode;//生成新结点
	p->data = e;//为新元素e分配空间,
	p->node = S;//将新结点插入栈顶
	S = p;//修改栈顶指针为p
	return OK;
}

链栈的总体表示

3.4出栈

需要判断是否为空,并且出了后就要释放掉原有的栈顶空间
步骤:
1>判断是否为空
2>将栈顶元素给e
3>临时保存栈顶元素的空间,以备释放
4>修改栈顶指针,指向新的栈顶元素
5>释放原有的

int Pop(LinkList &S,SELemType &e)
{
	if(S == NULL)return ERROR;//判断是否为空
	e = S->data;//将栈顶元素给e
	p = S;//临时保存栈顶元素的空间,以备释放
	S= S->next;//修改栈顶指针,指向新的栈顶元素
	delete P;//释放原有的
	return OK;
}

3.5取栈顶元素

和顺序栈有关的操作没啥区别

int GetTop(LinkStack S)
{
	if(S! = NUll)	return S->data;
}
#include <iostream>
 
using namespace std;
 
typedef struct node{
    int data;
    struct node *next;
}Node;
 
typedef struct stack{
    Node *top;            /**书本写法是:加一个bottom,个人感觉没什么用,反而加一个count用于表示节点数会更好*/
    int count;
}Link_Stack;
 
/**创建一个空栈*/
Link_Stack * Creat_stack()
{
    Link_Stack *p;
    p = new Link_Stack;   /**这一步不要忘!需要给p创建空间*/
    p->count = 0;
    p->top = NULL;
 
    return p;
}
 
/**入栈操作:push*/
Link_Stack * Push_stack(Link_Stack *p,int elem)
{
    if(NULL == p)
        return NULL;
 
    Node *temp;
    temp = new Node;
    temp->data = elem;
 
    temp->next = p->top;   /**注意这里和队列的入队操作不同,next指向不同,为了方便出栈操作*/
    p->top = temp;
 
    p->count += 1;
 
    return p;
}
 
/**出栈操作:pop*/
Link_Stack * Pop_stack(Link_Stack *p)
{
    Node *temp;
    temp = p->top;
    if(NULL == p->top)
    {
        cout << "The stack is empty." << endl;
        return p;
    }
    else{
        p->top = p->top->next;    /** temp = temp->next;  千万不能这么写,看看下一步是什么?*/
        delete temp;
 
        p->count -= 1;
 
        return p;
    }
}
 
/**栈的遍历:输出栈*/
int Show_stack(Link_Stack *p)
{
    Node *temp;
    temp = p->top;
 
    if(NULL == p->top)
    {
        cout << "The stack is empty." << endl;
        return 0;
    }
    while(NULL != temp)
    {
        cout << temp->data << ' ';
        temp = temp->next;
    }
    cout << endl;
 
    return 0;
}
 
int main()
{
    int i = 5;
    int elem;
    Link_Stack *p;
    p = Creat_stack();
    while(i--)
    {
        cin >> elem;
        Push_stack(p,elem);
    }
    cout << "空栈插入5个元素后:" << endl;
    Show_stack(p);
 
    cout << "删除3个元素后:" << endl;
    for(i = 3;i--;)
    {
        Pop_stack(p);
    }
    Show_stack(p);
    cout << "count:" << p->count << endl;
 
    cout << "删除2个元素后:" << endl;
    for(i = 2;i--;)
    {
        Pop_stack(p);
    }
    Show_stack(p);
    cout << "count:" << p->count << endl;
 
    Push_stack(p,6);
    cout << "插入元素6后:" << endl;
    Show_stack(p);
    cout << "count:" << p->count << endl;
 
    return 0;
}
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值