顺序栈与链栈的初始化,进栈,出栈的具体实现

一,栈的定义

栈是限定仅在表尾进行插入和删除操作的线性表
允许插入和删除的一端称为栈顶,另一端称为栈底。不含任何数据元素的栈称为空栈。栈又称为后进先出的线性表,简称LIFO结构。

注意:

  • 栈元素具有线性关系,即前驱后继关系
  • 可在线性表的表尾进行插入和删除操作,这里的表尾指的是栈顶
  • 栈底是固定的,最先进栈的只能在栈底
  • 栈的插入操作,叫做进栈,也称压栈,入栈
  • 栈的删除操作,叫做出栈,有的也叫弹栈

二,顺序栈

栈的顺序存储结构

栈是线性表的特例,栈的顺序存储是线性表顺序存储的简化,简称顺序栈

注意:

  • 线性表是用数组来实现的
  • 下标为 0 的一端作为栈底比较好
  • 定义一个top变量来指示栈顶元素在数组中的位置,当栈存在一个元素时,top等于 0, 空栈的判定条件为 top = -1
  • 若一个栈的长度为 5,则栈的普通情况,空栈和栈满的情况如下图所示:

在这里插入图片描述
顺序栈的结构定义

//顺序栈的定义 
typedef struct{
   
	Selem *base;  //栈底指针
	Selem *top;    //栈顶指针
	int Size;  //栈的长度 ,栈可用的最大容量 
}Haha; 

new的用法

  • new的作用是从自由存储为类的对象或对象数组分配内存,并将已适当分类的非零指针返回到对象。

比如:char * pchar= new char[10];
delete pchar;

例子中动态分配10char类型的内存给了pchar,来构成一个数组。需要注意的是,分配数组采用[ ],如果只是单个的只要new char就可以了。

  • 注意事项:
    (1)使用 delete 运算符可解除分配使用 new 运算符分配的内存。而且newdelete成对出现的。只出现一个是错误的或不规范的写法,即使能编译通过,也会有安全隐患,可能会造成内存泄露;
    (2)使用的newdelete相同。也就是说如果你在 new表达式中使用了 [ ],你必须在对应的 delete 表达式中使用 [ ]。
    (3)使用 newC++ 类对象分配内存时,将在分配内存后调用对象的构造函数。所以如果是自己写的类的话,最好自己写个构造函数,这样会比较好。

指针

指针是一种特殊类型的变量,用于存储值的地址

  • 指针是一个变量,其存储的是值的地址,而不是值本身
  • 如果home是一个变量,则&home是它的地址
  • 假设 m 是一个指针,则 m 表示的是一个地址,*m表示存储在该地址的值
  • &运算符来获得地址
  • *运算符来获得值

进栈操作
(建议结合下面代码理解)

//顺序栈的进栈,插入元素 e作为新的栈顶元素 
int Push(Haha &S,Selem e){
   
	if(S.top - S.base == S.Size) //栈满
		return 0; //不可再添加新的数据元素
	*(S.top ++) = e;  //将元素 e 压入栈顶,栈顶指针加一
	return 1; //进栈成功 
} 

出栈操作

时间复杂度为O(1)

//顺序栈的出栈,删除栈顶元素,返回其值 
char Pop(Haha &S){
   
	char e;
	if(S.base == S.top) //栈空
		return 0;
	e = *(--S.top); //栈顶指针减一,同时将栈顶元素赋值给e 
	return e; 
} 

整体代码如下:

#include <iostream> 
using namespace std;
#define MAX 10  //顺序栈存储空间的初始分配量 
typedef int Sta;  //typedef意思相当于 type define 
typedef char Selem;

//顺序栈的定义 
typedef struct{
   
	Selem *base;  //栈底指针
	Selem *top;    //栈顶指针
	int Size
  • 8
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
以下是用C语言实现的建立、遍历、的代码,包括顺序和链: ```c #include <stdio.h> #include <stdlib.h> #define MAXSIZE 100 // 定义顺序的最大长度 // 定义顺序结构体 typedef struct { int data[MAXSIZE]; // 存储中元素的数组 int top; // 顶指针 } SqStack; // 定义链结构体 typedef struct LNode { int data; // 存储中元素的值 struct LNode *next; // 指向下一个节点的指针 } *LinkStack; // 初始化顺序 void InitStack(SqStack *S) { S->top = -1; // 初始化顶指针为-1 } // 判断顺序是否为空 int StackEmpty(SqStack S) { if (S.top == -1) { return 1; // 为空 } else { return 0; // 不为空 } } // 操作 int StackPush(SqStack *S, int x) { if (S->top == MAXSIZE - 1) { return 0; // 满,无法 } else { S->top++; // 顶指针加1 S->data[S->top] = x; // 将元素x入 return 1; // 成功 } } // 操作 int StackPop(SqStack *S, int *x) { if (S->top == -1) { return 0; // 空,无法 } else { *x = S->data[S->top]; // 将顶元素赋值给x S->top--; // 顶指针减1 return 1; // 成功 } } // 初始化 void InitLinkStack(LinkStack *S) { *S = NULL; // 初始化为空 } // 判断链是否为空 int LinkStackEmpty(LinkStack S) { if (S == NULL) { return 1; // 为空 } else { return 0; // 不为空 } } // 操作 int LinkStackPush(LinkStack *S, int x) { LinkStack p = (LinkStack)malloc(sizeof(struct LNode)); // 创建新节点 p->data = x; // 将元素x入 p->next = *S; // 将新节点插入到链顶 *S = p; // 修改链顶指针 return 1; // 成功 } // 操作 int LinkStackPop(LinkStack *S, int *x) { if (*S == NULL) { return 0; // 空,无法 } else { LinkStack p = *S; // 指向链顶节点 *x = p->data; // 将顶元素赋值给x *S = p->next; // 修改链顶指针 free(p); // 释放原顶节点的空间 return 1; // 成功 } } int main() { int n, x, i; SqStack S1; LinkStack S2; InitStack(&S1); // 初始化顺序 InitLinkStack(&S2); // 初始化 // 输入要建立的元素个数n printf("请输入要建立的元素个数:\n"); scanf("%d", &n); // 建立顺序 printf("请输入要建立的顺序的元素值:\n"); for (i = 0; i < n; i++) { scanf("%d", &x); StackPush(&S1, x); // 操作 } // 输顺序中各元素值 printf("顺序中各元素值为:\n"); while (!StackEmpty(S1)) { StackPop(&S1, &x); // 操作 printf("%d ", x); } printf("\n"); // 建立链 printf("请输入要建立的链的元素值:\n"); for (i = 0; i < n; i++) { scanf("%d", &x); LinkStackPush(&S2, x); // 操作 } // 输中各元素值 printf("链中各元素值为:\n"); while (!LinkStackEmpty(S2)) { LinkStackPop(&S2, &x); // 操作 printf("%d ", x); } printf("\n"); // 将元素e入,并输后的顺序和链中各元素值 printf("请输入要入的元素值:\n"); scanf("%d", &x); StackPush(&S1, x); // 操作 LinkStackPush(&S2, x); // 操作 printf("入顺序中各元素值为:\n"); for (i = S1.top; i >= 0; i--) { printf("%d ", S1.data[i]); } printf("\n"); printf("入后链中各元素值为:\n"); LinkStack p = S2; while (p != NULL) { printf("%d ", p->data); p = p->next; } printf("\n"); // 将顺序和链中的顶元素,并输元素的值和顺序和链中各元素值 StackPop(&S1, &x); // 操作 printf("顺序元素的值为:%d\n", x); printf("顺序中各元素值为:\n"); for (i = S1.top; i >= 0; i--) { printf("%d ", S1.data[i]); } printf("\n"); LinkStackPop(&S2, &x); // 操作 printf("链元素的值为:%d\n", x); printf("后链中各元素值为:\n"); p = S2; while (p != NULL) { printf("%d ", p->data); p = p->next; } printf("\n"); return 0; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值