赞
踩
栈的链式存储结构简称为 链式栈
链式栈是通过单链表来实现的。每次入栈一个元素,向链表中添加一个节点(相当于头插法),出栈一个元素,释放一个节点。
链式栈是通过单链表来实现的。每次入栈一个元素,向链表中添加一个节点,出栈一个元素,释放一个节点。因为栈具有“后进先出”的特点,如果每次在链表的尾部进行插入和删除,就要遍历整个链表来找到尾节点。而在头部进行插入和删除时,只需根据头指针即可找到链表的首元素结点。而无需遍历链表。所以链式栈的出,入栈通过对链表进行头删和头插来实现。
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 入栈,然后出栈
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。