首页 > 编程学习 > 【数据结构】栈(顺序栈、双端栈、链栈)的存储结构及基本运算(C语言)

目录

    • 1. 栈的基本概念
    • 2. 顺序栈
    • 3. 双端顺序栈(两栈共享技术)
    • 4. 链栈

1. 栈的基本概念

栈是一种限定性线性表,是将线性表的插入和删除操作限制为仅在表的一端进行,通常将表中允许进行插入删除的一端称为栈顶(Top),因此栈顶的当前位置是动态变化的,它由一个称为栈顶指针的位置指示器来指示。表的另一端称为栈底(Bottom)。当栈中没有元素时称为空栈
栈的示意图

栈的修改是按后进先出的原则,如元素以 a1,a2,a3,…,an 的顺序进栈,则出栈顺序为 an,…,a3,a2,a1 。每次进栈的元素的元素都被放在原栈顶元素之上而成为新的栈顶,每次出栈的则是当前栈中的栈顶元素,即最后进的元素。

栈主要有两种存储结构:顺序存储结构和链式存储结构。

2. 顺序栈

顺序栈是由顺序存储结构实现的栈,利用一组地址连续的存储单元依次存放自栈底到栈顶的数据元素。利用一个位置指针 top 来动态地指示栈顶元素在顺序栈中的位置, top=-1 即表示空栈。

顺序栈的存储结构及初始化

/*顺序栈的存储结构*/
# define Stack_Size 50

typedef struct {
	int elem[Stack_Size];			//用于存放栈中元素的一维数组
	int top;						//存放栈顶元素的下标,top为-1表示空栈
}SeqStack;

/*初始化顺序栈*/
void InitStack(SeqStack* S) {
	S->top = -1;
}

顺序栈 判空、判满

/*判空*/
int IsEmpty(SeqStack* S) {
	if (S->top == -1)				//栈为空
		return TRUE;
	else
		return FALSE;
}

/*判满*/
int IsFull(SeqStack* S) {
	if (S->top == Stack_Size - 1)	//栈已满
		return TRUE;
	else
		return FALSE;
}

顺序栈 进栈、出栈、读取栈顶元素

/*顺序栈进栈*/
int Push(SeqStack* S, int x) {
	if (S->top == Stack_Size - 1)	//栈已满
		return FALSE;
	S->top++;
	S->elem[S->top] = x;			//x进栈
	return TRUE;
}

/*顺序栈出栈*/
int Pop(SeqStack* S, int *x) {
	if (S->top == -1)				//栈为空
		return FALSE;
	*x = S->elem[S->top];			//栈顶元素赋给x
	S->top--;
	return TRUE;
}

/*读取栈顶元素*/
int GetTop(SeqStack* S, int* x) {
	if (S->top == -1)				//栈为空
		return FALSE;
	else {
		*x = S->elem[S->top];		//栈顶元素赋给x
		return TRUE;
	}
}

3. 双端顺序栈(两栈共享技术)

双端顺序栈是一种两栈共享技术。申请一个一个共享的一维数组空间 S[M] ,将两个栈的栈底分别放在一维数组的两端,分别是0、M-1。
双端栈
双端栈的存储结构及初始化

/*双端顺序栈存储结构*/
# define M 100

typedef struct {
	int Stack[M];
	int top[2];						//top[0]和top[1]分别为两个栈顶指示器
}DqStack;

/*双端顺序栈初始化*/
void InitStack(DqStack* S) {
	S->top[0] = -1;
	S->top[1] = M - 1;
}

双端栈 进栈、出栈

/*双端顺序栈的进栈操作*/
int Push(DqStack* S, int x, int i) {
//将数据元素x压入第i号堆栈
	if (S->top[0] + 1 == S->top[1])		//栈已满
		return FALSE;
	switch (i) {
	case 0:								//压入0号栈
		S->top[0]++;
		S->Stack[S->top[0]] = x;
		break;
	case 1:								//压入1号栈
		S->top[1]--;
		S->Stack[S->top[1]] = x;
		break;
	default:
		return FALSE;
	}
	return TRUE;
}

/*双端顺序栈的出栈操作*/
int Pop(DqStack* S, int *x, int i) {
//从i号堆栈中弹出栈顶元素并送到x中
	switch (i) {
	case 0:								//0号栈出栈
		if (S->top[0] == -1)			//栈为空
			return FALSE;
		*x = S->Stack[S->top[0]];
		S->top[0]--;
		break;
	case 1:								//1号栈出栈
		if (S->top[1] == M)				//栈为空
			return FALSE;
		*x = S->Stack[S->top[1]];
		S->top[1]++;
		break;
	default:
		return FALSE;
	}
	return TRUE;
}

4. 链栈

链栈即采用链表作为存储结构实现的栈,链表的表头指针作为栈顶指针。
链栈链栈的存储结构

/*链栈存储结构*/
typedef struct node {
	int data;
	struct node* next;
}LinkStackNode;

typedef LinkStackNode* LinkStack;

链栈 进栈、出栈

/*链栈进栈操作*/
int Push(LinkStack LS, int x) {
	LinkStackNode* temp;
	temp = (LinkStack*)malloc(sizeof(LinkStackNode));
	temp->data = x;
	temp->next = LS->next;
	LS->next = temp;					//修改当前栈顶指针
}

/*链栈出栈操作*/
int Pop(LinkStack LS, int* x) {
	LinkStackNode* temp;
	temp = LS->next;
	if (temp == NULL)					//栈为空
		return FALSE;
	LS->next = temp->next;
	*x = temp->data;
	free(temp);
	return TRUE;
}

参考:耿国华《数据结构——用C语言描述(第二版)》

Copyright © 2010-2022 ngui.cc 版权所有 |关于我们| 联系方式| 豫B2-20100000