文章目录
声明:栈的实现使用的是.cpp文件。
- 由于我使用的是vs2010,vs2010的编译器不支持函数返回值bool类型,并且不能这样定义for(int i= 0; i < 10; i++),必须在函数的开头声明i=0。为了编写的方便,我使用的是.cpp文件,没有使用.c文件。虽然是c++文件,但是内容是c语言。如果有需要.c文件的,请自行修改这两个地方就可以了。
1. 栈的分类
* 物理结构的不同使得栈的种类不同
1. 顺序结构
1. 静态顺序栈
2. 动态顺序栈
* 两种实现方式:
1. 一种是栈顶指针指向栈顶元素
2. 另一种是栈顶指针指向栈顶元素的下一个位置
2. 链式结构
1. 静态链栈
2. 动态链栈
* 两种实现方式:
1. 一种是带头结点
2. 另一种是不带头结点
2. 动态链式栈的实现(不带头结点)
2.1 项目结构
2.2 LinkStack.h
/*
* 使用动态链表实现链式栈(不带头结点)
*/
// 1. 定义抽象数据类型
typedef struct {
int age;
} ElemType;
// 2. 定义链式栈的结点
typedef struct LNode{
ElemType data;
struct LNode * next;
} LNode;
// 3. 定义一些接口
/**
* func:初始化链式栈
* @head:头指针
*/
void initStack(LNode ** head);
/**
* func:销毁链式栈
* @head:头指针
*/
bool isStackEmpty(LNode * head);
/**
* func:判断栈是否为空
* @head:头指针
*/
void destroyStack(LNode ** head);
/**
* func:向栈顶压入元素
* @head:头指针
* @x:要添加的元素
*/
bool push(LNode ** head, ElemType x);
/**
* func:弹出栈顶元素
* @head:头指针
* @x:存放要删除的元素
*/
bool pop(LNode ** head, ElemType * x);
/**
* func:查看栈顶元素
* @head:头指针
* @x:存放要查看的元素
*/
bool selectStackTopElem(LNode * head, ElemType * x);
2.3 LinkStack.cpp
#include <stdio.h>
#include <stdlib.h>
#include "LinkStack.h"
/**
* func:初始化链式栈
*/
void initStack(LNode ** head) {
*head = NULL;
}
/**
* func判断栈是否为空
* @head:头指针
*/
bool isStackEmpty(LNode * head) {
if (head == NULL)
return true;
else
return false;
}
/**
* func:销毁链式栈
* @head:头指针
*/
void destroyStack(LNode ** head) {
if (isStackEmpty(*head))
return;
LNode * t;
while(*head != NULL) {
t = *head;
*head = (*head)->next;
free(t);
}
*head = t = NULL;
}
/**
* func:向栈顶压入元素
* @head:头指针
* @x:要添加的元素
*/
bool push(LNode ** head, ElemType x) {
// 先动态分配一个结点
if (*head == NULL)
return false;
LNode * temp = (LNode *)malloc(sizeof(LNode));
if (temp == NULL)
return NULL;
temp->data = x;
//temp->next = NULL;
// 再将该结点压入栈中
temp->next = *head;
*head = temp;
return true;
}
/**
* func:弹出栈顶元素
* @head:头指针
* @x:存放要删除的元素
*/
bool pop(LNode ** head, ElemType * x) {
// 判断栈是否为空
if (isStackEmpty(*head))
return false;
// 栈不为空,则删除栈顶元素
LNode * p = *head;
*x = p->data;
*head = (*head)->next;
free(p);
return true;
}
/**
* func:查看栈顶元素
* @head:头指针
* @x:存放要查看的元素
*/
bool selectStackTopElem(LNode * head, ElemType * x) {
// 判断栈是否为空
if (isStackEmpty(head))
return false;
// 栈不为空,则查看栈顶元素
*x = head->data;
return true;
}
2.4 main.cpp
#include <stdio.h>
#include <stdlib.h>
#include "LinkStack.h"
void main() {
// 声明链式栈(不带头节点)
LNode * head = NULL;
initStack(&head);
// 往栈中添加3个元素
ElemType a[3] = {{11}, {12}, {13}};
printf("初始时,栈是否为空%d\n", isStackEmpty(head));
push(&head, a[0]);
push(&head, a[1]);
push(&head, a[2]);
printf("添加了3个元素后,栈是否为空%d\n", isStackEmpty(head));
// 依次删除栈顶两个元素
ElemType temp;
pop(&head, &temp);
printf("删除的第1个元素为%d\n", temp.age);
pop(&head, &temp);
printf("删除的第2个元素为%d\n", temp.age);
printf("此时,栈是否为空%d\n", isStackEmpty(head));
// 查看栈顶元素
selectStackTopElem(head, &temp);
printf("此时,栈顶元素为%d\n", temp.age);
// 销毁栈
destroyStack(&head);
}
2.5 运行结果
3. 动态链式栈的实现(带头结点)
3.1 项目结构
3.2 LinkStack.h
/*
* 使用动态链表实现链式栈(不带头结点)
*/
// 1. 定义抽象数据类型
typedef struct {
int age;
} ElemType;
// 2. 定义链式栈的结点
typedef struct LNode{
ElemType data;
struct LNode * next;
} LNode;
// 3. 定义一些接口
/**
* func:初始化链式栈
* @head:头指针
*/
void initStack(LNode ** head);
/**
* func:销毁链式栈
* @head:头指针
*/
bool isStackEmpty(LNode * head);
/**
* func:判断栈是否为空
* @head:头指针
*/
void destroyStack(LNode ** head);
/**
* func:向栈顶压入元素
* @head:头指针
* @x:要添加的元素
*/
bool push(LNode * head, ElemType x);
/**
* func:弹出栈顶元素
* @head:头指针
* @x:存放要删除的元素
*/
bool pop(LNode * head, ElemType * x);
/**
* func:查看栈顶元素
* @head:头指针
* @x:存放要查看的元素
*/
bool selectStackTopElem(LNode * head, ElemType * x);
3.3 LinkStack.cpp
#include <stdio.h>
#include <stdlib.h>
#include "LinkStack.h"
/**
* func:初始化链式栈
*/
void initStack(LNode ** head) {
*head = (LNode *)malloc(sizeof(LNode));
(*head)->next = NULL;
}
/**
* func判断栈是否为空
* @head:头指针
*/
bool isStackEmpty(LNode * head) {
if (head->next == NULL)
return true;
else
return false;
}
/**
* func:销毁链式栈
* @head:头指针
*/
void destroyStack(LNode ** head) {
LNode * t;
while(*head != NULL) {
t = *head;
*head = (*head)->next;
free(t);
}
*head = t = NULL;
}
/**
* func:向栈顶压入元素
* @head:头指针
* @x:要添加的元素
*/
bool push(LNode * head, ElemType x) {
// 先动态分配一个结点
if (head == NULL)
return false;
LNode * temp = (LNode *)malloc(sizeof(LNode));
if (temp == NULL)
return NULL;
// 再将该结点压入栈中
temp->data = x;
temp->next = head->next;
head->next = temp;
return true;
}
/**
* func:弹出栈顶元素
* @head:头指针
* @x:存放要删除的元素
*/
bool pop(LNode * head, ElemType * x) {
// 判断栈是否为空
if (isStackEmpty(head))
return false;
// 栈不为空,则删除栈顶元素
LNode * p = head->next;
*x = p->data;
head->next = p->next;
free(p);
p = NULL;
return true;
}
/**
* func:查看栈顶元素
* @head:头指针
* @x:存放要查看的元素
*/
bool selectStackTopElem(LNode * head, ElemType * x) {
// 判断栈是否为空
if (isStackEmpty(head))
return false;
// 栈不为空,则查看栈顶元素
*x = head->next->data;
return true;
}
3.4 main.cpp
#include <stdio.h>
#include <stdlib.h>
#include "LinkStack.h"
void main() {
// 声明链式栈(不带头节点)
LNode * head = NULL;
initStack(&head);
// 往栈中添加3个元素
ElemType a[3] = {{11}, {12}, {13}};
printf("初始时,栈是否为空%d\n", isStackEmpty(head));
push(head, a[0]);
push(head, a[1]);
push(head, a[2]);
printf("添加了3个元素后,栈是否为空%d\n", isStackEmpty(head));
// 依次删除栈顶两个元素
ElemType temp;
pop(head, &temp);
printf("删除的第1个元素为%d\n", temp.age);
pop(head, &temp);
printf("删除的第2个元素为%d\n", temp.age);
printf("此时,栈是否为空%d\n", isStackEmpty(head));
// 查看栈顶元素
selectStackTopElem(head, &temp);
printf("此时,栈顶元素为%d\n", temp.age);
// 销毁栈
destroyStack(&head);
}
3.5 运行结果
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/84621.html