1,设计一个算法利用顺序栈的基本运算判断一个字符串是否是回文
解题思路:
      由于回文是从前到后和从后到前读都是一样的,所以只要将待判断的字符串颠倒
然后与原字符串相比较,就可以决定是否是回文了

#include<stdio.h>
#include<stdlib.h>
#define MaxSize 100 //顺序栈的初始分配大小
typedef struct SqStack {
char data[MaxSize];//保存栈中元素
int top;//栈中指针
}SqStack; //声明初始化方法
void initStack(SqStack &st);
//声明压栈方法
int Push(SqStack &st, char x);
//声明出栈方法
int Pop(SqStack &st, char &x);
//判断是否为空
int StackEmpty(SqStack st);
//声明判断是否是回文的方法
int isPalindrome(char str[]);
int main() {
char str[] = "abcdcba";
printf("是否是回文?1(是):0(不是)= %d \n", isPalindrome(str));
return ;
}
//实现方法
//初始化
void initStack(SqStack &st) {//st为引用型参数
st.top = -;
}
//压栈
int Push(SqStack &st, char x) {
if (st.top==MaxSize-) {//栈满,上溢出,返回0
return ;
}
else {
st.top++;
st.data[st.top] = x;
return ;//成功进栈返回1
}
}
//出栈
int Pop(SqStack &st, char &x) { //x为引用型参数
if (st.top == -) {
return ;
}
else {
x = st.data[st.top];
st.top--;
return ;//成功出栈返回1
}
} //判断是否为空
int StackEmpty(SqStack st) {
if (st.top == -)return ;
else return ;
} //判定一个给定字符串str是否是回文,是返回1 不是返回0
int isPalindrome(char str[]) {
SqStack st;//定义一个顺序栈st
initStack(st);//栈初始化
int i = ;
char ch;
while ((ch=str[i++])!='\0') //所有字符串一次进栈
Push(st,ch);
i = ;//从头开始遍历str while (!StackEmpty(st)) {
Pop(st,ch);
if (ch!=str[i++]) {//两字符不相同时返回0
//销毁栈返回0
return ;
}
}
return ;//所有字符都相同返回1
}

例2:设计一个算法,判断一个可能包含有小括号(“(”,“)”),中括号(“[”,“]”),大括号(“{”,“}”)的表达式中各类括号是否匹配,若匹配返回1,不匹配返回0
     解题思路:

设置一个栈st(使用字符数组存放栈中元素,再用一个整型变量top 作为栈顶指针)用i扫描表达式,忽略非括号字符,当遇到左括号“(”,”[","{",时,将其入栈,
遇到 } ] )时,判断栈顶是否相匹配的括号,若不是退出扫描,返回0,负责扫描完毕,若栈空则返回1,否则返回0;

#include <stdio.h>
#define MaxSize 100
int match(char *exps) //exps存放表达式
{ char st[MaxSize];
int nomatch=,top=-,i=;
while (exps[i]!='\0' && nomatch==)//遍历表达式exps
{ switch(exps[i])
{
case '(': case '[': case '{': //左括号进栈
top++;st[top]=exps[i];break;
case ')': //判断栈顶是否为'('
if (st[top]=='(') top--;
else nomatch=;
break;
case ']': //判断栈顶是否为'['
if (st[top]=='[') top--;
else nomatch=;
break;
case '}': //判断栈顶是否为'{'
if (st[top]=='{') top--;
else nomatch=;
break;
default: //跳过其他字符
break;
}
i++;
}
if (nomatch== && top==-) //栈空且符号匹配则返回1
return ;
else
return ; //否则返回0
}
void main()
{
char str1[]="[(])";
char str2[]="[()]";
char str3[]="[()])";
char str4[]="([()]";
printf("判断结果如下:\n");
if (match(str1))
printf(" %s是匹配的表达式\n",str1);
else
printf(" %s不是匹配的表达式\n",str1);
if (match(str2))
printf(" %s是匹配的表达式\n",str2);
else
printf(" %s不是匹配的表达式\n",str2);
if (match(str3))
printf(" %s是匹配的表达式\n",str3);
else
printf(" %s不是匹配的表达式\n",str3);
if (match(str4))
printf(" %s是匹配的表达式\n",str4);
else
printf(" %s不是匹配的表达式\n",str4); }

例3:设计一个算法,将一个十进制正整数转换为相应的二进制数;

解题思路:

将十进制数转化为2进制数,通常才用除2取余法,在转换过程中,二进制数是从低位到高位的次序得到的,这和通常的从高位到低位输出相反,

为此设计一个栈,用于暂时存放每次得到的余数,当转换过程结束时,退栈所有元素便得到从高位到低位的二进制数,如下演示:

实现:

#include <stdio.h>
#define MaxSize 100
void trans(int d, char b[]) //b用于存放d转换成的二进制数的字符串
{
char st[MaxSize], ch;
int i = , top = -; //栈顶指针top初始为-1
while (d != )
{
ch = '' + d % ; //求余数并转换为字符
top++; st[top] = ch; //字符ch进栈
d /= ; //继续求更高位
}
while (top != -)
{
b[i] = st[top];
top--; //出栈并存放在数组b中
i++;
}
b[i] = '\0'; //加入字符串结束标志
} void main()
{
int d;
char str[MaxSize];
do
{
printf("输入一个正整数:");
scanf("%d", &d);
} while (d<);
trans(d, str);
printf("对应的二进制数:%s\n", str); }

在较复杂的数据处理中,通常需要保存多个需要临时产生的数据,如果先产生的数据先处理,那么需要用队列来处理这些数据;

综合:设计一个算法,反映病人到医院看病,排队看医生的过程:

描述:病人排队看医生,采用先到先看的方式,所以要用到队列,由于病人人数具有较大的不确定性,这里采用一个带头结点的单链表作为队列的存储结构,为了简单,

病人通过其姓名来唯一标识,如下病人队列:

实现如下:

#include <stdio.h>
#include <malloc.h>
#include <string.h>
typedef struct Lnode
{ char data[]; //存放患者姓名
struct Lnode *next; //指针域
} QType; //链队结点类型
typedef struct
{ QType *front; //指向队头病人结点
QType *rear; //指向队尾病人结点
} LQueue; //病人链队类型
//---初始化队列运算算法---
void InitQueue(LQueue *&lq)
{ lq=(LQueue *)malloc(sizeof(LQueue));
lq->rear=lq->front=NULL; //初始时队头和队尾指针均为空
}
//----销毁链队----
void DestroyQueue(LQueue *&lq)
{ QType *pre=lq->front,*p;
if (pre!=NULL) //非空队的情况
{ if (pre==lq->rear) //只有一个数据结点的情况
free(pre); //释放*pre结点
else //有两个或多个数据结点的情况
{ p=pre->next;
while (p!=NULL)
{ free(pre); //释放*pre结点
pre=p; p=p->next; //pre、p同步后移
}
free(pre); //释放尾结点
}
free(lq); //释放链队结点
}
}
//----进队运算算法----
void EnQueue(LQueue *&lq,char x[])
{ QType *s;
s=(QType *)malloc(sizeof(QType)); //创建新结点,插入到链队的末尾
strcpy(s->data,x);s->next=NULL;
if (lq->front==NULL) //原队为空队的情况
lq->rear=lq->front=s; //front和rear均指向*s结点
else //原队不为空队的情况
{ lq->rear->next=s; //将*s链到队尾
lq->rear=s; //rear指向它
}
}
//-----出队运算算法-----
int DeQueue(LQueue *&lq,char x[])
{ QType *p;
if (lq->front==NULL) //原队为空队的情况
return ;
p=lq->front; //p指向队头结点
strcpy(x,p->data); //取队头元素值
if (lq->rear==lq->front) //若原队列中只有一个结点,删除后队列变空
lq->rear=lq->front=NULL;
else //原队有两个或以上结点的情况
lq->front=lq->front->next;
free(p);
return ;
}
//----判断队空运算算法----
int QueueEmpty(LQueue *lq)
{ if (lq->front==NULL) return ; //队空返回1
else return ; //队不空返回0
}
//----输出队中所有元素的算法----
int DispQueue(LQueue *lq)
{ QType *p;
if (QueueEmpty(lq)) //队空返回0
return ;
else
{ p=lq->front;
while (p!=NULL)
{ printf("%s ",p->data);
p=p->next;
}
printf("\n");
return ; //队不空返回1
}
} void main()
{ int sel,flag=;
LQueue *lq;
char name[];
InitQueue(lq); //初始化病人队列
while (flag==) //未下班时循环执行
{ printf("1:排队 2:看医生 3:查看排队 0:下班 请选择:");
scanf("%d",&sel); //选择一项操作
switch(sel)
{
case : //医生下班
if (!QueueEmpty(lq))
printf(" >>请排队的患者明天就医\n");
DestroyQueue(lq);
flag=;
break;
case : //一个病人排队
printf(" >>输入患者姓名:");
scanf("%s",name);
EnQueue(lq,name);
break;
case : //一个病人看医生
if (!DeQueue(lq,name))
printf(" >>没有排队的患者\n");
else
printf(" >>患者%s看医生\n",name);
break;
case : //查看目前病人排队情况
printf(" >>排队患者:");
if (!DispQueue(lq))
printf(" >>没有排队的患者\n");
break;
}
}
}

算法学习day01 栈和队列的更多相关文章

  1. JavaScript中的算法之美——栈、队列、表

    序 最近花了比较多的时间来学习前端的知识,在这个期间也看到了很多的优秀的文章,其中Aaron可能在这个算法方面算是我的启蒙,在此衷心感谢Aaron的付出和奉献,同时自己也会坚定的走前人这种无私奉献的分 ...

  2. python数据结构与算法第六天【栈与队列】

    1.栈和队列的原理 栈:后进先出(LIFO),可以使用顺序表和链表实现 队列:先进先出(FIFO),可以使用顺序表和链表实现 2.栈的实现(使用顺序表实现) #!/usr/bin/env python ...

  3. C语言数据结构基础学习笔记——栈和队列

    之前我们学过了普通的线性表,接下来我们来了解一下两种特殊的线性表——栈和队列. 栈是只允许在一端进行插入或删除的线性表. 栈的顺序存储结构也叫作顺序栈,对于栈顶指针top,当栈为空栈时,top=-1: ...

  4. 【数据结构与算法】001—栈与队列(Python)

    栈与队列 1.栈(stacks)是一种只能通过访问其一端来实现数据存储与检索的线性数据结构,具有后进先出(last in first out,LIFO)的特征 2.队列(queue)是一种具有先进先出 ...

  5. 数据结构和算法(Java版)快速学习(栈与队列)

    栈是仅允许在表尾进行插入和删除操作的线性表.我们把允许插入和删除的一端称为栈顶(top),另一端称为栈底(bottom).栈是一种后进先出(Last In First Out)的线性表,简称(LIFO ...

  6. DS博客作业03—栈和队列

    1.本周学习总结 本周学习了栈和队列两种数据结构,分别对应后进先出,先进先出两种数据操作 学会栈的特殊类型-共享栈,队列的特殊类型-循环队列的一系列操作 学会熟练使用栈和队列的STL容器,使代码简洁 ...

  7. 20162322 朱娅霖 作业005&006 栈,队列

    20162322 2017-2018-1 <程序设计与数据结构>第五.六周学习总结 教材学习内容总结 集合的介绍(总述) 集合是收集并组织其他对象的对象.主要分为线性集合(集合中的元素排成 ...

  8. 3-6-汉诺塔(Hanoi Tower)问题-栈和队列-第3章-《数据结构》课本源码-严蔚敏吴伟民版

    课本源码部分 第3章  栈和队列 - 汉诺塔(Hanoi Tower)问题 ——<数据结构>-严蔚敏.吴伟民版        源码使用说明  链接☛☛☛ <数据结构-C语言版> ...

  9. Java数据结构和算法 - 栈和队列

    Q: 栈.队列与数组的区别? A: 本篇主要涉及三种数据存储类型:栈.队列和优先级队列,它与数组主要有如下三个区别: A: (一)程序员工具 数组和其他的结构(栈.队列.链表.树等等)都适用于数据库应 ...

随机推荐

  1. 如何调用.so动态库中的函数,如何把自己的函数导出为.so的动态库函数供别人调用

    调用.so中的函数和平常的函数没有区别,只是在编译连接时加上-lxxxx就行了.要生成.so库,则编译时用下面的语句:gcc -shared -Wl,-soname,libmyfun.so -o li ...

  2. vim考场配置

    syntax on set number set mouse=a set autoread set showmatch set autoindent set smartindent set tabst ...

  3. Java:String,int相互转化

    int转String int a: a + “”    String.valueOf(a)    Interger.toString(a)    一般使用以上几种方法进行转化 第一种方法效率不好,ja ...

  4. 浅谈C++ STL deque 容器

    浅谈C++ STL deque 容器 本篇随笔简单介绍一下\(C++STL\)中\(deque\)容器的使用方法及常见使用技巧. deque容器的概念 \(deque\)的意义是:双端队列.队列是我们 ...

  5. springboot中Thymeleaf和Freemarker模板引擎的区别

    前言这两个都是属于模板引擎,但是各有各的好处,enn,在市面上比较多的也就是jsp.freemarker.velocity.thymeleaf等页面方案.Thymeleaf和Freemarker的区别 ...

  6. 第一行代码 Android (郭霖 著)

    https://github.com/guolindev/booksource 第1章 开始启程----你的第一行Android代码 (已看) 第2章 先从看得到的入手----探究活动 (已看) 第3 ...

  7. 震惊!CCF改名为中国沙雕化学学会!!!

    震惊!中国沙雕计算机学会要改名中国沙雕化学学会??? Ak元素 据传,CCF,发现了一种新元素,元素符号暂命名为为Ak,中文名称暂未命名,据说是第250号元素. Ak 元素的发现 珂学家在一个叫洛谷的 ...

  8. PMP图表(必背)

  9. Wireshark使用入门

    目录 1. Wireshark介绍 1.1 客户端界面 1.2 Display Filter 的常用方法 1.3 界面上一些小TIPS 2. 使用Wireshark分析TCP三次握手过程 2.1 三次 ...

  10. LeetCode 206:反转链表 Reverse Linked List

    反转一个单链表. Reverse a singly linked list. 示例: 输入: 1->2->3->4->5->NULL 输出: 5->4->3- ...