C语言 数据结构 之 链式栈

栈的链式存储结构简称为 链式栈

链式栈是通过单链表来实现的。每次入栈一个元素,向链表中添加一个节点(相当于头插法),出栈一个元素,释放一个节点。

链式栈是通过单链表来实现的。每次入栈一个元素,向链表中添加一个节点,出栈一个元素,释放一个节点。因为栈具有“后进先出”的特点,如果每次在链表的尾部进行插入和删除,就要遍历整个链表来找到尾节点。而在头部进行插入和删除时,只需根据头指针即可找到链表的首元素结点。而无需遍历链表。所以链式栈的出,入栈通过对链表进行头删和头插来实现。

1. 链式栈的结点结构

        链式栈是有单链表来实现的,所以与单链表的结点结构相同。由数据域和指向下一个结点的指针域(next域)组成。

//链式结构  =数据域+指针域
struct Node
{
	int data;
	struct Node *next;
};

2. 链式栈的初始化

        与单链表的初始化相同,可以设置函数单独先对每个节点进行初始化操作。

 

//  2、创建节点  为插入做准备,学习数据的时候,一定要把功能划分明确
struct Node *createNode(int data)
{
	struct Node *newNode = (struct Node *)malloc(sizeof(struct Node));
	newNode->data = data;
	newNode->next = NULL;

	return newNode;  返回指针变量
}

 3、表头插入
//  插在头结点之后  插队插入,不能越过头结点
//  插队插入,不能越过头结点

void insertNodeByHead(struct Node *headNode, int data)  //表头法插入
{

	// 1、插入的新节点的定义变量
	struct Node* newNode = createNode(data);
	// 2、 插在头结点之后  插队插入,不能越过头结点
	newNode->next = headNode->next;

	headNode->next = newNode;
}

4、打印,浏览信息

void printList(struct Node *headNode)  //打印,浏览信息
{

	//  有表头,要从第二个节点开始打印
	struct Node *pMove = headNode->next;
	while (pMove != NULL)
	{
		printf("%d\t", pMove->data);
		pMove = pMove->next;


	}

	printf("\n");
}

5、栈操作

struct  stack
{
	struct Node* stackTop;    //  用栈顶指针表示整个链表
	int size;                 //  数据结构中的万金油  记录数据结构中元素的个数

};


//  1、指针----->指针变量  动态内存申请

//  2、初始化变量

//  3、返回变量
struct  stack *createStack()
{


	//1、指针----->指针变量
	struct  stack *mystack = (struct  stack*)malloc(sizeof(struct  stack));
	

	//2、初始化变量
	mystack->size = 0;
	mystack->stackTop = NULL;
	//3、返回变量
	return mystack;
}

//入栈函数
/*  将指定的数据压入栈 */
void push(struct  stack *mystack, int data)
{
	//入栈操作----->链表的表头插入
	//无表头的链表
	struct Node *newNode = createNode(data);
	newNode->next = mystack->stackTop;  //新来元素的下一个next指向栈顶指针,连续存储
	mystack->stackTop = newNode;   //用栈顶指针  永远指向新来的元素
	mystack->size++;
}

int getTop(struct  stack *mystack)  //获取栈顶元素
{
	if (mystack->size == 0)
	{
		printf("栈为空!,无法获取");
		system("pause");
		return mystack->size;
	}

	return mystack->stackTop->data;


}

void pop(struct  stack *mystack)
{
	if (mystack->size == 0)
	{
		printf("栈为空!,无法出栈");
		system("pause");
		
	}
	else
	{
		//  无表头的链表进行删除
		struct Node *nextNode = mystack->stackTop->next;  //先保存记录
		free(mystack->stackTop);  //将原先节点的占用的内存释放

		mystack->stackTop = nextNode;
		mystack->size--;
	}
}

int empty(struct  stack *mystack)
{

	if (mystack->size == 0)
	{
		return 0;

	}
	else
		return 1;//返回1,代表栈不为空



}

6、总代码

/*

栈的应用
// 1、寻路算法  迷宫
// 2、悔棋退步问题
// 3、了解栈  FILO  先进后出  先存后拿
// 4、属于自己的编译方式
// 5、解决问题的能力
*/

#include<stdio.h>
#include<stdlib.h>
//链式结构  =数据域+指针域
struct Node
{
	int data;
	struct Node *next;
};

//  2、创建节点  为插入做准备,学习数据的时候,一定要把功能划分明确
struct Node *createNode(int data)
{
	struct Node *newNode = (struct Node *)malloc(sizeof(struct Node));
	newNode->data = data;
	newNode->next = NULL;

	return newNode;  返回指针变量
}


//  3、表头插入
//  插在头结点之后  插队插入,不能越过头结点
//  插队插入,不能越过头结点

// 函数参数设计是具有含义的:插入那个链表??插入的新节点的定义变量
void insertNodeByHead(struct Node *headNode, int data)  //表头法插入
{

	// 1、插入的新节点的定义变量
	struct Node* newNode = createNode(data);
	// 2、 插在头结点之后  插队插入,不能越过头结点
	newNode->next = headNode->next;

	headNode->next = newNode;
}

//  4、表尾插入
void insertNodeByTail(struct Node *headNode, int data)
{

	struct Node* newNode = createNode(data);
	struct Node* tailNode = headNode;
	while (tailNode->next != NULL)
	{

		tailNode = tailNode->next;
	}
	tailNode->next = newNode;
}

void printList(struct Node *headNode)  //打印,浏览信息
{

	//  有表头,要从第二个节点开始打印
	struct Node *pMove = headNode->next;
	while (pMove != NULL)
	{
		printf("%d\t", pMove->data);
		pMove = pMove->next;


	}

	printf("\n");
}



/****************************栈操作********************/
//    用结构体封装一个栈
struct  stack
{
	struct Node* stackTop;    //  用栈顶指针表示整个链表
	int size;                 //  数据结构中的万金油  记录数据结构中元素的个数

};


//  1、指针----->指针变量  动态内存申请

//  2、初始化变量

//  3、返回变量
struct  stack *createStack()
{


	//1、指针----->指针变量
	struct  stack *mystack = (struct  stack*)malloc(sizeof(struct  stack));
	

	//2、初始化变量
	mystack->size = 0;
	mystack->stackTop = NULL;
	//3、返回变量
	return mystack;
}

//入栈函数
/*  将指定的数据压入栈 */
void push(struct  stack *mystack, int data)
{
	//入栈操作----->链表的表头插入
	//无表头的链表
	struct Node *newNode = createNode(data);
	newNode->next = mystack->stackTop;  //新来元素的下一个next指向栈顶指针,连续存储
	mystack->stackTop = newNode;   //用栈顶指针  永远指向新来的元素
	mystack->size++;
}

int getTop(struct  stack *mystack)  //获取栈顶元素
{
	if (mystack->size == 0)
	{
		printf("栈为空!,无法获取");
		system("pause");
		return mystack->size;
	}

	return mystack->stackTop->data;


}

void pop(struct  stack *mystack)
{
	if (mystack->size == 0)
	{
		printf("栈为空!,无法出栈");
		system("pause");
		
	}
	else
	{
		//  无表头的链表进行删除
		struct Node *nextNode = mystack->stackTop->next;  //先保存记录
		free(mystack->stackTop);  //将原先节点的占用的内存释放

		mystack->stackTop = nextNode;
		mystack->size--;
	}
}

int empty(struct  stack *mystack)
{

	if (mystack->size == 0)
	{
		return 0;

	}
	else
		return 1;//返回1,代表栈不为空



}
int main()
{

	//1、链表的实质:结构体变量  和结构体变量  连接在一起

	struct stack *mystack = createStack();
	push(mystack, 1);
	push(mystack, 2);
	push(mystack, 3);
	push(mystack, 4);
	push(mystack, 5);
	while (empty(mystack))
	{

		printf("%d---->\t", getTop(mystack));
		pop(mystack);

	}
	printf("\n");
	system("pause");
	return 0;
}

将1 2 3 4 5 入栈,然后出栈

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Love coldplay

你的鼓励,将让我持续更新

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值