数据结构——栈

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

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

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);
}
相关推荐
杰克尼4 小时前
BM5 合并k个已排序的链表
数据结构·算法·链表
xiaolang_8616_wjl4 小时前
c++文字游戏_闯关打怪
开发语言·数据结构·c++·算法·c++20
hqxstudying5 小时前
Java创建型模式---单例模式
java·数据结构·设计模式·代码规范
sun0077005 小时前
数据结构——栈的讲解(超详细)
数据结构
ゞ 正在缓冲99%…10 小时前
leetcode918.环形子数组的最大和
数据结构·算法·leetcode·动态规划
努力写代码的熊大11 小时前
单链表和双向链表
数据结构·链表
Orlando cron12 小时前
数据结构入门:链表
数据结构·算法·链表
许愿与你永世安宁17 小时前
力扣343 整数拆分
数据结构·算法·leetcode
Heartoxx18 小时前
c语言-指针(数组)练习2
c语言·数据结构·算法
杰克尼19 小时前
1. 两数之和 (leetcode)
数据结构·算法·leetcode