对栈的操作和算法实现

一、栈的定义

从数据结构角度看,栈也是线性表,其特殊性在于栈的基本操作都是线性操作的子集,它是操作受限的线性表。

栈(stack)是限定仅在表尾进行插入或删除操作的线性表。

栈一般分为两种:

静态栈:用数组实现;

动态栈:用链表实现。

一般用的比较多的都是动态栈。如果学会了链表,其实对栈的操作就比较简单了。

二、栈的结构

空栈的结构:(其实就是栈顶和栈顶都指向一个不存放有效数据的头结点)

存有结点的栈结构:(栈顶指针指向栈顶结点,栈底指针指向头结点)

三、用C语言实现

/*
	2016年9月17日11:35:35
	栈的操作和算法
*/
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>

typedef struct Node
{
	int data;             //数据域
	struct Node * pNext;  //指针域
} NODE, * PNODE;

typedef struct Stack
{
	PNODE pTop;          //栈顶
	PNODE pBottom;       //栈底
} STACK, * PSTACK;

//函数声明
void init_stack(PSTACK pS);      //初始化栈
void push_stack(PSTACK pS, int val);
void traverse_stack(PSTACK pS);
bool is_empty(PSTACK pS);
bool pop_stack(PSTACK pS, int * pVal);
void clear_stack(PSTACK pS);

int main(void)
{
	STACK S;
	int val;

	init_stack(&S);

	push_stack(&S, 1);
	push_stack(&S, 2);
	push_stack(&S, 3);
	push_stack(&S, 4);
	push_stack(&S, 5);
	traverse_stack(&S);
	clear_stack(&S);
	traverse_stack(&S);

/* 	if(pop_stack(&S, &val))
	{
		printf("出栈成功,出栈的值为:%d\n",val);
	}
	else
	{
		printf("出栈失败,栈为空!\n");
	}
	traverse_stack(&S); */

	return 0;
}

void init_stack(PSTACK pS)     //初始化栈
{
	PNODE pNew = (PNODE)malloc(sizeof(NODE));   //造出一个栈的头结点
	if(NULL == pNew)
	{
		printf("内存分配失败,程序终止!\n");
		exit(-1);
	}

	pS->pTop = pNew;
	pS->pBottom = pS->pTop;
	pNew->pNext = NULL;
}

void push_stack(PSTACK pS, int val)    //压栈
{
	PNODE pNew = (PNODE)malloc(sizeof(NODE));
	if(NULL == pNew)
	{
		printf("内存分配失败,程序终止!\n");
		exit(-1);
	}

	pNew->data = val;
	pNew->pNext = pS->pTop;    //不能是pNew->pNext = pBottom;因为当有多个节点时,pTop不等于pBottom;
	pS->pTop = pNew;

	return;
}

void traverse_stack(PSTACK pS)    //遍历输出,从栈顶开始遍历
{
	PNODE p = pS->pTop;

	while(pS->pBottom != p)
	{
		printf("  %d   \n", p->data);
		p = p->pNext;
	}
	printf("\n");

	return;
}

bool is_empty(PSTACK pS)   //判断是否为空
{
	if(pS->pTop == pS->pBottom)
		return true;
	else
		return false;
}

bool pop_stack(PSTACK pS, int * pVal)   //出栈
{
	if(is_empty(pS))    //先判断是否为空
	{
		return false;
	}
	else
	{
		PNODE p = pS->pTop;
		*pVal = p->data;
		pS->pTop = p->pNext;
		free(p);
		p = NULL;

		return true;
	}
}

void clear_stack(PSTACK pS)   //清空栈
{
	PNODE p, q;
	p = pS->pTop;
	q = NULL;

	while(pS->pBottom != p)
	{
		q = p->pNext;
		free(p);
		p = q;
	}

	pS->pTop = pS->pBottom;

	return;
}
 
时间: 2024-10-20 01:50:04

对栈的操作和算法实现的相关文章

栈结构的经典算法题

栈结构 颠倒一个栈的元素顺序 问题:假设有一个栈{1,2,3,4,5,6},6是栈顶,1是栈底,现在要把这个栈中的元素颠倒一下. 思路:最简单的办法当然是把栈中的元素依次pop到一个数组中,然后把这个数组再push回栈里面即可,但这样需要O(n)的辅助空间. 下面介绍一种仅使用O(1)辅助空间的算法,我们知道,可以使用递归来模拟栈的操作.我们借助函数递归pop元素,这样在递归的函数栈上依次有 {6,5,4,3,2,1},1是栈顶,6是栈底,然后在递归返回的时候,如何把当前元素塞到原栈的底部呢?这

数据结构——栈和队列相关算法实现

数据结构栈和队列的基本算法实现 限定性线性表--栈 栈的定义 栈作为一种限定性的线性表,是将线性表的插入和删除操作限制为仅在表的一端进行. 基本算法演示 /* 栈的常见操作: 1.初始化栈 2.元素进栈 3.元素出栈 4.栈的遍历 5.判断栈是否为空栈 6.清空整个栈 */ # include <stdio.h> # include <stdlib.h> typedef struct Node { int date; struct Node * pNext; }NODE,* PNO

栈的操作

学习了数据结构之的顺序表与链表之后,再去接触栈的操作,觉得简单多了.自己就想用栈来实现下实际功能.但是遇到了麻烦(对于初学者来说),不管结果怎样,这都是一次成长的过程,虽然现在问题没有解决,但是我先把他以微博的形式记录下来,以遍我在以后能解决它. #include<stdio.h> #include<stdlib.h> #include<malloc.h> #include"string.h" typedef char NoteType; //#in

栈式自编码算法

学习UFDL栈式自编码算法的笔记 深度网络的优势 深度神经网络,即含有多个隐藏层的神经网络.通过引入深度网络,我们可以计算更多复杂的输入特征.因为每一个隐藏层可以对上一层的输出进行非线性变换,因此深度神经网络拥有比"浅层"网络更加优异的表达能力(例如可以学到更加复杂的函数关系). 其实三层网络,只要能无限增加隐层的单元数就能拟合任何函数.而使用深度网络的最主要优势是:它能以更加紧凑简洁的方式来表达比浅层网络大得多的函数集合.正式点说,我们可以找到一些函数,这些函数可以用k层网络简洁地表

洛谷P1573 栈的操作 [2017年6月计划 数论11]

P1573 栈的操作 题目描述 现在有四个栈,其中前三个为空,第四个栈从栈顶到栈底分别为1,2,3,…,n.每一个栈只支持一种操作:弹出并 压入.它指的是把其中一个栈A的栈顶元素x弹出,并马上压入任意一个栈B中.但是这样的操作必须符合一定的规则才能进行.规则1:A栈不能为空.规则 2:B栈为空或x比B栈栈顶要小. 对于给定的n,请你求出把第四个栈的n个元素全部移到第一个栈的最少操作次数. 由于最少操作次数可能很多,请你把答案对1000007取模. 输入输出格式 输入格式: 一行,一个n 输出格式

HDU 5818 Joint Stacks ——(栈的操作模拟,优先队列)

题意:有两个栈A和B,有3种操作:push,pop,merge.前两种都是栈的操作,最后一种表示的是如果“merge A B”,那么把B中的元素全部放到A中,且满足先入后出的栈原则. 分析:显然,我们给每一个节点配备一个时间戳即可.我一开始的思路是直接开两个优先队列进行直接模拟,merge操作就是把一个栈的元素全部倾倒到另一个栈内,但是会出现的问题是,如果有一个状态A和B的元素都相当多了,并且反复的进行merge操作,那么每一次merge都意味着大量的元素进出,肯定会超时的.因此,我们需要优化,

栈和队列----用递归函数和栈的操作实现逆序一个栈

用递归函数和栈的操作实现逆序一个栈 一个栈依次压入1.2.3.4.5,那么从栈顶到栈底分别为5.4.3.2.1,将这个栈转置后,从栈顶到栈底为1.2.3.4.5,也就是实现栈中元素的逆序,但是只能使用递归函数来实现,不能实现其他数据结构. package com.test; import java.util.Stack; /** * Created by Demrystv. */ public class ReverseStack { //将栈stack的栈底元素返回并且删除 private s

顺序栈的操作,整数进栈,取栈顶元素,栈内剩余元素

// main.cpp //  stack_quhao //  Created by duanqibo on 2019/6/29. //  Copyright © 2019年 duanqibo. All rights reserved. //  顺序栈的操作,整数进栈,取栈顶元素,栈内剩余元素 #include <iostream> #include <stdio.h> #include <stdlib.h> const int maxsize=6; /* typede

数字位运算操作与算法简单示例

我们对于位运算可能既陌生又熟悉.知道其运算方法运算过程,但不能运用好它. 首先,我们还是回顾一下Java中位运算都包含那些操作: 一.与运算(&) 运算法则:将二进制数进行按位与运算.0&0=0:0&1=0:1&1=1 : 如:0011 & 0010 = 0010: 二.或运算(|) 运算法则:将二进制数进行按位或运算.0|0 =0:1|0 = 1;  1|1=1 如:0011 & 0010 = 0011: 三.异或运算(^) 运算法则:将二进制数进行按位异