【数据结构】11 堆栈(顺序存储和链式存储)

定义

可认为是具有一定约束的线性表,插入和删除操作都在一个称为栈顶的端点位置。也叫后入先出表(LIFO)
类型名称 :堆栈(STACK)
数据对象集 : 一个有0个或者多个元素的有穷线性表。
操作集

(1)Stack CreateStack( int MaxSize)

生成空堆栈,其最大长度为MaxSize

(2)bool IsFull(Stack)

判断栈S是否已满。

(3)bool Push(Stack S, ElementType X)

将元素X压入堆栈

(4)ElementType Pop(Stack S)

删除并返回栈顶元素

例3.5 如果将abcd四个字符按顺序压入堆栈,是否可能产生cabd这样的序列,共可能产生多少种输出?
一个字符出入栈 :只可能是A进------A出
两个字符出入栈 : 2种情况

A进A出 B进B出

A进B进 B出A出
三个字符出入栈 : 5种情况

A进B进C进 C出B出A出

A进B进 B出 C进 C出

A进B进 B出A出 C进C出

A进A出 B进B出 C进C出

A进A出 B进C进 C出B出
四个字符: 14种情况

  1. A在第一位出 A_ _ _
    对应3个字符出入栈 -5种情况
  2. A在第二位 _ A _ _
    只能B出来后A才能出 BA_ _
    对应2个字符出入栈 -2种情况
  3. A在第三位 _ _ A _
    前两位必是 B或者C
    最后一位必是D
    2种情况
  4. A在第四位 _ _ _ A
    对应三个字符出入栈 5种情况

堆栈的实现

顺序栈的实现

由一个一维数组和一个记录栈顶元素位置的变量组成,另外还有一个记录堆栈最大容量的变量MaxSize。

习惯将栈底放在数组下标小的那端,栈顶位置用一个整型变量Top记录当前栈顶元素的下标值。当Top指向-1时,表示空栈;当Top指向MaxSize-1时表示栈满。

顺序栈类型Stack表示如下:

c 复制代码
typedef int ElementType;
typedef int Position;
typedef struct SNode* PtrToSNode;

struct SNode {
	ElementType* Data;
	Position Top;
	int MaxSize;

};

typedef PtrToSNode Stack;

顺序栈的创建

c 复制代码
Stack CreateStack(int MaxSize) {
	Stack S = (Stack)malloc(sizeof(SNode) * 1);
	S->Data = (ElementType * )malloc(sizeof(ElementType) * MaxSize);
	S->Top = -1;
	S->MaxSize = MaxSize;
	return S;
}

进栈

c 复制代码
bool IsFull(Stack S) {
	if (S->Top == S->MaxSize - 1) {
		return true;
	}
	return false;
}

bool Push(Stack S, ElementType X) {
	if (IsFull(S)) {
		printf("The Stack is full!\n");
		return false;
	}
	(S->Top)++;

	S->Data[S->Top] = X;
	return true;

}

出栈

c 复制代码
bool IsEmpty(Stack S) {
	if (S->Top == -1) {
		return true;
	}
	return false;
}

ElementType Pop(Stack S) {
	if (IsEmpty(S)) {
		printf("The Stack is empty!\n");
		return -1;
	}
	int temp = S->Data[S->Top];
	(S->Top)--;
	return temp;


}

完整代码

c 复制代码
# include <stdio.h>
#include < stdlib.h>

typedef int ElementType;
typedef int Position;
typedef struct SNode* PtrToSNode;

struct SNode {
	ElementType* Data;
	Position Top;
	int MaxSize;

};

typedef PtrToSNode Stack;


Stack CreateStack(int MaxSize) {
	Stack S = (Stack)malloc(sizeof(SNode) * 1);
	S->Data = (ElementType * )malloc(sizeof(ElementType) * MaxSize);
	S->Top = -1;
	S->MaxSize = MaxSize;
	return S;
}

bool IsFull(Stack S) {
	if (S->Top == S->MaxSize - 1) {
		return true;
	}
	return false;
}

bool Push(Stack S, ElementType X) {
	if (IsFull(S)) {
		printf("The Stack is full!\n");
		return false;
	}
	/*(S->Top)++;

	S->Data[S->Top] = X;*/
	S->Data[++(S->Top)] = X;
	return true;

}

bool IsEmpty(Stack S) {
	if (S->Top == -1) {
		return true;
	}
	return false;
}

ElementType Pop(Stack S) {
	if (IsEmpty(S)) {
		printf("The Stack is empty!\n");
		return -1;
	}
	/*int temp = S->Data[S->Top];
	(S->Top)--;
	return temp;*/
	return (S->Data[(S->Top)--]);


}

void print_s(Stack S) {
	int t = S->Top;
	while (t != -1) {
		printf("Node: %d\n", S->Data[t]);
		(t)--;
	}
}

int main() {
	Stack S = NULL;
	int MaxSize = 10;
	S = CreateStack(MaxSize);
	ElementType X;
	int N;
	scanf_s("%d", &N);
	while (N--) {
		scanf_s("%d", &X);
		if (Push(S, X) == false) {
			printf("Push error!\n");
		}

	}

	print_s(S);

	int out = Pop(S);
	printf("out : %d\n", out);
	print_s(S);
	

}

用一个数组实现两个堆栈

结构体
c 复制代码
typedef struct DSNode* DStack;
struct DSNode
{
	ElementType* Data;
	Position Top1;
	Position Top2;
	int MaxSize;
};
创建
c 复制代码
DStack CreateDStack(int MaxSize) {
	DStack S = (DStack)malloc(sizeof(DSNode) * 1);
	S->Data = (ElementType*)malloc(sizeof(ElementType) * MaxSize);
	S->Top2 = -1;
	S->Top1 = MaxSize;
	S->MaxSize = MaxSize;
	return S;
}
入栈
c 复制代码
bool PushX(DStack S, ElementType X, int Tag) {
	if (S->Top1 - S->Top2 == 1) {
		printf("the stack is full!\n");
		return false;
	}
	if (Tag == 1) {
		(S->Top1)--;
		S->Data[S->Top1] = X;
	}
	else{
		(S->Top2)++;
		S->Data[S->Top2] = X;
	}
	return true;
}
出栈
c 复制代码
ElementType PopX(DStack S, int Tag) {

	if (Tag == 1) {
		if (S->Top1 == S->MaxSize) {
			printf("the stack1 is empty!\n");
			return -1;
		}
		else {
			return S->Data[(S->Top1)++];
		}
		
	}
	else {
		if (S->Top2 == -1) {
			printf("the stack2 is empty!\n");
			return -1;
		}
		else {
			return S->Data[(S->Top2)--];
		}
	}


}
完整代码
c 复制代码
# include <stdio.h>
#include < stdlib.h>

typedef int ElementType;
typedef int Position;

typedef struct DSNode* DStack;
struct DSNode
{
	ElementType* Data;
	Position Top1;
	Position Top2;
	int MaxSize;
};

DStack CreateDStack(int MaxSize) {
	DStack S = (DStack)malloc(sizeof(DSNode) * 1);
	S->Data = (ElementType*)malloc(sizeof(ElementType) * MaxSize);
	S->Top2 = -1;
	S->Top1 = MaxSize;
	S->MaxSize = MaxSize;
	return S;
}

bool PushX(DStack S, ElementType X, int Tag) {
	if (S->Top1 - S->Top2 == 1) {
		printf("the stack is full!\n");
		return false;
	}
	if (Tag == 1) {
		(S->Top1)--;
		S->Data[S->Top1] = X;
	}
	else{
		(S->Top2)++;
		S->Data[S->Top2] = X;
	}
	return true;
}

ElementType PopX(DStack S, int Tag) {

	if (Tag == 1) {
		if (S->Top1 == S->MaxSize) {
			printf("the stack1 is empty!\n");
			return -1;
		}
		else {
			return S->Data[(S->Top1)++];
		}
		
	}
	else {
		if (S->Top2 == -1) {
			printf("the stack2 is empty!\n");
			return -1;
		}
		else {
			return S->Data[(S->Top2)--];
		}
	}


}

void print_ds(DStack S) {
	printf("print S1:\n");
	int t = S->Top1;
	while (t != S->MaxSize) {
		printf("Node: %d\n", S->Data[t]);
		(t)++;
	}

	printf("print S2:\n");
	t = S->Top2;
	while (t != -1) {
		printf("Node: %d\n", S->Data[t]);
		(t)--;
	}
}

int main() {
	
	int MAXSIZE = 10;
	DStack S = CreateDStack(MAXSIZE);
	ElementType X;
	int N;
	scanf_s("%d", &N);
	while (N--) {
		scanf_s("%d", &X);
		if (PushX(S, X, 1) == false) {
			printf("Push error!\n");
		}
		if (PushX(S, X, 2) == false) {
			printf("Push error!\n");
		}

	}

	print_ds(S);
	int out = PopX(S,1);
	printf("out : %d\n", out);
	print_ds(S);


}

链式存储的实现

栈顶指针Top就是链表的栈顶结点,栈中的其他结点通过他们的指针Next链接起来,栈底结点的Next为NULL

数据结构

c 复制代码
typedef int ElementType;
typedef struct SNode* PtrToSNode;


struct SNode {
	ElementType Data;
	PtrToSNode Next;
};

typedef PtrToSNode Stack;

创建

c 复制代码
Stack CreateStack(Stack S) {
	S = (Stack)malloc(sizeof(SNode) * 1);
	S->Next = NULL;
	return S;
}

入栈

c 复制代码
bool Push(Stack S, ElementType X) {
	Stack temp = (Stack)malloc(sizeof(SNode));
	temp->Data = X;
	temp->Next = S->Next;
	S->Next = temp;
	return true;

	
	
}

出栈

c 复制代码
ElementType Pop(Stack S) {
	if (S->Next == NULL) {
		printf("the stack is empty!\n");
		return -1;
	}
	ElementType re = S->Next->Data;
	S->Next = S->Next->Next;
	return re;

}

完整代码

c 复制代码
# include <stdio.h>
#include < stdlib.h>

typedef int ElementType;
typedef struct SNode* PtrToSNode;


struct SNode {
	ElementType Data;
	PtrToSNode Next;
};

typedef PtrToSNode Stack;

Stack CreateStack(Stack S) {
	S = (Stack)malloc(sizeof(SNode) * 1);
	S->Next = NULL;
	return S;
}


bool Push(Stack S, ElementType X) {
	Stack temp = (Stack)malloc(sizeof(SNode));
	temp->Data = X;
	temp->Next = S->Next;
	S->Next = temp;
	return true;

	
	
}


ElementType Pop(Stack S) {
	if (S->Next == NULL) {
		printf("the stack is empty!\n");
		return -1;
	}
	ElementType re = S->Next->Data;
	S->Next = S->Next->Next;
	return re;

}

void prints(Stack S) {
	Stack t = S->Next;
	while (t != NULL) {
		printf("Node: %d\n", t->Data);
		t = t->Next;
	}
}

int main() {
	Stack S = NULL;
	S = CreateStack(S);
	ElementType X;
	int N;
	scanf_s("%d", &N);
	while (N--) {
		scanf_s("%d", &X);
		if (Push(S, X) == false) {
			printf("Push error!\n");
		}


	}

	prints(S);

	ElementType out = Pop(S);
	printf("out : %d\n", out);
	prints(S);


}
相关推荐
熬夜学编程的小王17 分钟前
C++类与对象深度解析(一):从抽象到实践的全面入门指南
c++·git·算法
CV工程师小林19 分钟前
【算法】DFS 系列之 穷举/暴搜/深搜/回溯/剪枝(下篇)
数据结构·c++·算法·leetcode·深度优先·剪枝
Dylanioucn23 分钟前
【分布式微服务云原生】掌握 Redis Cluster架构解析、动态扩展原理以及哈希槽分片算法
算法·云原生·架构
繁依Fanyi32 分钟前
旅游心动盲盒:开启个性化旅行新体验
java·服务器·python·算法·eclipse·tomcat·旅游
罔闻_spider42 分钟前
爬虫prc技术----小红书爬取解决xs
爬虫·python·算法·机器学习·自然语言处理·中文分词
Themberfue1 小时前
基础算法之双指针--Java实现(下)--LeetCode题解:有效三角形的个数-查找总价格为目标值的两个商品-三数之和-四数之和
java·开发语言·学习·算法·leetcode·双指针
陈序缘2 小时前
LeetCode讲解篇之322. 零钱兑换
算法·leetcode·职场和发展
-$_$-2 小时前
【LeetCode HOT 100】详细题解之二叉树篇
数据结构·算法·leetcode
大白飞飞2 小时前
力扣203.移除链表元素
算法·leetcode·链表
尘心cx2 小时前
数据结构-栈
数据结构