数据结构——栈

逻辑结构:在数据结构中栈只能在一段进行进栈和出栈操作的线性结构---所以满足后进先出的原则

物理结构:在存储结构上分为顺序栈和链栈

1.顺序栈

1.1顺序栈的结构体

cs 复制代码
#define MaxSize 10
typedef struct Stack
{
	int data[MaxSize];//数组用于存放栈中的元素
	int top;//栈顶指针
}SqStack;

1.2初始化顺序栈

cs 复制代码
//初始化栈
void InitStack(SqStack* S)
{
	S->top = -1;//栈顶指针为-1表示为空栈
}

1.3栈的判空

cs 复制代码
 //栈的判空
bool Empty(SqStack* S)
{
	if (S->top == -1)
	{
		printf(" 这个栈是空栈\n");
		return true;
	}
	else
	{
		return false;
	}
}

1.4进栈操作

cs 复制代码
//进栈操作

bool Push(SqStack* S)
{
	//进栈要先保证栈没有满
	if (S->top >= MaxSize)
	{
		return false;
	}
	int x = 0;
	printf("请输入要进栈的元素:");
	scanf("%d", &x);
	S->data[++S->top] = x;
	//S->top=S->top+1;
	// S->data[S->top]=x;
	//先对指针加一,再进行赋值操作
	return true;
}

1.5出栈操作

cs 复制代码
//出栈操作
bool Pop(SqStack* S,int* x)
{
	//出栈要保证栈不空
	if (S->top == -1)
	{
		return false;
	}
	//出栈操作只能取出栈顶元素
	*x = S->data[S->top--];
	//x=S->data[S->top];
	//s->top--;
	//这里的数据x依旧在内存当中并没有删除,只是在逻辑上删除了
	return true;
}

1.6读出栈顶元素

cs 复制代码
//读栈顶元素与出栈操作区别不大
bool GetTop(SqStack* S,int* x)
{
    //读栈顶元素要保证栈不空
    if (S->top == -1)
    {
        return false;
    }
     *x = S->data[S->top];
    return true;
}

1.7完整的顺序栈代码

cs 复制代码
//顺序栈的基本操作

typedef struct Stack
{
	int data[MaxSize];//数组用于存放栈中的元素
	int top;//栈顶指针
}SqStack;


//初始化栈
void InitStack(SqStack* S)
{
	S->top = -1;//栈顶指针为-1表示为空栈
}

 //栈的判空
bool Empty(SqStack* S)
{
	if (S->top == -1)
	{
		printf(" 这个栈是空栈\n");
		return true;
	}
	else
	{
		return false;
	}
}

//进栈操作

bool Push(SqStack* S)
{
	//进栈要先保证栈没有满
	if (S->top >= MaxSize)
	{
		return false;
	}
	int x = 0;
	printf("请输入要进栈的元素:");
	scanf("%d", &x);
	S->data[++S->top] = x;
	//S->top=S->top+1;
	// S->data[S->top]=x;
	//先对指针加一,再进行赋值操作
	return true;
}

//出栈操作
bool Pop(SqStack* S,int* x)
{
	//出栈要保证栈不空
	if (S->top == -1)
	{
		return false;
	}
	//出栈操作只能取出栈顶元素
	*x = S->data[S->top--];
	//x=S->data[S->top];
	//s->top--;
	//这里的数据x依旧在内存当中并没有删除,只是在逻辑上删除了
	return true;
}


//读栈顶元素与出栈操作区别不大
bool GetTop(SqStack* S,int* x)
{
	//读栈顶元素要保证栈不空
	if (S->top == -1)
	{
		return false;
	}
	 *x = S->data[S->top];
	return true;
}


int main()
{
	SqStack S;
	int x = 0;//用于记录栈顶元素,或者读出栈顶元素
	InitStack(&S);
	//先进栈5个元素
	int i = 0;
	for (i = 0; i < 5; i++)
	{
		Push(&S);
	}
	//出栈一个元素
	Pop(&S,&x);
	printf("出栈元素是%d\n", x);

	//读出此时的栈顶元素
	GetTop(&S,&x);
	printf("此时的栈顶元素是%d\n", x);
	return 0;
}

2.链栈

下面主要介绍不带头结点的链栈,并且把链表的表头当作链栈的栈顶。

2.1链栈的结构体和初始化

cs 复制代码
typedef struct LinkNode
{
	int data;
	struct LinkNode* next;
}LiStack;


//初始化链栈
void InitLiStack(LiStack** L)
{
	(*L) = NULL;
}



int main()
{
	LiStack* S=NULL;
	int x = 0;
	InitLiStack(&S);//这里涉及到二级指针
	//进栈操作,先进栈五个元素
	int i = 0;
	for (i = 0; i < 5; i++)
	{
		Push(&S);
	}
	//出栈一个元素
	Pop(&S,&x);
	printf("出栈的元素是%d\n", x);

	//获取栈顶元素
	GetTop(S,&x);
	printf("当前栈顶元素是%d\n", x);
}

2.2入栈操作

cs 复制代码
//入栈
bool Push(LiStack** L)
{
	//对于链栈不存在栈满
	int x = 0;
	printf("请输入要进栈的整数:");
	scanf("%d", &x);

	LiStack* s = (LiStack*)calloc(1, sizeof(LiStack));
	if (s == NULL)
	{
		return false;
	}
	s->data = x;
	s->next = (*L);
	(*L) = s;
	return true;
}

2.3出栈操作

cs 复制代码
//出栈
bool Pop(LiStack** L, int* x)
{
	//先判断栈是否为空 
	if (L == NULL)
	{
		return false;
	}
	(*x) = (*L)->data;
	LiStack* p = (*L);
	(*L) = p->next;
	free(p);
	return true;
}

2.4读出栈顶元素

cs 复制代码
//获取栈顶元素
bool GetTop(LiStack* L,int* x)
{
	//先判断栈是否为空 
	if (L == NULL)
	{
		return false;
	}
	(*x) = L->data;
	return true;
}

2.5链栈的整体代码

cs 复制代码
//不带头结点的链栈

typedef struct LinkNode
{
	int data;
	struct LinkNode* next;
}LiStack;


//初始化链栈
void InitLiStack(LiStack** L)
//这里涉及到二级指针
{
	(*L) = NULL;
}

//入栈
bool Push(LiStack** L)
{
	//对于链栈不存在栈满
	int x = 0;
	printf("请输入要进栈的整数:");
	scanf("%d", &x);

	LiStack* s = (LiStack*)calloc(1, sizeof(LiStack));
	if (s == NULL)
	{
		return false;
	}
	s->data = x;
	s->next = (*L);
	(*L) = s;
	return true;
}

//出栈
bool Pop(LiStack** L, int* x)
{
	//先判断栈是否为空 
	if (L == NULL)
	{
		return false;
	}
	(*x) = (*L)->data;
	LiStack* p = (*L);
	(*L) = p->next;
	free(p);
	return true;
}

//获取栈顶元素
bool GetTop(LiStack* L,int* x)
{
	//先判断栈是否为空 
	if (L == NULL)
	{
		return false;
	}
	(*x) = L->data;
	return true;
}

int main()
{
	LiStack* S=NULL;
	int x = 0;
	InitLiStack(&S);//这里涉及到二级指针,传递的是栈顶指针的地址
	//进栈操作,先进栈五个元素
	int i = 0;
	for (i = 0; i < 5; i++)
	{
		Push(&S);
	}
	//出栈一个元素
	Pop(&S,&x);
	printf("出栈的元素是%d\n", x);

	//获取栈顶元素
	GetTop(S,&x);
	printf("当前栈顶元素是%d\n", x);
}
相关推荐
minji...3 小时前
数据结构 堆(4)---TOP-K问题
java·数据结构·算法
落羽的落羽4 小时前
【C++】论如何封装红黑树模拟实现set和map
数据结构·c++·学习
一百天成为python专家6 小时前
K-近邻算法
数据结构·python·算法·pandas·近邻算法·ipython·python3.11
小新学习屋6 小时前
《剑指offer》-数据结构篇-哈希表/数组/矩阵/字符串
数据结构·leetcode·哈希表
爱装代码的小瓶子16 小时前
数据结构之队列(C语言)
c语言·开发语言·数据结构
aramae19 小时前
大话数据结构之<队列>
c语言·开发语言·数据结构·算法
cccc来财20 小时前
Java实现大根堆与小根堆详解
数据结构·算法·leetcode
刚入坑的新人编程1 天前
暑期算法训练.9
数据结构·c++·算法·leetcode·面试·排序算法
找不到、了1 天前
Java排序算法之<选择排序>
数据结构·算法·排序算法
小徐不徐说1 天前
动态规划:从入门到精通
数据结构·c++·算法·leetcode·动态规划·代理模式