栈的概念及其基本操作--详细(C++)

基本概念及相关术语:

栈是只允许在一端进行插入和删除操作的线性表

由此可见,栈也是线性表的一种,只是栈的操作受限制的线性表。

栈顶(top):线性表允许插入和删除的那一段。值得注意的是,栈顶指针top的指向是有些两种方式的,一种是指向栈顶当前元素,一种是指向栈顶的下一位置。两种指向方式对栈的操作影响不大,只是在判断栈顶位置的时候略有差异,本文以指向当前栈顶元素为例。另一种指向方式读者可以自行实践。

栈底(bottom):固定的,不允许进行插入和删除的另一端。

空栈:不含有任何元素的空表。

栈的存储方式:

栈有两种基本存储方式:

  1. 顺序存储:利用一段连续的内存空间进行存储。
  2. 链式存储:利用非连续的内存空间存储,元素之间使用指针进行链接。(通常单链表实现,栈顶是表头,栈底的表尾)

链栈的优点:

  • 便于多个栈共享存储空间,提高空间效率;
  • 不存在栈满上溢的情况

栈的特性:

先进后出

栈的基本操作--顺序存储

栈的基本操作大致包括6个:

  1. InitStack(&s):初始化一个空栈;
  2. StackEmpty(s):判断一个在栈是否为空;
  3. Push(&s,x):入栈,若栈S未满,这将x加入栈,使之称为栈顶;
  4. Pop(&s):出栈,若栈S非空,则弹出栈顶元素;
  5. GetTop(s,x):读栈顶元素;
  6. DestroyStack(&s):销毁栈,释放栈S所占用内存空间;

1.InitStack(&s):初始化一个空栈:

创建一个空栈后,将栈顶指针指向-1;

void stackinit(sq& s)
{
	s.top = -1;
}

2.StackEmpty(s):判断一个在栈是否为空:

bool stackempty(sq s)
{
	if (s.top == -1) return true; //为空返回true
	else return false; //不为空返回false
}

3.Push(&s,x):入栈,若栈S未满,这将x加入栈,使之称为栈顶:

bool push(sq& s, int x)
{
	if (s.top == maxsize - 1) return false; //如果栈空间满,则不能再插入元素,否则导致内存溢出,直接返回false;
	s.data[++s.top] = x; //栈不满,则可以插入元素,将栈顶指针上移,再将需要插入的元素赋值给栈顶
	return true;
}

4.Pop(&s):出栈,若栈S非空,则弹出栈顶元素:

void pop(sq& s)
{
	if (s.top == -1) cout << "栈空"<<endl; //栈为空,则不能出栈。
	s.top--; //栈不空,能出栈,栈顶指针下移
}

5.GetTop(s,x):读栈顶元素:

int gettop(sq s)
{
	int x; //接收栈顶元素 
	if (s.top == -1) return -1; //栈空,无法读取元素
	x = s.data[s.top]; //栈不空,将当前栈顶元素赋值给x
	return x; //返回x的值,即读取x的值
}

6.DestroyStack(&s):销毁栈,释放栈S所占用内存空间:

void destorystack(sq &s) {
	if (s.top!=-1) free(s.data); //若栈不空,释放栈所占用的内存空间
	s.top = -1;
}

整体代码:

#include<iostream>
using namespace std;
#define maxsize 10
typedef struct {
	int data[maxsize];
	int top;
}sq;
void stackinit(sq& s)
{
	s.top = -1;
}
bool stackempty(sq s)
{
	if (s.top == -1) return true;
	else return false;
}
bool push(sq& s, int x)
{
	if (s.top == maxsize - 1) return false;
	s.data[++s.top] = x;
	return true;
}
void pop(sq& s)
{
	if (s.top == -1) cout << "栈空"<<endl;
	s.top--;
}
int gettop(sq s)
{
	int x;
	if (s.top == -1) return -1;
	x = s.data[s.top];
	return x;
}
void destorystack(sq &s) {
	if (s.top!=-1) free(s.data);
	s.top = -1;
}
int main() {
	sq s1;
	stackinit(s1);
	for (int i = 0; i < 10; i++)
	{
		push(s1, i);
	}
	while (!stackempty(s1))
	{
		cout << gettop(s1)<< " ";
		s1.top--;
	}	
	cout << endl;
	for (int i = 0; i < 10; i++)
	{
		push(s1, i);
	}
	pop(s1);
	while (!stackempty(s1))
	{
		cout << gettop(s1) << " ";
		s1.top--;
	}
	destorystack(s1);
	return 0;
}

执行结果:

链表的基本操作--链式存储

链式存储就是对链表的操作,在这里可以设置头节点也可以不设置头节点。

我这里以单链表有头结点的头插法为例。

链栈的节点定义:

typedef struct Linknode {
	int data;
	struct Linknode* next;
};

1.InitStack(*head):初始化一个空栈:

void initlink(Linknode *head) {
	if (head == nullptr) cout << "分配失败" << endl;
	else head->next = nullptr;
}

2.StackEmpty(*head):判断一个在栈是否为空:

bool isempty(Linknode* head) {
	if (head->next == nullptr)  return true;
	else return false;
}

3.Push(*head,x):入栈:

void enqueue(Linknode* head,int x) {
	Linknode* L = new Linknode[sizeof(Linknode)];
	L->data = x;
	L->next = head->next;
	head->next = L;
}

4.Pop(*head):出栈:

void dequeue(Linknode* head)
{
	Linknode* L = new Linknode[sizeof(Linknode)];
	L = head->next;
	head->next = L->next;
	delete[] L;
}

5.GetTop(s,x):读栈顶元素:

void gethead(Linknode* head)
{
	int x;
	x = head->next->data;
	cout << x << endl;
}

6.DestroyStack(&s):销毁栈:

void DestroyStack(Linknode* head) {
	Linknode* p = new Linknode[sizeof(Linknode)];
	p = head->next;
	if (!isempty(head)) {
		while (head->next != nullptr)
		{
			head->next = p->next;
			delete[]p;
			p = head->next;
		}
	}
	delete[]p;
}

整体代码:

#include<iostream>
using namespace std;
typedef struct Linknode {
	int data;
	struct Linknode* next;
};
void initlink(Linknode *head) {
	//head = new Linknode[sizeof(Linknode)];
	if (head == nullptr) cout << "分配失败" << endl;
	else head->next = nullptr;
}
bool isempty(Linknode* head) {
	if (head->next == nullptr)  return true;
	else return false;
}
void enqueue(Linknode* head,int x) {
	Linknode* L = new Linknode[sizeof(Linknode)];
	L->data = x;
	L->next = head->next;
	head->next = L;
}
void dequeue(Linknode* head)
{
	Linknode* L = new Linknode[sizeof(Linknode)];
	L = head->next;
	head->next = L->next;
	delete[] L;
}
void gethead(Linknode* head)
{
	int x;
	x = head->next->data;
	cout << x << endl;
}
void DestroyStack(Linknode* head) {
	Linknode* p = new Linknode[sizeof(Linknode)];
	p = head->next;
	if (!isempty(head)) {
		while (head->next != nullptr)
		{
			head->next = p->next;
			delete[]p;
			p = head->next;
		}
	}
	delete[]p;
}
int main() {
	Linknode* h = new Linknode[sizeof(Linknode)];
	initlink(h);
	if (isempty(h)) cout << "链表空" << endl;
	for (int i = 0; i < 10; i++)
	{
		enqueue(h, i);
	}
	gethead(h);
	dequeue(h);
	gethead(h);
	DestroyStack(h);
	return 0;
}

执行结果:

  • 47
    点赞
  • 385
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
map是一种基于哈希表实现的数据结构,它允许存储一对键值对,并按照的方式对这些键值对进行操作。在C语言中,我们可以通过以下方式实现map基本操作: 1. 初始化:首先,我们需要定义一个空的map,并分配内存空间来存储键值对。可以使用一个结构体来表示一个键值对,例如: ```c typedef struct { int key; int value; } KeyValuePair; KeyValuePair* stack; int top = -1; int capacity = 10; ``` 2. 入:在map中,入操作将一个键值对添加到的顶部。我们可以将键值对添加到数组stack的末尾,并更新top变量的值。如果已满,可以考虑动态扩容。 ```c void push(int key, int value) { if (top == capacity - 1) { // 已满,执行动态扩容操作 // ... } KeyValuePair* pair = malloc(sizeof(KeyValuePair)); pair->key = key; pair->value = value; stack[++top] = *pair; } ``` 3. 出:出操作将顶的键值对移除,并返回该键值对。我们可以通过减小top的值来实现出操作。 ```c KeyValuePair pop() { if (top == -1) { // 为空,返回一个默认的键值对或者抛出异常 // ... } KeyValuePair pair = stack[top]; top--; return pair; } ``` 4. 获取顶元素:获取顶元素操作返回顶的键值对,但不对进行任何修改。 ```c KeyValuePair topElement() { if (top == -1) { // 为空,返回一个默认的键值对或者抛出异常 // ... } return stack[top]; } ``` 需要注意的是,上述代码只是简单示例,并没有完整处理异常情况和动态扩容等操作。在实际应用中,可能需要根据具体需求进行适当的修改和优化。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值