数据结构之栈(3)

栈(stack)的定义:

栈是限定仅仅在表尾进行插入或删除操作的线性表。因此,进行插入或删除的这一端叫栈顶(top),相应的,另一端叫栈底。不含元素的空表称为空栈。

如下图:假设按照数字:1,2,3,4,5次序依次入栈,则数字1称为栈底元素,5称为栈顶元素,如果要退栈,数字5是第一个退出去的。因此,栈的修改是按照后进先出的原则进行的。

栈的特点:先进后出,后进先出

栈的基本操作:

1.进栈或压栈(插入)

2.出栈(删除)

3.判断是否为空表

4.遍历

栈的顺序结构实现:

#include<stdio.h>	
#define MAXSIZE 100
typedef int ElemType;
typedef struct {
	ElemType data[MAXSIZE];
	int top;
}Stack;
//初始化
void initStack(Stack* s) {
	s->top = -1;//压栈+1 为0,数组下标从0开始
}

栈的基本操作:


1.进栈或压栈(插入)

//栈的顺序结构-进栈/压栈
int push(Stack* s, ElemType e) {
	//判断是否栈满
	if (s->top >= MAXSIZE - 1) {
		printf("满了\n");
		return 0;
	}
	s->top++;
	s->data[s->top] = e;
	return 1;
}


2.出栈(删除)

//栈的顺序结构-出栈
ElemType pop(Stack* s, ElemType *e) {
//判断是否为空表
	if (s->top == -1) {
		printf("空表\n");
		return 0;
	}
	* e = s->data[s->top];
	s->top--;
	return 1;
}


3.判断是否为空表

//栈的顺序结构-判断栈是否为空
int isEmpty(Stack* s) {
	if (s->top == -1) {
		printf("空的\n");
		return 1;
	}
	else {
		return 0;
	}
}

4.获取栈顶元素

//栈的顺序结构-获取栈顶元素
int getTop(Stack* s, ElemType* e) {
	//判断是否为空表
	if (s->top == -1) {
		printf("空表\n");
		return 0;
	}
	*e = s->data[s->top];
	return 1;
}

5.遍历

//遍历
void ProStack(Stack* s) {
	int i = 0;
	while (i <= s->top) {
		printf("%d ", s->data[i]);
		i++;
	}
	printf("\n");
}

实现:

//实现
int main() {
	Stack s;
	initStack(&s);
	//入栈
	push(&s, 10);
	push(&s, 20);
	push(&s, 30);
	push(&s, 40);
	push(&s, 50);
	//遍历
	ProStack(&s);//10 20 30 40 50
	ElemType e;
	//出栈
	pop(&s, &e);
	printf("%d\n", e);//50
	//遍历
	ProStack(&s);//10 20 30 40
	//获取栈顶元素
	getTop(&s, &e);
	printf("%d", e);//40
}

栈的动态内存分配

格式:

#define  MAXSIZE 100
typedef struct {
	ElemType* data;
	int top;
}Stack;
//初始化
Stack* initStack() {
	Stack* s = (Stack*)malloc(sizeof(Stack));
	s->data = (ElemType*)malloc(sizeof(ElemType) * MAXSIZE);
	s->top = -1;
	return s;
}

其他代码与上面一样。

实现:

//实现
int main() {
	Stack* s = initStack();
	//入栈
	push(s, 10);
	push(s, 20);
	push(s, 30);
	push(s, 40);
	push(s, 50);
	ElemType e;
	//出栈
	pop(s, &e);
	printf("%d\n", e);//50
	//获取栈顶元素
	getTop(s, &e);
	printf("%d", e);//40
}

栈的链式结构实现

格式:

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

typedef int ElemType;
typedef struct stack {
	ElemType data;
	struct stack* next;
}Stack;
//依然满足栈的特点:先进后出,后进先出
//如果使用头插法那么尾结点就是栈底,首结点后第一个元素就是栈顶
Stack* initStack() {
	Stack* s = (Stack*)malloc(sizeof(Stack));
	s->data = 0;
	s->next = NULL;
	return s;
}

操作:

1.判断是否为空

//判断栈是否为空
int isEmpty(Stack* s) {
	if (s->next == NULL) {
		printf("空的\n");
		return 1;
	}
	else
	{
		return 0;
	}
}

2.头插法进栈

//进栈(头插法)
int push(Stack* s, ElemType e) {
	Stack* p = (Stack*)malloc(sizeof(Stack));
	p->data = e;
	p->next = s->next;
	s->next = p;
	return 1;
}

3.出栈

//出栈(删除头结点后一个结点的数据)
/*
思路:
找到头结点p
用指针q记录要出栈的结点
通过改变p的后继结点实现出栈
*/
int pop(Stack* s, ElemType* e) {
	//判断是否为空
	if (s->next == NULL) {
		printf("空的!");
		return 0;
	}
	*e = s->next->data;
	Stack* q = s->next;
	s->next = q->next;
	free(q);
	return 1;

}

4.获取栈顶元素

//获取栈顶元素
int getTop(Stack* s, ElemType* e) {
	
	//判断是否为空
	if (s->next == NULL) {
		printf("空的!");
		return 0;
	}
	*e = s->next->data;
	return 1;
}

5.遍历

//遍历
void PriStack(Stack* s) {
	Stack* q = s->next;//创建一个结构体类型的变量指向栈中的第一个元素
	//通过循环遍历打印输出
	while (q != NULL) {
		printf("%d ", q->data);
		q = q->next;
	}
	

}

实现:

int main() {
	Stack* s = initStack();//创建一个头结点
	//进栈
	push(s, 1);
	push(s, 2);
	push(s, 3);
	push(s, 4);
	push(s, 5);
	//遍历
	PriStack(s);//5 4 3 2 1
	//出栈
	ElemType e;
	pop(s, &e);
	printf("出栈元素为:%d\n", e);//出栈元素为:5
	//遍历
	PriStack(s);//4 3 2 1
	//获取栈顶元素
	printf("栈顶元素为:%d", getTop(s, e));//4

}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值