数据结构(C语言版)之栈及递归

简介: 数据结构(C语言版)之栈及递归

前言

●数据结构作为计算机专业基础课,综合性强,抽象性高,在一定程度上增加了学习难度,本次我们共同从数据结构的基础探讨,由浅入深进行数据结构的学习。
●由于作者水平有限,文章难免存在谬误之处,敬请读者斧正,俚语成篇,恳望指教!

●本文只浅显的探讨了栈的基本知识,作者相信随着学习课程的深入,我们将会对数据结构有更深的理解与收获!

正文

————————————————

一、栈

1.栈的概念及术语

image.gif编辑image.gif编辑

1.定义

只能在表的一端(栈顶)进行插入和删除运算的线性表

2.逻辑结构

与线性表相同,仍为一对一关系

3.存储结构

用顺序栈或链栈存储均可,但以顺序栈更常见

4.运算规则

只能在栈顶运算,且访问结点时依照后进先出(LIFO)或先进后出(FILO)的原则

5.实现方式

关键是编写入栈和出栈函数,具体实现依顺序栈或链栈的不同而不同 基本操作有入栈、出栈、读栈顶元素值、建栈、判断栈满、栈空等

6.栈是一种特殊的线性表,它的逻辑结构和存储结构与线性表相同,其特殊性体现在“运算受限” 。

限制在表的一端进行插入和删除操作。能够进行操作的一端是浮动端,称之为栈顶,通常用一个“栈顶指针”指示,它的位置会随着操作而发生变化;与此相对,表的另一端是固定端,称之为栈底。 如同线性表可以为空表一样,当栈中没有元素时称为空栈。往栈中插入元素的操作称为入栈,删除栈中元素的操作称栈 。

image.gif编辑

2.栈的特点

image.gif编辑image.gif编辑

二、栈的表示及基本操作

1.顺序栈

顺序栈的类型定义

#define MAXSIZE 100
typedef struct
{ 
  DataType data[MAXSIZE];
  int top;
}SqStack;
image.gif

image.gif编辑

说明

在顺序栈中,用于指示栈顶的当前位置的top是整型,它的实质是栈顶元素在数组中的下标。 栈顶指针top直接反映出栈的当前状态:空栈时,栈顶指针top为-1;

栈满时,栈顶指针top为MAXSIZE-1;

入栈时,栈顶指针top加1;

出栈时,栈顶指针top减1。

栈底位置固定不变,可以设置在数组的任意端,一般习惯上将数组低下标端作为栈底。

顺序栈的算法实现

(1)初始化栈(置栈空) 
初始化栈主要是分配存储空间,并将栈顶指针置为-1。 
int  InitStack(SqStack &S)
{   //构造一个空栈
  S.top= -1;
  return OK;
}
(2)判栈空
int  StackEmpty(SqStack S) 
//判栈为空栈时返回值为真,反之为假
{ return(S.top==-1? TRUE:FALSE);} 
(3)判栈满
int StackFull(SqStack S)
//判栈为满栈时返回值为真,反之为假
{   return(S.top==MAXSIZE-1?TRUE:FALSE);}
(4)进栈
进栈时应首先判栈满,若栈不满则将栈顶指针top上移,存入元素。
int Push(SqStack &S, DataType e)
{ //将元素e插入到栈中,作为的新栈顶
  if(StackFull(S))  return ERROR; //栈满
  S.top++;    // top加1,栈顶位置上移
  S.data[S.top]=e;   //数据e存入当前栈顶
  return  OK;
}
(5)出栈
出栈时应首先判断栈是否为空,若栈不为空,则取出栈顶元素,将栈顶指针top下移,再返回栈顶元素。
int Pop(SqStack &S,DataType &e)
{//若栈不为空,则删除栈顶元素
  if(StackEmpty(S)) return ERROR; //栈空
  e=S.data[S.top];   //取出数据放入e所指单元中
  S.top--;     // top减1,栈顶位置下移
  return OK;
}
(6)取栈顶元素1
int GetTop(SqStack S,DataType &e)
{//若栈不为空,则取栈顶元素
  if(StackEmpty(S)) return ERROR;  //栈空
  e=S.data[S.top];    //取出数据,top不变
  return OK;
}
(6)取栈顶元素2
DataType GetTop(SqStack S)
{//若栈不为空,则取栈顶元素
    DataType e;
  if(StackEmpty(S)) return ERROR;  //栈空
  e=S.data[S.top];    //取出数据,top不变
  return e;
}
image.gif

2.链栈

链栈的类型定义

链栈:通常用一个无头结点的单链表表示,其结点结构与单链表的结点结构相同。

typedef struct node
{ 
       DataType data;
       struct node* next;
} StackNode,*LinkStack;
LinkStack top;   //top为栈顶指针
image.gif

说明

对于单链表来说,在表头插入和删除结点要比在表尾相对简单,因此将单链表表头作为栈顶,则单链表的头指针即为栈顶指针。

链栈的算法实现

链栈的本质是简化的单链表,top作为栈顶指针始终指向链表首结点。进栈操作就是在链表表头插入一个新的结点,出栈操作就是删除当前的表头结点并释放空间。

(1)初始化栈(置空栈)
LinkStack  InitStack()
//空栈的top指针为NULL
{  return NULL;   }
(2)判栈空
int  StackEmpty(LinkStack top)      
//判栈为空栈时返回值为真,反之为假
{   return(top==NULL? TRUE:FALSE);  }
(3)进栈
void Push(LinkStack top, DataType e)
{   //将元素e进链栈,即在表头插入新的结点
  StackNode  *s;
  s=(StackNode*)malloc(sizeof(StackNode));
  s->data=e;
  s->next=top;
  top=s;
}
(4)出栈
int Pop(LinkStack top,DataType &e)
{   //若栈不为空将栈顶元素出栈,即为删除表头结点
  StackNode *p;
  if(StackEmpty(top)) return  ERROR;  //栈空
  e=top->data;
  p=top;
  top=top->next;
  free(p);
  retrun OK;
}
image.gif

三、栈与递归

递归的定义  

若一个对象部分地包含它自己,  或用它自己给自己定义,  则称这个对象是递归的;

若一个过程直接地或间接地调用自己, 则称这个过程是递归的过程。

long Fact ( long n ) {
    if ( n == 0) return 1;
    else return n * Fact (n-1); }
image.gif

以下三种情况常常用到递归方法

递归定义的数学函数

具有递归特性的数据结构

可递归求解的问题

image.gif编辑

image.gif编辑

image.gif编辑

image.gif编辑

image.gif编辑

image.gif编辑

image.gif编辑

image.gif编辑

image.gif编辑

image.gif编辑

总结:

本文共同探讨了栈的相关内容,在日常生活中有极其丰富的应用,作者认为要认真对待数据结构的学习,搭建基本知识框架,随着日积月累的学习逐渐填补总结,从脚踏实地做起,祝愿大家能够熟悉掌握这门课程,并将其能够熟悉的应用!

耐心看到这里的小伙伴一定很棒!加油!路在脚下,梦在前方!

●由于作者水平有限,文章难免存在谬误之处,敬请读者斧正,俚语成篇,恳望指教!

相关文章
|
28天前
|
算法 数据处理 C语言
C语言中的位运算技巧,涵盖基本概念、应用场景、实用技巧及示例代码,并讨论了位运算的性能优势及其与其他数据结构和算法的结合
本文深入解析了C语言中的位运算技巧,涵盖基本概念、应用场景、实用技巧及示例代码,并讨论了位运算的性能优势及其与其他数据结构和算法的结合,旨在帮助读者掌握这一高效的数据处理方法。
45 1
|
1月前
|
存储 算法 搜索推荐
【趣学C语言和数据结构100例】91-95
本文涵盖多个经典算法问题的C语言实现,包括堆排序、归并排序、从长整型变量中提取偶数位数、工人信息排序及无向图是否为树的判断。通过这些问题,读者可以深入了解排序算法、数据处理方法和图论基础知识,提升编程能力和算法理解。
49 4
|
1月前
|
存储 机器学习/深度学习 搜索推荐
【趣学C语言和数据结构100例】86-90
本文介绍并用C语言实现了五种经典排序算法:直接插入排序、折半插入排序、冒泡排序、快速排序和简单选择排序。每种算法都有其特点和适用场景,如直接插入排序适合小规模或基本有序的数据,快速排序则适用于大规模数据集,具有较高的效率。通过学习这些算法,读者可以加深对数据结构和算法设计的理解,提升解决实际问题的能力。
45 4
|
1月前
|
存储 算法 数据处理
【趣学C语言和数据结构100例】81-85
本文介绍了五个经典算法问题及其C语言实现,涵盖图论与树结构的基础知识。包括使用BFS求解单源最短路径、统计有向图中入度或出度为0的点数、统计无向无权图各顶点的度、折半查找及二叉排序树的查找。这些算法不仅理论意义重大,且在实际应用中极为广泛,有助于提升编程能力和数据结构理解。
45 4
|
1月前
|
算法 数据可视化 数据建模
【趣学C语言和数据结构100例】76-80
本文介绍了五种图论算法的C语言实现,涵盖二叉树的层次遍历及广度优先搜索(BFS)和深度优先搜索(DFS)的邻接表与邻接矩阵实现。层次遍历使用队列按层访问二叉树节点;BFS利用队列从源节点逐层遍历图节点,适用于最短路径等问题;DFS通过递归或栈深入图的分支,适合拓扑排序等场景。这些算法是数据结构和算法学习的基础,对提升编程能力和解决实际问题至关重要。
52 4
|
1月前
|
存储 算法 vr&ar
【趣学C语言和数据结构100例】71-75
本文介绍了五个C语言数据结构问题及其实现,涵盖链表与二叉树操作,包括按奇偶分解链表、交换二叉树左右子树、查找节点的双亲节点、计算二叉树深度及求最大关键值。通过递归和遍历等方法,解决了理论与实际应用中的常见问题,有助于提升编程能力和数据结构理解。
43 4
|
1月前
|
存储 算法 C语言
【趣学C语言和数据结构100例】66-70
本书《趣学C语言和数据结构100例》精选了5个典型的数据结构问题及C语言实现,涵盖链表与数组操作,如有序集合的集合运算、有序序列表的合并、数组中两顺序表位置互换、三递增序列公共元素查找及奇偶数重排。通过详细解析与代码示例,帮助读者深入理解数据结构与算法设计的核心思想,提升编程技能。
36 4
|
29天前
|
存储 缓存 算法
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式,强调了合理选择数据结构的重要性,并通过案例分析展示了其在实际项目中的应用,旨在帮助读者提升编程能力。
55 5
|
28天前
|
并行计算 算法 测试技术
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面,旨在通过综合策略提升程序性能,满足实际需求。
62 1
|
存储 缓存 C语言
数据结构——双链表(C语言)
数据结构——双链表(C语言)