考研数据结构之栈(2.2)——链栈的操作(C表示)

概念

栈的定义

栈是一种只能在一端进行插入或删除操作的线性表。其中允许进行插入或删除操作的一端称为栈顶(Top)。

栈顶由一个称为栈顶指针的位置指示器(其实就是一个变量,对于顺序栈,就是记录栈顶元素所在数组位置标号的一个整型变量;

对于链式栈,就是记录栈顶元素所在结点地址的指针)来指示,它是动态变化的。

表的另一端称为栈底,栈底是固定不变的。

栈的插入和删除操作一般称为入栈和出栈。

栈的特点

由栈的定义可以看出,栈的主要特点就是先进后出(FILO)。栈中的元素就好比开进一个死胡同的车队,最先开进去的汽车只能等后进来的汽车都出去了,才能出来。

栈的存储结构

可用顺序表和链表来存储栈,栈可以依照存储结构分为两种:顺序栈链式栈。在栈的定义中已经说明,栈是一种在操作上稍加限制的线性表,即栈本质上是线性表,而线性表有两种主要的存储结构——顺序表和链表,因此栈也同样有对应的两种存储结构。

栈的数学性质

当n个元素以某种顺序进栈,并且可在任意时刻出栈(在满足先进后出的前提下)时,所获得的元素排列的数目N恰好满足函数 Catalan()的计算,即

 

 

 

 

 

链栈的两个状态:

(1)栈空状态:stack->next==NULL。即没有开始结点。

(2)栈满状态:理论上不存在栈满的情况。

链栈的两个操作:

(1)(由指针p所指的元素)进栈操作

p->next=stack->next;
stack->next=p;

(2)出栈操作(出栈元素保存在x中)

p=stack->next;
x=p->data;
stack->next=p->next;
free(p);

代码

#include <stdio.h>
#include <stdlib.h>
 
#define maxSize 20
 
/* 链栈结点定义 */
typedef struct LNode {
	int data; // 数据域
	struct LNode *next;// 指针域
} LNode;
 
/* 初始化栈 */
/* *&list指的是要初始化的栈 */
void initStack(LNode *&list) { // list要改变,所以要用引用型
	/* list表示头结点,list->data没有值,list->next表示栈顶结点 */
	list=(LNode *)malloc(sizeof(LNode));// 制造一个头结点
	list->next=NULL;
}
 
/* 判断是否栈空,如果栈空返回1,否则返回0 */
/* *list指的是要进行判断的链栈 */
int isEmpty(LNode *list) {
	if(list->next==NULL) { // 栈空状态:list->next==NULL
		return 1;
	} else {
		return 0;
	}
}
 
/* 入栈 */
/* *list指的是要入栈操作的链栈;x指的是要新入栈的元素的data值 */
void push(LNode *list,int x) {
	/* 申请新的进栈结点 */
	LNode *newNode;
	newNode=(LNode *)malloc(sizeof(LNode));
	newNode->next=NULL;
	/* 将新结点入栈,也是链表的头插法 */
	newNode->data=x;// 为新结点赋予数据
	newNode->next=list->next;
	list->next=newNode;
}
 
/* 出栈 */
/* *list指的是要出栈的链栈;&x指的是出栈元素的data值 */
int pop(LNode *list,int &x) {
	LNode *temp=list->next;// 开始结点,也就是要出栈的结点
	if(temp==NULL) {
		return 0;
	} else {
		list->next=temp->next;// 将头结点的next指向被删除结点(出栈结点)的next
		x=temp->data;// 保存出栈结点的数据data
		free(temp);// 是否结点资源
		return 1;// 出栈成功返回1
	}
}
 
/* 打印链栈 */
/* list指的是要被打印的链栈 */
void printStack(LNode  *list) {
	LNode *temp=list->next;
	printf("\n");
	while(temp!=NULL) {
		printf("%d\t",temp->data);
		temp=temp->next;
	}
	printf("\n");
}
 
int main() {
	LNode *list;
	int x;
	initStack(list);// 初始化栈
 
	/* 入栈 */
	push(list,1);// 将1入栈
	push(list,2);// 将2入栈
	push(list,3);// 将3入栈
	push(list,4);// 将4入栈
	push(list,5);// 将5入栈
	printStack(list);// 打印入栈成功的链栈
 
	/* 判断栈空 */
	printf("是否栈空(1表示栈空,0表示非空):%d\n",isEmpty(list));
 
	/* 出栈 */
	/* 第一次出栈 */
	pop(list,x);// 将栈顶元素出栈
	printf("出栈元素:%d",x);// 打印出栈的元素
	printStack(list);// 打印剩下的链栈元素
	/* 第二次出栈 */
	pop(list,x);// 将栈顶元素出栈
	printf("出栈元素:%d",x);// 打印出栈的元素
	printStack(list);// 打印剩下的链栈元素
	/* 第三次出栈 */
	pop(list,x);// 将栈顶元素出栈
	printf("出栈元素:%d",x);// 打印出栈的元素
	printStack(list);// 打印剩下的链栈元素
 
	return 0;
}

测试结果如下:

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值