目录
栈
顺序栈
//顺序栈,用数组存储的栈。
/*
标准:
1.定义加基本操作,判空,判满,进栈,出栈。
2.top指针(伪指针,就是一个int变量)一般有俩种,一个指向栈顶元素,初始化为-1(本次使用这个)
一个指向栈顶元素的下一个位置,初始化为0.
*/
#include<stdio.h>
#include<malloc.h>
#define maxSize 50
typedef struct{
int value;
}ElemType;
//一般ElemType就是int,直接写就行,这是用户所操作的最底层,其他均封装起来
typedef struct{
ElemType data[maxSize];
int top;//栈顶指针指向栈顶元素
}Stack;
bool InitStack(Stack &s){
s.top=-1;
return true;
}
bool StackEmpty(Stack s){
return s.top==-1;
}
bool StackFull(Stack s){
return s.top==maxSize-1;
}
bool push(Stack &s,ElemType x){
if(StackFull(s)) return false;
s.data[++s.top]=x;
return true;
}
bool pop(Stack &s,ElemType &x){ //&x是为了x接受输出
if(StackEmpty(s)) return false;
x=s.data[s.top--];
return true;
}
单链栈
//单链栈。
/*
标准:
1.定义加基本操作,判空,进栈,出栈。
2.栈顶在链头,入栈出栈均在链头。
3.采用带头结点单链表,故不需要再来一个top指针了。
*/
#include<stdio.h>
#include<malloc.h>
typedef struct{
int value;
}ElemType;
//一般ElemType就是int,直接写就行,这是用户所操作的最底层,其他均封装起来
typedef struct SNode{
ElemType data;
SNode *next;
}SNode,*Stack; //这个就是简洁表示,要是更规范点可以再定义个Stack结构体。
bool InitStack(Stack &s){
SNode *p=(SNode*)malloc(sizeof(SNode));//头结点
p->next=NULL;
s=p;
return true;
}
bool StackEmpty(Stack s){
return s->next==NULL;
}
bool push(Stack &s,ElemType x){
SNode *p=(SNode *)malloc(sizeof(SNode));//插入结点
p->data=x;
p->next=s->next;
s->next=p;
return true;
}
bool pop(Stack &s,ElemType &x){ //&x是为了x接受输出
if(StackEmpty(s)) return false;
SNode *p=s->next;
x=p->data;
s->next=p->next;
free(p);
return true;
}
双链栈
//双向链栈
/*
标准:
1.定义加基本操作,判空,进栈,出栈。
2.栈顶在链尾,需要维持一个top指针指向链尾。
3.采用带头结点双链表。
*/
#include<stdio.h>
#include<malloc.h>
typedef struct{
int value;
}ElemType;
//一般ElemType就是int,直接写就行,这是用户所操作的最底层,其他均封装起来
typedef struct SNode{
ElemType data;
SNode *pior,*next;
}SNode;
//规范表示,重新定义个结构体Stack:
typedef struct {
SNode *head,*top;//head头结点,top栈顶在链尾
}*Stack;
bool InitStack(Stack &s){
s=(Stack)malloc(sizeof(Stack));//分配栈空间
SNode *p=(SNode*)malloc(sizeof(SNode));//分配头结点空间
p->pior=NULL;//头结点赋值
p->next=NULL;//头结点赋值
s->head=p;
s->top=p;
return true;
}
bool StackEmpty(Stack s){
return s->head==s->top;
}
bool push(Stack &s,ElemType x){
SNode *p=(SNode *)malloc(sizeof(SNode));//插入结点
p->data=x;
p->next=NULL;
p->pior=s->top;
s->top->next=p;//这句别忘了,仔细点
s->top=p;
return true;
}
bool pop(Stack &s,ElemType &x){ //&x是为了x接受输出
if(StackEmpty(s)) return false;
SNode *p=s->top;
x=p->data;
s->top=s->top->pior;
s->top->next=NULL;
free(p);
return true;
}
测试上述栈结构
#include<stdio.h>
#include<malloc.h>
//#include "_1SequenceStack.h"//test1
//#include "_2SingleListStack.h"//test2
#include "_3DoubleDirListStack.h"//test3
//test,实际考试就这么写,定义Stack,init,然后就可以用几个方法
//StackEmpty,StackFull,Push,Pop,GetTop
//可见单链栈和顺序栈的测试一模一样,这是因为封装了具体实现,
//在做数据结构大题的时候,也不用管是怎么样实现的,只用使用即可。
int main(){
Stack s;
InitStack(s);
if (StackEmpty(s)) printf("empty\n");
else printf("not empty");
for (int i = 0; i < 100; i++)
{
ElemType a;
a.value=i;
if(push(s,a)) printf("%d 进栈成功\n",a.value);
else printf("%d 进栈失败\n",a.value);
}
for (int i = 0; i < 6; i++)
{
ElemType a;
if(pop(s,a)) printf("%d出栈\n",a.value);
else printf("出栈失败");
}
}
栈应用-括号匹配
//括号匹配
/*
1.从左往右遍历表达式中括号元素:
若当前括号元素是左括号则将其入栈
若当前括号元素是右括号,则弹出栈顶元素,与当前元素匹配。
若匹配则继续遍历,若不匹配则字符串匹配失败
2.遍历完成后,若栈空则匹配成功,若栈非空则匹配失败
*/
#include<stdio.h>
#include<malloc.h>
#include<string.h>
#include "_1SequenceStack.h"
bool Match(char *s){
Stack signStack;//
InitStack(signStack);
for (int i = 0; i < strlen(s); i++){
//考试时候不用写这俩步,这地方写是因为为了运行,就是因为栈实现写的还不够完美(要支持泛型)
ElemType elem;
elem.value=s[i];
//考试直接从这开始
if(s[i]=='(' || s[i]=='[') push(signStack,elem);
if(s[i]==')'){
pop(signStack,elem);
if (elem.value!='(') return false;
}
if(s[i]==']'){
pop(signStack,elem);
if (elem.value!='[') return false;
}
}
if (StackEmpty(signStack)) return true;
return false;
}
int main(){
char s[50]="(2+3)*4-[5*(2-3)]*2";
//scanf("%s",s);//给出字符串
if(Match(s)) printf("匹配成功");
else printf("匹配失败");
}
队列
循环队列(数组)
//循环队列,用数组实现。
/*
标准:
1.入队操作在队尾进行,只改变rear。出队操作在队头进行,只改变front。
2.front,rear指向各个教材都不太一样,大致有三种情况
front=0,rear=0 front指向队头元素,rear指向队尾元素的下一个位置(常见)==》本次的定义
front=-1,rear=-1 front指向队头元素的前一个位置,rear指向队尾元素(常见)
front=0, rear=-1 front指向队头元素,rear指向队尾元素(是因为判断不像前面俩个那么简单,稍微复杂点)
3.解决循环队列的队空队满判断,共有三种办法
空出一个位置,常用。==》本次使用这个
增加size标志,easy
增加tag标志,每次入队tag=1,只会队满,每次出队tag=0,只会队空
*/
#include<stdio.h>
#include<malloc.h>
#define maxSize 5
typedef struct{
int value;
}ElemType;
typedef struct {
ElemType data[maxSize];
int front,rear;
}Queue;
bool InitQueue(Queue &q){
q.front=0;//指向对头元素
q.rear=0;//指向队尾元素的下一个位置
return true;
}
bool QueueEmpty(Queue q){
return q.front==q.rear;
}
bool QueueFull(Queue q){
return (q.rear+1)%maxSize==q.front;
}
int QueueLength(Queue q){
return (q.rear+maxSize-q.front)%maxSize;
}
bool EnQueue(Queue &q,ElemType x){
if (QueueFull(q)) return false;
q.data[q.rear]=x;
q.rear=(q.rear+1)%maxSize;//只改变rear
return true;
}
bool DeQueue(Queue &q,ElemType &x){
if (QueueEmpty(q)) return false;
x=q.data[q.front];
q.front=(q.front+1)%maxSize;
return true;
}
链表队列(链表)
//用单链表实现的队列
/*
标准:
1.入队在链尾,需要维持一个队尾指针。
2.出队在链头,使用带头结点的单链表,自动有一个队头指针。
总结:头删尾插。
*/
#include<stdio.h>
#include<malloc.h>
typedef struct{
int value;
}ElemType;
//一般ElemType就是int,直接写就行,这是用户所操作的最底层,其他均封装起来
typedef struct QNode{
ElemType data;
QNode *next;
}QNode;
typedef struct {
QNode *head,*rear;//head指向头结点,rear队尾指针。
}*Queue;
bool InitQueue(Queue &q){
QNode *p=(QNode *)malloc(sizeof(QNode));
p->next=NULL;
q=(Queue)malloc(sizeof(Queue));
q->head=p;
q->rear=p;
return true;
}
bool QueueEmpty(Queue q){
return q->head==q->rear;
}
bool EnQueue(Queue &q,ElemType x){
QNode *p=(QNode*)malloc(sizeof(QNode));
p->data=x;
p->next=NULL;
q->rear->next=p;
q->rear=p;
return true;
}
bool DeQueue(Queue &q,ElemType &x){
if (QueueEmpty(q)) return false;
QNode *p=q->head->next;
x=p->data;
q->head->next=p->next;
if(q->rear==p) q->rear=q->head;//这句话容易忘,如果只有一个元素记得改rear。
free(p);
return true;
}
测试上述队列结构
#include<stdio.h>
#include<malloc.h>
//#include "_5CircleQueue.h"
#include "_6ListQueue.h"
int main(){
Queue q;
InitQueue(q);
for (int i = 0; i < 10; i++)
{
ElemType x;
x.value=i;
if (EnQueue(q,x)) printf("%d入队成功\n",x.value);
else printf("%d入队失败\n",x.value);
}
for (int i = 0; i < 10; i++)
{
ElemType x;
if (DeQueue(q,x)) printf("%d出队成功\n",x.value);
else printf("%d出队失败\n",x.value);
}
}