数据结构第三章栈和队列

个人笔记而已,不喜勿喷

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;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

y6y6y666

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值