数据结构中简单栈知识点及具体代码实现(适用于初学者或学完后复习的人)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

本文适用于初学数据结构栈或者学完后复习的人群。博主为编程新人,如有错误,还请于评论区多多指正!
内容包含:顺序栈 链栈 链表 递归里的栈四个部分 可依据需要自行跳转观看

一、栈的简单介绍?

栈(STACK): 一种特殊的数据存储结构,特殊之处相较于一般的顺序表或链表(可以于任意处进行插入删除等操作),栈限定于插入删除操作只能用栈顶处进行。即插入只能于(N+1)处,删除只能于(N)处,总结即为后进先出型(last in first out)。插入称为入栈操作(push),删除称为出栈操作(pop)。

顺序栈代码表示

#include<stdio.h>
#include <stdlib.h>

#define MaxStackSize 100

typedef struct {
int *top;
int *base;
int elem;
int stackSize;
} SqStack;

void InitSqStack(SqStack *s);//初始化栈
int StackIsEmpty(SqStack *s);//判断栈是否为空
int LengthStack(SqStack *s);//求栈的长度
int PushStack(SqStack *s, int elem);//push 入栈操作
void PopStack(SqStack *s);//pop 出栈操作

int main() {
SqStack s;
InitSqStack(&s);
int n;
printf(“请输入你想入栈的个数: “);
scanf(”%d”, &n);
for (int i = 0; i < n; ++i) {
int number = 0;
printf(“请输入你要入栈的数字: “);
scanf(”%d”, &number);
PushStack(&s, number);
}
int length = LengthStack(&s);
printf(“%d”, length);
PopStack(&s);
return 0;
}

//初始化栈
void InitSqStack(SqStack *s) {
s->base = (int *) malloc(MaxStackSize * sizeof(int));
s->top = s->base;
s->stackSize = MaxStackSize;
}

//判断栈是否为空:当top指针和base指针指向相同时:栈为空
int StackIsEmpty(SqStack *s) {
if (s->base == s->top) {
return 1;//为空返回1
} else
return 0;//不为空返回0
}

//返回栈的长度
int LengthStack(SqStack *s) {
return (s->top - s->base);
}

//push 入栈操作
int PushStack(SqStack *s, int elem) {
if (s->top - s->base == s->stackSize) {
return -1;
}
*s->top++ = elem;
return 1;
}

//pop 出栈操作
void PopStack(SqStack *s) {
if (s->top != s->base) {
s->top–;
}
}

链栈的代码表示

#include<stdio.h>
#include <stdlib.h>

typedef struct StackNode{
int elem;
struct StackNode *next;
}StackNode,*LinkStack;

void InitSqStack(StackNode *s);//初始化栈
void PushStack(StackNode *s);//push 入栈操作
void PopStack(StackNode *s);//pop 出栈操作

int main(){
LinkStack s=(LinkStack) malloc(sizeof (StackNode));
InitSqStack(s);
printf(“初始化后\n”);
PushStack(s);
PushStack(s);
PushStack(s);
printf(“\n");
PopStack(s);
printf("
\n”);
}
void InitSqStack(StackNode *s){
s->next=NULL;
}

void PushStack(StackNode *s){
StackNode *p=(StackNode *)malloc(sizeof(StackNode));
int elem;
printf(“请输入一个数据elem: “);
scanf(”%d”,&elem);
p->elem=elem;
p->next=s;
s=p;
}

void PopStack(StackNode *s){
if (s==NULL){
exit(0);
}
StackNode *p=(StackNode *)malloc(sizeof(StackNode));
p=s;
s=s->next;
free§;
printf(“hello world”);
}

在这里插入图片描述

补充:

此链表不同于常规链表,为了方便栈顶插入删除操作,使 S (StackNode *)指针始终指向栈顶元素,下面补充一下常规链表表示方法(包含头插及尾插两种方法)

常规链表表示

#include<stdio.h>
#include <stdlib.h>

typedef struct {
char name[10];
char telephone_number[15];
int age;
}Student;

typedef struct LNode{
Student date;
struct LNode *next;
}LNode ,*LinkList;

void CraetListbyHead(LinkList L, int n);
void CraetListbyFoot(LinkList L,int n);
void PrintList(LinkList L);
int LengthList(LinkList L);
Student Getelem(LinkList L, int i,Student student);
void insertElem(LinkList L,int i,Student student);

int main() {
LinkList L=(LinkList) malloc(sizeof( LNode));

CraetListbyHead( L,4);
PrintList(L);
printf("***************************\n");
printf("\n");

Student student;
student= Getelem(L,4,student);
printf("%s  %s  %d\n",student.name,student.telephone_number,student.age);
printf("***************************\n");
printf("\n");


Student student1={"汪汪","1383838438",27};
insertElem(L,4,student1);
PrintList(L);
printf("***************************\n");
printf("\n");


int length= LengthList(L);
printf("链表的长度是: %d\n",length);
return 0;

}

//头插法链表
void CraetListbyHead(LinkList L,int n){
L->next=NULL;
for (int i = n; i >0 ; --i) {
LNode *p=new LNode;
scanf(“%s %s %d”,p->date.name,p->date.telephone_number,&(p->date.age));
p->next=L->next;
L->next=p;
}
}

void PrintList(LinkList L) {
LNode *p ;
p = L->next;
while (p != NULL) {
printf(“%s %s %d \n”,p->date.name,p->date.telephone_number,p->date.age);
p=p->next;
}
}

int LengthList(LinkList L){
int i=0;
LNode *p;
p=L->next;
while(p!=NULL){
i++;
p=p->next;
}
return i;
}

Student Getelem(LinkList L,int i,Student student) {
LNode *p=L->next;
int j=1;
while(p!=NULL&&j<i){
p=p->next;
j++;
}
student=p->date;
return student;
}

void insertElem(LinkList L,int i,Student student){
LNode *s,*p;
s->date=student;
int j=1;
p=L->next;
while(p!=NULL&&j<i-1){
p=p->next;
j++;
}
s->next=p->next;
p->next=s;

}
//尾插法链表
void CraetListbyFoot(LinkList L,int n){
L->next=NULL;
LNode *r;
r=L;
for (int i = 0; i < n; ++i) {
LNode *p;
scanf(“%s %s %d”,p->date.name,p->date.telephone_number,&(p->date.age));
p->next=NULL;
r->next=p;
r=p;
}
}

递归算法里的栈

递归:定义包括自己或者自己给自己定义,会直接或者间接调用自己的过程 称为递归。递归是一种解决某类特定问题的必要方法,简单的比如斐波那契数列、阶乘计算、汉诺塔等问题。另外常见数据结构如:树、广义表等也具有递归的特性。又比如嵌套多函数调用,都有着最后调用 最先返回的特性,正好与栈的lifo结构相吻合。要使用递归,就一定会用到系统栈。
在这里插入图片描述

总结

希望这篇文章能够帮助到您!

猜你喜欢

转载自blog.csdn.net/m0_61908582/article/details/124663731