【数据结构和算法】了解认识栈,并实现栈的相关函数(上)

简介: 【数据结构和算法】了解认识栈,并实现栈的相关函数(上)

一、栈是什么?

栈:是一种特殊的线性表。其只允许在固定的一端进行插入和删除操作。进行数据的插入和删除的一端称为栈顶,另外的一端称为栈底。栈中的数据元素遵循先进后出(后进先出)的原则

之前在学习C语言的时候,就i听说过的两种概念

1.压栈:栈的插入操作叫做进栈、压栈、入栈等,插入数据在栈顶

2.出栈:栈的删除操作叫做出栈。出数据也在栈顶

 

二、栈的实现

1.实现的方式

有两种

1.我们可以通过顺序表的形式实现,因为进行尾插尾删除,代价小,就算是更改或者删除栈中指定的元素,不过也是移动位置而已。


如图所示:

结构体代码如下:

#define MAX 100
#define CAp 4 ///初始化的时候capacity的容量
#define Make 2//每一次增加的newCapacity的容量
//静态
typedef struct Stacknode {
  int data[MAX];//数据域
  int size;//表示元素个数
}Stack;
//动态
typedef struct Stacknode2 {
  int* data;//数据域
  int size;//表示元素个数
  int capacity;//表示当前容量
}Stack1;

2.通过链表的形式进行实现栈表

结构体如下:

//创建基础结构
typedef struct node {
  int data;
  struct node* next;
}ST;
//栈实际上就是一个只能进行头插头删的单向链表
//创建栈的头尾结点 结构体
typedef struct stack {
  struct node* top;//栈顶元素地址
  struct node* bottom;//栈底元素地址
  int size;//栈的元素个数
};

2.实现栈的函数

以链表实现栈为例,在本文结尾处,一并放置用数组实现栈的完整代码

1.初始化栈

结构体如上,使用的是上文的结构体类型

代码如下:

//初始化栈
struct stack* create_stack()
{
  struct stack* s = (struct stack*)malloc(sizeof(struct stack));
  s->size = 0;
  s->bottom = s->top = NULL;
  return s;
}

使用malloc函数,申请空间,将s的size大小置为0,bottom和top表示栈底栈顶都指向NULL

2.入栈

如图所示:

代码如下:

//创建新的结点
struct node* create_node(int data) {
  struct node* newnode = (struct node*)malloc(sizeof(struct node));
  newnode->next = NULL;
  newnode->data = data;
  return newnode;
}
//入栈
//入栈首先要将准备入栈的元素封装成结点,和链表没有差别
void stackPush(struct stack* s, int x) {
  ST* newnode = create_node(x);
  newnode->next = s->top;
  s->top = newnode;
  s->size++;
}

3.出栈

如图所示:

代码如下:

//出栈
void stackPop(struct stack* s, int* x) {
//判断是否为空栈   如果是 空栈的话就  使得输出 Pop failed
  if (s->size == 0) {
    printf("Pop failed\n");
    exit(-1);
  }
  //创建结点临时变量  赋值得到栈顶元素
  ST* tmp = s->top;
  *x = tmp->data;//得到数值
  s->top = tmp->next;
  s->size--;
}

4.查看栈顶元素

代码如下:

//查看栈顶元素
void stackTop(struct stack* s, int* x) {
  if (s->size == 0) {
    printf("空栈~~\n");
    exit(-1);
  }
  *x = s->top->next->data;
}

5.打印栈和清空栈

代码如下:

//清空栈
void make_stack_empty(struct stack* s) {
  s->size = 0;
  s->bottom = s->top ;
  //将栈底等于栈顶就可以  然后将size为0
}
void stackPrint(struct stack* s) {
  //打印栈表
  ST* list = s->top;
  printf("top -> ");
  while (list!=NULL) {
    printf("%d -> ", list->data);
    list = list->next;
  }
}


相关文章
|
2天前
|
存储 C语言
数据结构基础详解(C语言): 栈与队列的详解附完整代码
栈是一种仅允许在一端进行插入和删除操作的线性表,常用于解决括号匹配、函数调用等问题。栈分为顺序栈和链栈,顺序栈使用数组存储,链栈基于单链表实现。栈的主要操作包括初始化、销毁、入栈、出栈等。栈的应用广泛,如表达式求值、递归等场景。栈的顺序存储结构由数组和栈顶指针构成,链栈则基于单链表的头插法实现。
|
3天前
|
Java
【数据结构】栈和队列的深度探索,从实现到应用详解
本文介绍了栈和队列这两种数据结构。栈是一种后进先出(LIFO)的数据结构,元素只能从栈顶进行插入和删除。栈的基本操作包括压栈、出栈、获取栈顶元素、判断是否为空及获取栈的大小。栈可以通过数组或链表实现,并可用于将递归转化为循环。队列则是一种先进先出(FIFO)的数据结构,元素只能从队尾插入,从队首移除。队列的基本操作包括入队、出队、获取队首元素、判断是否为空及获取队列大小。队列可通过双向链表或数组实现。此外,双端队列(Deque)支持两端插入和删除元素,提供了更丰富的操作。
10 0
【数据结构】栈和队列的深度探索,从实现到应用详解
|
8天前
|
Linux C++ Windows
栈对象返回的问题 RVO / NRVO
具名返回值优化((Name)Return Value Optimization,(N)RVO)是一种优化机制,在函数返回对象时,通过减少临时对象的构造、复制构造及析构调用次数来降低开销。在C++中,通过直接在返回位置构造对象并利用隐藏参数传递地址,可避免不必要的复制操作。然而,Windows和Linux上的RVO与NRVO实现有所不同,且接收栈对象的方式也会影响优化效果。
|
24天前
|
负载均衡 网络协议 安全
DKDP用户态协议栈-kni
DKDP用户态协议栈-kni
|
23天前
|
存储 安全 编译器
缓冲区溢出之栈溢出(Stack Overflow
【8月更文挑战第18天】
46 3
|
24天前
|
负载均衡 网络协议 安全
DPDK用户态协议栈-KNI
DPDK用户态协议栈-KNI
|
24天前
|
测试技术
【初阶数据结构篇】栈的实现(附源码)
在每一个方法的第一排都使用assert宏来判断ps是否为空(避免使用时传入空指针,后续解引用都会报错)。
|
24天前
|
算法
【初阶数据结构】复杂度算法题篇
该方法基于如下的事实:当我们将数组的元素向右移动 k 次后,尾部 kmodn 个元素会移动至数组头部,其余元素向后移动 kmodn 个位置。
|
25天前
|
机器学习/深度学习 人工智能 算法
【人工智能】线性回归模型:数据结构、算法详解与人工智能应用,附代码实现
线性回归是一种预测性建模技术,它研究的是因变量(目标)和自变量(特征)之间的关系。这种关系可以表示为一个线性方程,其中因变量是自变量的线性组合。
37 2
|
10天前
crash —— 获取内核地址布局、页大小、以及栈布局
crash —— 获取内核地址布局、页大小、以及栈布局