个人笔记而已,不喜勿喷
1.1栈
#include <stdio.h>
#include <stdlib.h> //malloc()
// define 标识符 常量
// define 用来定义常量,结尾没有分号
#define TRUE 1 // 定义TRUE为常量1
#define FALSE 0 // 定义FALSE为常量0
#define OK 1 // 定义OK为常量1
#define ERROR 0 // 定义ERROR为常量0
#define INFEASIBLE -1 // 定义INFEASIBLE 为常量-1
#define OVERFLOW -2 // 定义OVERFLOW为常量-2
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
// 将int重命名为Status
typedef int Status;
typedef int EleXCXmType; // typedef 对int起两次名字
typedef int SElemType; // typedef 对int起两次名字
// typedef ElemType* Triplet; //对ElemType类型的指针 起名字为 Triplet
typedef struct
{
SElemType *base;
SElemType *top;
int stacksize;
} SqStack;
// 初始化栈
Status InitStack(SqStack *S)
{
S->base = (SElemType *)malloc(STACK_INIT_SIZE * sizeof(SElemType));
if (!S->base)
exit(OVERFLOW);
S->top = S->base;
S->stacksize = STACK_INIT_SIZE;
return OK;
}
// 入栈
Status Push(SqStack *S, SElemType e)
{
if (S->top - S->base >= S->stacksize)
{
S->base = (SElemType *)realloc(S->base, (S->stacksize + STACKINCREMENT) * sizeof(SElemType));
if (!S->base)
exit(OVERFLOW);
S->top = S->base + S->stacksize;
S->stacksize += STACKINCREMENT;
}
*S->top++ = e;
return OK;
}
Status Pop(SqStack *S, SElemType *e)
{
if (S->top == S->base)
return ERROR;
*e = *(--S->top);
return OK;
}
Status StackEmpty(SqStack *S)
{
if (S->top - S->base)
{
return OK;
}
else
{
return ERROR;
}
}
void conversion(int N, int n)
{
SqStack S;
// printf("%d%d",N,n);
// printf("请输入要转换的数字和进制 空格分开\n");
InitStack(&S);
// scanf("%d",&N);
while (N)
{
Push(&S, N % n);
N = N / 8;
}
while (StackEmpty(&S))
{
int e = 0;
Pop(&S, &e);
printf("%d", e);
}
}
int main()
{
printf("请输入非负十进制操作数以及要将其转换成的进制空格分开\n");
int N, n;
scanf("%d%d", &N, &n);
conversion(N, n);
}
1.2栈cpp
#include <stdio.h>
#include <stdlib.h>
typedef int ElemType;
typedef int Status;
#define OK 1
#define ERROR 0
#define OVERFLOW 0
#define TRUE 1
#define FALSE 0
#define STACK_INIT_SIZE 100 //存储空间初始分配量
#define STACK_INCREMENT 10 //存储空间分配增量
typedef char ElemType;
typedef struct{
ElemType *base; //栈底指针 //不变
ElemType *top; //栈顶指针 //变 总是指向栈顶的下一个存储位置
int stacksize; //栈空间大小 //base==top:栈空
} SqStack;
//对于顺序栈,可通过动态申请得到其存储空间,它有4个要素
//栈满条件:
//S.top-S.base>=S.stacksize
//元素e进栈操作: *(S.top)++=e
//出栈元素e e=*--S.top、
//初始化栈操作 主要操作:通过动态申请所需要的空间大小
//并且初始化相关参数
void InitStack(SqStack &S)
{
//构造一个空栈 //S.base是这段空间的首地址
if(!(S.base=(ElemType*)malloc(STACK_INIT_SIZE*sizeof(ElemType))))
exit(OVERFLOW);
S.top=S.base;
S.stacksize=STACK_INIT_SIZE;
}
//(销毁算法)
void DestroyStack(SqStack &S)
{
free(S.base);
S.base=NULL;
S.top=NULL;
S.stacksize=0;
}
//push
void Push(SqStack &S,ElemType e)
{
if(S.top-S.base>=S.stacksize)
{
S.base=(ElemType*)realloc(S.base,(S.stacksize+STACK_INCREMENT)*sizeof(ElemType));
if(!S.base)
exit(OVERFLOW);
S.top=S.base+S.stacksize;
S.stacksize+=STACK_INCREMENT;
}
*(S.top)++=e;
}
//pop
Status Pop(SqStack &S,ElemType &e)
{
//若栈不为空,则删除S的栈顶元素,用e返回其值,并返回ok
//否则返回ERROR
if(S.top==S.base)
{
return ERROR;
e=*--S.top;
return OK;
}
}
//取栈顶元素
Status GetTop(SqStack S,ElemType e)
{
//若栈不为空,则用e返回S的栈顶元素,并返回ok
//否则返回ERROR
if(S.top>S.base)
{
e=*(S.top-1);
return OK;
}
else return ERROR;
}
//判断栈空算法
Status StackEmpty(SqStack S)
{
//若栈为空栈,则返回FALSE
if(S.top==S.base)
return TRUE;
else
return FALSE;
}
1.3链栈
#include <stdio.h>
#include <stdlib.h>
typedef int ElemType;
typedef int Status;
#define OK 1
#define ERROR 0
#define OVERFLOW 0
#define TRUE 1
#define FALSE 0
#define STACK_INIT_SIZE 100 //存储空间初始分配量
#define STACK_INCREMENT 10 //存储空间分配增量
typedef char ElemType;
typedef struct node{
ElemType data;
struct node *next;
} LinkStack;
//链栈没有头结点 //单链表
//归纳起来,链栈top=NULL,其4个要素如下
//栈空条件:top==NULL
//栈满条件:不考虑
//元素x进栈操作:创建存放元素x的结点p,将其插入到栈顶位置上
//出栈元素x操作:置x为栈顶结点的data域,并删除该节点
//top指向最上边的一个元素
//初始化链栈操作
//主要操作:用top==NULL标识为空栈
void InitStack(LinkStack *&top)
{
top=NULL;
}
//(销毁栈算法)
void DestroyStack(LinkStack *&top)
{
LinkStack *pre=top,*p;
if(pre==NULL) //空栈
return;
p=pre->next;
while(p!=NULL)
{
free(pre); //释放pre结点
pre=p;
p=p->next; //pre、p同步后移
}
free(pre); //释放尾节点
}
//(3)进栈操作
//主要操作:先创建一个新节点,其data域值为x,然后将该节点插入到top结点之后
//作为栈顶结点
int Push(LinkStack *&top,ElemType x)
{
LinkStack *p;
p=(LinkStack *)malloc(sizeof(LinkStack));
p->data=x; //创建结点p用于存放x
p->next=top; //插入p结点作为栈顶结点
top=p;
return 1;
}
//(4)出栈操作
int Pop(LinkStack *&top,ElemType &x )
{
LinkStack *p;
if(top==NULL){ //栈空
return 0;
}
else{ //栈不空
p=top; //p指向栈顶结点
x=p->data; //取栈顶元素x
top=p->next; //删除结点p
free(p); //释放结点p
return 1;
}
}
//取栈顶
int GetTop(LinkStack *top,ElemType &x)
{
if(top==NULL) //栈空,夏溢出时返回0
return 0;
else
{
x=top->data;
return 1;
}
}
//(6)判断栈空
int StackElempty(LinkStack *top)
{
if(top==NULL)
{
return 1;
}
else
return 0;
}
#include "stack.cpp"
int Judge(char str[], int n)
{
int i;
ElemType x;
SqStack st;
InitStack(st);
for (int i = 0; i < n; i++)
{
if (str[i] == 'I')
{
Push(st, str[i]);
}
else if (str[i] == 'O')
if (!Pop(st, x))
{
DestroyStack(st);
return 0;
}
}
if (StackEmpty(st))
{
DestroyStack(st);
return 1;
}
else
{
DestroyStack(st);
return 0;
}
}
// 回文
int Palindrome(char str[], int n)
{
SqStack st;
InitStack(st);
int i;
char ch;
for (i = 0; i < n; i++)
{
Push(st, str[i]);
}
i = 0;
while (!StackEmpty(st))
{
Pop(st, ch);
if (ch != str[i++])
return 0;
}
return 1;
}
#include "Stack.cpp"
int Match(char exp[], int n) // exp存放表达式式子
{
SqStack st; // 栈初始化
InitStack(st);
int flag = 1, i = 0;
char ch;
while (i < n && flag == 1) // 遍历表达式exp
{
switch (exp[i])
{
case '(':
case '[':
case '{':
Push(st, exp[i]);
break;
case ')':
if (!Pop(st, ch) || ch != '(')
flag = 0;
break;
case ']':
if(!Pop(st,ch)||ch!='[')
flag=0;
break;
case '}':
if(!Pop(st,ch)||ch!='{')
flag=0;
break;
}
i++;
}
if(StackEmpty(st)&&flag==1)
{
return 1;
}
else
{
return 0;
}
}
2.1队列cpp
#include <stdio.h>
#include <stdlib.h>
typedef int ElemType;
typedef int Status;
#define OK 1
#define ERROR 0
#define OVERFLOW 0
#define TRUE 1
#define FALSE 0
#define STACK_INIT_SIZE 100 // 存储空间初始分配量
#define STACK_INCREMENT 10 // 存储空间分配增量
typedef int QElemeType;
// 列队头指针始终指向第一个元素,列队尾指针始终指向最后一个元素的下一个位置
// 队列的静态存储结构
#define MaxSize 20 // 队列元素
// typedef struct
// {
// ElemType data[MaxSize]; // 指定容量
// int front, rear; // 队头和队尾指针
// } SqQueue;
typedef struct
{
ElemType* base; // 初始化的动态分配存储空间
int front; // 头指针,若队列不空,指向队列头元素
int rear; // 尾指针,若队列不空,指向队列尾元素下一个元素
} SqQueue;
void InitQueue(SqQueue &Q);
void DestroyQueue(SqQueue &Q);
Status EnQueue(SqQueue &Q, QElemeType e);
Status DeQueue(SqQueue &Q, QElemeType &e);
Status GetHead(SqQueue Q, QElemeType &e);
Status QueueEmpty(SqQueue Q);
// 循环队列
// 空Q.front==Q.rear
// 满:(Q.rear+1)%MaxSize==Q.front
// 进队:Q.data[Q.rear]=x; Q.rear=(Q.rear+1)%MaxSize;
// 出:x=Q.data[Q.front];Q.front=(Q.front+1)%MaxSize;
// 循环队列:
#define MAXQSIZE 100
int main()
{
SqQueue Q;
InitQueue(Q);
EnQueue(Q,6);
int e;
DeQueue(Q,e);
printf("%d",e);
DestroyQueue(Q);
return 0;
}
// (1)初始化
// sq.front=sq.rear=0
void InitQueue(SqQueue &Q)
{
// 构造一个空队列Q
Q.base = (QElemeType *)malloc(MAXQSIZE * sizeof(QElemeType));
if (!Q.base) // 储存分配失败
exit(OVERFLOW);
Q.front = Q.rear = 0;
}
// 销毁队列
void DestroyQueue(SqQueue &Q)
{
// 销毁队列Q,Q不再存在
if (Q.base)
free(Q.base);
Q.base = NULL;
Q.front = Q.rear = 0;
}
// 入队列算法
// 主要操作是:先判断队列是否已满,若不满,在队尾指针位置存放x、
// ,然后循环加1.
Status EnQueue(SqQueue &Q, QElemeType e)
{
// 插入元素e为Q的新的队尾元素
if ((Q.rear + 1) % MAXQSIZE == Q.front) // 队列满
return ERROR;
Q.base[Q.rear] = e;
Q.rear = (Q.rear + 1) % MAXQSIZE;
return OK;
}
// 出队
// 主要操作:先判断队列是否为空,若不为空,将队头指针位置的元素赋值给x,然后对头指针循环+1
Status DeQueue(SqQueue &Q, QElemeType &e)
{
// 若队列不为空,则删除Q的队头元素,用e返回其值
// 并返回OK,否则返回ERROR
if (Q.front == Q.rear) // 队列空
return ERROR;
e = Q.base[Q.front];
Q.front = (Q.front + 1) % MAXQSIZE;
return OK;
}
// 取队头元素运算算法
// 主要操作:先判断队列是否已经空,若不空,将队头指针钱一个位置的元素赋值为x
Status GetHead(SqQueue Q, QElemeType &e)
{
// 若队列不空,则用e反回Q的队头元素,并返回ok
// 否则返回ERROR
if (Q.front == Q.rear) // 队空
return ERROR;
e = Q.base[Q.front];
return OK;
}
// 判空
Status QueueEmpty(SqQueue Q)
{
// 若队列Q为空队列,则返回TRUE,否则返回FALSE
if (Q.front == Q.rear) // 队列空的标志
return TRUE;
else
return FALSE;
}
2.2队列题.cpp
// 对于循环队列,写出求队列中元素个数的
// 公式,并编写相应的算法。
// 队中元素个数=(rear-front+MaxSize)%MaxSize
// 解:循环队列元素个数的计算公式如下:
#include "SqQueue.cpp"
//算法
int QueueLength(SqQueue Q)
{
//返回Q元素的个数,即队列的长度
return (Q.rear-Q.front+MAXQSIZE)%MAXQSIZE;
}
// 如果用一个大小为MaxSize的环形数组表
// 示队列,该队列只有一个队头指针front,不设队尾指
// 针rear,而改置一个计数器count,用以记录队列中
// 的元素个数。
// (1)队列中最多能容纳多少个元素?
// (2)设计实现队列基本运算的算法。
//依题意,设计队列的类型如下
//=--------------静态存储结构·-----
typedef struct
{
ElemType data[MaxSize]; //存放队列中的元素
int front; //队头指针
int count; //队列中元素个数
}SqQueue;
// (1)队列中最多可容纳MaxSize个元素,因为这里不
// 需要空出一个位置以区分队列空和队列满的情况。
// (2)队列sq为空的条件是:sq.count==0;
// 队列为满的条件是:sq.count==MaxSize;
// 队尾元素的位置是:
// (sq.front+sq.count)%MaxSize。
//初始化算法
void InitQueue(SqQueue &qu)
{
qu.front=qu.count=0;
}
//-----销毁队列算法
void DestyooyQueue(SqQueue sq)
{
//静态申请的空间所以不用销毁
}
//入队列操作
int EnQueue(SqQueue &sq,ElemType x)
{
if(sq.count==MAXQSIZE) //队满
return 0;
sq.data[(sq.front+sq.count)%MaxSize]=x;
sq.count++; //队中元素个数加1
return 1;
}
//--出队列算法
int DeQueue(SqQueue &sq,ElemType &x)
{
if(sq.count==0) //队空
return 0;
x=sq.data[sq.front];
sq.front=(sq.front+1)%MaxSize;
sq.count--; //队中元素个数-1
return 1;
}
//取队头
int GetHead(SqQueue sq,ElemType &x)
{
if(sq.count==0) //队空
{
return 0;
}
x=sq.data[sq.front]; //将front所指向的值给x
return 1;
}
//判断队空
int QueueEmpty(SqQueue sq)
{
if(sq.count==0)
return 1; //队空返回1
else
return 0; //队不为空返回0
}
2.3标志队列.cpp
#include <stdio.h>
#include <stdlib.h>
typedef int ElemType;
typedef int Status;
#define OK 1
#define ERROR 0
#define OVERFLOW 0
#define TRUE 1
#define FALSE 0
#define MAX_QUEUE_SIZE 100 // 存储空间初始分配量
// #define STACK_INCREMENT 10 // 存储空间分配增量
typedef int QElemeType;
typedef struct
{
int front; // 队头指针
int rear; // 队尾指针
int size; // 队列元素个数
int tag; // 标志域tag
int data[MAX_QUEUE_SIZE]; // 队列数据
} Queue;
void initQueue(Queue *q);
int isQueueEmpty(Queue *q);
int isQueueFull(Queue *q);
void enqueue(Queue *q, int data);
int dequeue(Queue *q, int *e);
// #define AX_QUEUE_SIZE 100
int main()
{
Queue Q;
initQueue(&Q);
enqueue(&Q, 6);
int e = 0;
dequeue(&Q, &e);
printf("%d", e);
return 0;
}
void initQueue(Queue *q)
{
q->front = q->rear = q->size = 0;
q->tag = 0;
}
int isQueueEmpty(Queue *q)
{
return q->size == 0;
}
int isQueueFull(Queue *q)
{
return q->size == MAX_QUEUE_SIZE;
}
void enqueue(Queue *q, int data)
{
if (isQueueFull(q))
{
printf("Queue is full\n");
return;
}
q->data[q->rear] = data;
q->rear = (q->rear + 1) % MAX_QUEUE_SIZE; ///%(MISSING)
q->size++;
q->tag = 1; // 设置tag为1,表示队列非空
}
int dequeue(Queue *q, int *e)
{
if (isQueueEmpty(q))
{
printf("Queue is empty\n");
return -1;
}
int data = q->data[q->front];
*e = data;
q->front = (q->front + 1) % MAX_QUEUE_SIZE; //%!(MISSING)
q->size--;
if (q->size == 0)
{ // 如果队列为空
q->tag = 0; // 将tag设置为0
}
return data;
}
2.4链队列
#include <stdio.h>
#include <stdlib.h>
typedef int ElemType;
typedef int Status;
#define OK 1
#define ERROR 0
#define OVERFLOW 0
#define TRUE 1
#define FALSE 0
#define STACK_INIT_SIZE 100 // 存储空间初始分配量
#define STACK_INCREMENT 10 // 存储空间分配增量
typedef int QElemeType;
// 链队列是一个同时带有队头指针front和队尾指针rear的单链表
// 队头指针指向头结点,队尾指针·指向队尾结点,即单链表尾节点,并将对头和队尾指针结合起来构成链队节点·
// 数据节点
typedef struct QNode
{
ElemType data; // 存放队中元素
struct QNode *next; // 指向下一个结点
} QNode, *QueuePtr; // 数据节点类型
// 链队结点
typedef struct
{
QNode *front; // 队头指针
QNode *rear; // 队尾指针
} LinkQueue; // 链队节点类型
// 链队列的四个要素
//: 队空:Q.front->next==NULL
// 队满: 不考虑(因为每个节点都是动态分配的)
// 进队:创建节点,将其插入到队尾,并由Q.rear指向它
// 出队:删除对头的节点
// (1)初始化:
void InitQueue(LinkQueue &Q)
{
// 构造一个空队列Q
if (!(Q.front = Q.rear = (QueuePtr)malloc(sizeof(QNode))))
{
exit(OVERFLOW);
}
Q.front->next = NULL;
}
// 销毁
void DestroyQueue(LinkQueue &Q)
{
// 销毁队列 Q(无论空否均可)
while (Q.front)
{
Q.rear = Q.front->next;
free(Q.front);
Q.front = Q.rear;
}
}
// 入队列
void EnEueue(LinkQueue &Q, QElemeType e)
{
// 插入元素e为Q的新的队尾元素
QueuePtr p;
if (!(p = (QueuePtr)malloc(sizeof(QNode)))) // 存储分配失败
exit(OVERFLOW);
p->data = e;
p->next = NULL;
Q.rear->next = p;
Q.rear = p;
}
// 出队列*
// 主要操作:将front->next结点的data域值赋给e,并删除该节点
// 否则返回ERROR
Status DeQueue(LinkQueue &Q, QElemeType &e)
{ // 若队列不为空,删除Q的队头元素,用e返回其值,并返回OK
// 否则返回ERROR
QueuePtr p;
if (Q.front == Q.rear)
return ERROR;
p = Q.front->next;
e = p->data;
Q.front->next = p->next;
if (Q.rear == p) //***
{
Q.rear = Q.front;
}
free(p);
return OK;
}
// 取队头元素算法
// 主要操作:将队头结点的域值赋给e
Status GetHead(LinkQueue Q, QElemeType &e)
{
// 若队列不空,则用e返回Q的队头元素,并返回OK
// 否则返回ERROR
QueuePtr p;
if (Q.front == Q.rear)
{
return ERROR;
}
p = Q.front->next;
e = p->data;
return OK;
}
//(6)判空
Status QueueEmpty(LinkQueue Q)
{
// 若Q为空队列,则返回true,否则返回FALSE
if (Q.front->next == NULL)
{
return TRUE;
}
else
return FALSE;
}
// 示例
// 若使用不带头结点的循环链表来表示队列,Q是
// 这样的链表中尾结点指针。试基于此结构给出队列的入队
// 列、出队列算法。
typedef struct node
{
ElemType data; // 数据域
struct node *next; // 指针域
} QNode; // 链队数据结点类型
//----入队列算法----
void EnQueue(QNode *&Q, ElemType x)
{
QNode *s;
s = (QNode *)malloc(sizeof(QNode));
s->data = x; // 创建存放x的结点s
if (Q == NULL) // 原为空队
{
Q = s;
Q->next = Q; // 构成循环单链表
}
else // 原队不空,结点s插到队尾
{
s->next = Q->next;
Q->next = s;
Q = s; // Q指向结点s
}
}
//-----出队列算法-----
int DeQueue(QNode *&Q, ElemType &x)
{
QNode *s;
if (Q == NULL)
return 0; // 原为队空
if (Q->next == Q) // 原队只有一个结点
{
x = Q->data;
free(Q);
Q = NULL;
}
else // 原队有两个或以上的结点
{
s = Q->next; // 将Q之后的结点s删除
x = s->data;
Q->next = s->next;
free(s);
}
return 1;
}