笔试c语言实现栈,c语言实现栈的一般操作(王道课后题)

本文详细介绍了栈和链表在括号匹配、火车车厢调度以及非递归计算等场景的应用。通过顺序栈和链式栈的数据结构,实现了括号匹配算法、火车车厢软硬座调整以及斐波那契数列的非递归计算,展示了数据结构在实际问题中的解决能力。
摘要由CSDN通过智能技术生成

#include //调用命名空间std内定义的所有标识符

using namespace std;

#define MaxSize 50

#define Elemtype char

//栈的顺序存储

typedef struct {

Elemtype data[MaxSize];

int top;

} SqStack;

//栈的链式存储

typedef struct LinkNode {

Elemtype data;

struct LinkNode* next;

}*LinkStack;

typedef struct LNode {

Elemtype data;

struct LNode* next;

//仅设置了前驱节点,没有写建立方法

struct LNode* prior;

}LNode, * LinkedList;

//初始化

void InitStack(SqStack& S) {

S.top = -1;

}

//判断栈空

bool StackEmpty(SqStack S) {

if (S.top == -1) {

return true;

}

else {

return false;

}

}

//入栈

bool Push(SqStack& S, Elemtype e) {

if (S.top == MaxSize - 1) {

return false;

}

S.data[++S.top] = e;

returntrue;

}

//出栈

bool Pop(SqStack& S, Elemtype& e) {

if (S.top == -1) {

return false;

}

e = S.data[S.top--];

return true;

}

//读栈顶元素

bool GetTop(SqStack S, Elemtype& e) {

if (S.top == -1) {

return false;

}

e = S.data[S.top];

return true;

}

//以I和O代表入栈和出栈,判断所给序列是否合法

bool Judge(char A[]) {

int i = 0;

int j = 0, k = 0;

//数组结束的标识

while (A[i] != '\0') {

switch (A[i]) {

case 'I':

j++; break;

case 'O':

k++; break;

if (k > j) {

printf("序列非法\n");

return false;

}

}

i++;

}

if (j != k) {

printf("序列非法");

return false;

}

else {

printf("合法");

return true;

}

}

//判断带头结点单链表全部n个字符是否中心对称(eg:xyx,xyyx都是中心对称)

bool centrosymmetry(LinkedList L, int n) {

int i;

char* s = new char[n / 2];

LNode* p = L->next;

for (i = 0; i < n / 2;i++) {

s[i] = p->data;

p = p->next;

}

i--;

if (n % 2 == 1) {

p = p->next;

}

while (p!=NULL&&s[i]==p->data) {

i--;

p = p->next;

}

if (i == -1) {

return true;

}

else {

return false;

}

}

//两个栈s1和s2都采用顺序栈的方式,共享一个存储区[0,...,MaxSize-1],

//采用栈顶相向,迎面增长的存储方式,设计s1和s2有关入栈和出栈的操作算法

typedef struct {

Elemtype stack[MaxSize];

//top 两个栈顶指针

int top[2];

}stk;

stk s;

//i 为栈号,0表示s1 1表示s2

int push(int i, Elemtype e) {

if (i<0||i>1) {

printf("栈号输入错误");

return 0;

}

if (s.top[1] - s.top[0] == 1) {

printf("栈满");

return 0;

}

switch (i) {

case 0:s.stack[++s.top[0]] = e; return 1; break;

case 1:s.stack[--s.top[1]] = e; return 1; break;

default:

break;

}

}

//

Elemtype pop(int i) {

if (i < 0 || i>1) {

printf("栈号输入错误");

return 0;

}

switch (i) {

case 0:

if (s.top[0]==-1) {

printf("栈空");

return -1;

}

else {

return s.stack[s.top[0]--];

}

case 1:

if (s.top[1]==MaxSize) {

printf("栈空");

return -1;

}

else {

return s.stack[s.top[1]++];

}

default:

break;

}

}

/*

一个算数表达式中包含圆括号,方括号,花括号3种类型的括号,编写一个算法来判别

表达式中的括号是否匹配,以字符"\0" 作为算数表达式的结束符

(扫描每个字符,遇到左括号进栈,右括号时检查栈顶元素是否为相应的左括号,

是则退栈,否则匹配错误,最后栈不为空也错误)

*/

bool BracketsCheck(char* str) {

//动态数组用指针

SqStack S;

InitStack(S);

int i = 0;

Elemtype e = '0';

while (str[i]!='\0') {

switch (str[i]) {

case '(':

Push(S, '('); break;

case '[':

Push(S, '['); break;

case '{':

Push(S, '{'); break;

case ')':

Pop(S, e);

if (e!='(') {

printf("括号不匹配\n");

return false;

}

break;

case ']':

Pop(S, e);

if (e != '[') {

printf("括号不匹配\n");

return false;

}

break;

case '}':

Pop(S, e);

if (e != '{') {

printf("括号不匹配\n");

return false;

}

break;

default:

break;

}

i++;

}

if (!StackEmpty(S)) {

printf("括号不匹配\n");

return false;

}

else {

printf("括号匹配\n");

return true;

}

}

/*

两侧铁道均为单向行驶道,火车调度站有一个用于调度的"栈道",火车调度站的入口有

n节硬座和软座车厢(分别用H和S表示等待调度)编写算法使所有的软座车厢都调整到硬座之前

*/

void Train_Arrange(char *train) {

SqStack S;

Elemtype c = '0';

char* p = train, * q = train;

while (*p) {

if (*p == 'H') {

Push(S, *p);

}

else {

*(q++) = *p;

}

p++;

}

while (!StackEmpty(S)) {

Pop(S, c);

*(q++) = c;

}

}

//利用一个栈实现递归函数的非递归运算(好像有点晦涩)

double p(int n, double x) {

struct stack {

int no;

double val;

}st[MaxSize];

//top为栈的下标值

int top = -1, i;

//n=0,n=1时的初值

double fv1 = 1, fv2 = 2 * x;

for (i = n; i >= 2; i--) {

top++;

st[top].no = i;

}

while (top>=0) {

st[top].val = 2 * x * fv2 - 2 * (st[top].no - 1) * fv1;

fv1 = fv2;

fv2 = st[top].val;

top--;

}

if (n==0) {

return fv1;

}

return fv2;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值