快速解析 栈和队列

来源:互联网 发布:昆医教务网络管理系统 编辑:程序博客网 时间:2024/06/06 15:43



栈:
    定义:
        后进先出的线性表,只能在表尾进行删除和插入操作
        ——表尾:栈顶(top), 表头:栈底(bottom)

    栈的顺序存储结构:
        
  1. typedef struct{
  2. ElemType *base;
  3. ElemType *top;
  4. int stackSize;
  5. }sqStack;

    其中,base 是指向栈底的指针变量,top 是指向栈顶的指针变量, stackSize 指示栈的当前可使用的最大容量
 
     创建栈:
        
  1. #define STACK_INIT_SIZE 100
  2. initStack(sqStack *s)
  3. {
  4. s -> base = (ElemType *)malloc(STACK_INIT_SIZE * sizeof(ElemType));
  5. if(!s -> base)
  6. exit(0);
  7. s -> top = s -> base;
  8. s -> stackSize = STACK_INIT_SIZE;
  9. }

    压栈操作:
  1. #define STACKINCREMENT 10
  2. Push(sqStack *s, ElemType e)
  3. {
  4. if( s-> top - s -> base >= s -> stackSize)
  5. {
  6. s -> base = (ElemType *)realloc(s -> base, (s -> stackSize + STACKINCREMENT) * sizeof(ElemType));
  7. if(!s -> base)
  8. exit(0);
  9. s -> top = s -> base + s -> stackSize;
  10. s -> stackSize = s -> stackSize + STACKINCREMENT;
  11. }
  12. *(s -> top) = e;
  13. s -> top ++;
  14. }

    出栈操作:
  1. Pop(sqStack *s, ElemType *e)
  2. {
  3. if(s -> top == s -> base) //栈空
  4. return ;
  5. *e = *--(s -> top);
  6. }

    清空栈:
         只要将 s -> top 的内容赋值为 s -> base 即可,就表明这个栈是空的了。
  1. ClearStack(sqStack *s)
  2. {
  3. s -> top = s -> base;
  4. }

    销毁栈:

  1. DestroyStack(sqStack *s)
  2. {
  3. int i, len;
  4. len = s -> stackSize;
  5. for(i = 0; i < len; i++){
  6. free(s -> base);
  7. s -> base ++;
  8. }
  9. s -> base = s -> top = NULL;
  10. s -> stackSize = 0;
  11. }

    注意:销毁栈和清空栈不同,销毁栈是要释放掉该栈所占据的物理内存空间

    栈的链式存储结构:
 
  1. typedef struct StackNode{
  2. ElemType data; //存放栈的数据
  3. struct StackNode *next;
  4. }StackNode, *LinkStackPtr;
  5. typedef struct LinkStack{
  6. LinkStackPrt top; //top指针
  7. int count; //栈元素计数器
  8. }

 计算栈的当前容量:

  1. int StackLen(sqStack s)
  2. {
  3. return (s.top - s.base);
  4. }

队列:
    在一端进行插入操作,在另一端进行删除操作的线性表

    队列的链式存储结构: 
  1. typedef struct QNode{
  2. ElemType *data;
  3. struct QNode *next;
  4. }QNode, *QueuePrt;
  5. typedef struct{
  6. QueuePrt front, rear; //队头、尾指针
  7. }LinkQueue;

     创建队列:
  1. initQueue(LinkQueue *q)
  2. {
  3. q -> front = q -> rear = (QueuePtr)malloc(sizeof(QNode));
  4. if(!q -> front)
  5. exit(0);
  6. q -> front -> next = NULL;
  7. }

     入队列操作:
  1. InsertQueue(LinkQueue *q, ElemType e)
  2. {
  3. QueuePtr p;
  4. p = (QueuePtr)malloc(sizeof(QNode));
  5. if(p == NULL)
  6. exit(0);
  7. p -> data = e;
  8. p -> next = NULL;
  9. q -> rear -> next = p;
  10. q -> rear = p;
  11. }

    出队列操作:
  1. DeleteQueue(LinkQueue *q, ElemType *e)
  2. {
  3. QueuePtr p;
  4. if(q -> front == q -> rear)
  5. return;
  6. p = q -> front -> next;
  7. *e = p -> data;
  8. q -> front -> next = p -> next;
  9. if(q -> rear == p)
  10. q -> rear = q -> front;
  11. free(p);
  12. }

     销毁队列操作:
  1. DestoryQueue(LinkQueue *q)
  2. {
  3. while(q -> front){
  4. q -> rear = q -> front -> next;
  5. free(q -> front);
  6. q -> front = q -> rear;
  7. }
  8. }

     循环队列:
        循环队列的容量是固定的,它的队头和队尾指针都可以随着元素出入队列而发生变化,这样循环队列逻辑上就好像是一个环形存储空间。
        循环队列的尾指针 rear 将指向下一个存储单元

     定义循环队列:
  1. #define MAXSIZE 100
  2. typedef struct{
  3. ElemType *base;//用于存放内存分配基地址
  4. int front;
  5. int rear;
  6. }

    初始化循环队列:
  1. initQueue(cycleQueue *q)
  2. {
  3. q -> base = (ElemType *)malloc(MAXSIZE *sizeof(ElemType));
  4. if(!q -> base)
  5. exit(0);
  6. q -> front = q -> rear = 0;
  7. }

     入队操作:
  1. InsertQueue(cycleQueue *q, ElemType e)
  2. {
  3. if((q -> rear + 1) % MAXSIZE == q -> front)
  4. return ;
  5. q -> base[q -> rear] = e;
  6. q -> rear = (q -> rear + 1) % MAXSIZE;
  7. }

     出队操作:
  1. DeleteQueue(cycleQueue *q, ElemType *e)
  2. {
  3. if(q -> front == q -> rear)
  4. return ;
  5. *e = q -> base[q -> front];
  6. q -> front = (q -> front + 1) % MAXSIZE;
  7. }
 

栈:
    定义:
        后进先出的线性表,只能在表尾进行删除和插入操作
        ——表尾:栈顶(top), 表头:栈底(bottom)

    栈的顺序存储结构:
        
  1. typedef struct{
  2. ElemType *base;
  3. ElemType *top;
  4. int stackSize;
  5. }sqStack;

    其中,base 是指向栈底的指针变量,top 是指向栈顶的指针变量, stackSize 指示栈的当前可使用的最大容量
 
     创建栈:
        
  1. #define STACK_INIT_SIZE 100
  2. initStack(sqStack *s)
  3. {
  4. s -> base = (ElemType *)malloc(STACK_INIT_SIZE * sizeof(ElemType));
  5. if(!s -> base)
  6. exit(0);
  7. s -> top = s -> base;
  8. s -> stackSize = STACK_INIT_SIZE;
  9. }

    压栈操作:
  1. #define STACKINCREMENT 10
  2. Push(sqStack *s, ElemType e)
  3. {
  4. if( s-> top - s -> base >= s -> stackSize)
  5. {
  6. s -> base = (ElemType *)realloc(s -> base, (s -> stackSize + STACKINCREMENT) * sizeof(ElemType));
  7. if(!s -> base)
  8. exit(0);
  9. s -> top = s -> base + s -> stackSize;
  10. s -> stackSize = s -> stackSize + STACKINCREMENT;
  11. }
  12. *(s -> top) = e;
  13. s -> top ++;
  14. }

    出栈操作:
  1. Pop(sqStack *s, ElemType *e)
  2. {
  3. if(s -> top == s -> base) //栈空
  4. return ;
  5. *e = *--(s -> top);
  6. }

    清空栈:
         只要将 s -> top 的内容赋值为 s -> base 即可,就表明这个栈是空的了。
  1. ClearStack(sqStack *s)
  2. {
  3. s -> top = s -> base;
  4. }

    销毁栈:

  1. DestroyStack(sqStack *s)
  2. {
  3. int i, len;
  4. len = s -> stackSize;
  5. for(i = 0; i < len; i++){
  6. free(s -> base);
  7. s -> base ++;
  8. }
  9. s -> base = s -> top = NULL;
  10. s -> stackSize = 0;
  11. }

    注意:销毁栈和清空栈不同,销毁栈是要释放掉该栈所占据的物理内存空间

    栈的链式存储结构:
 
  1. typedef struct StackNode{
  2. ElemType data; //存放栈的数据
  3. struct StackNode *next;
  4. }StackNode, *LinkStackPtr;
  5. typedef struct LinkStack{
  6. LinkStackPrt top; //top指针
  7. int count; //栈元素计数器
  8. }

 计算栈的当前容量:

  1. int StackLen(sqStack s)
  2. {
  3. return (s.top - s.base);
  4. }

队列:
    在一端进行插入操作,在另一端进行删除操作的线性表

    队列的链式存储结构: 
  1. typedef struct QNode{
  2. ElemType *data;
  3. struct QNode *next;
  4. }QNode, *QueuePrt;
  5. typedef struct{
  6. QueuePrt front, rear; //队头、尾指针
  7. }LinkQueue;

     创建队列:
  1. initQueue(LinkQueue *q)
  2. {
  3. q -> front = q -> rear = (QueuePtr)malloc(sizeof(QNode));
  4. if(!q -> front)
  5. exit(0);
  6. q -> front -> next = NULL;
  7. }

     入队列操作:
  1. InsertQueue(LinkQueue *q, ElemType e)
  2. {
  3. QueuePtr p;
  4. p = (QueuePtr)malloc(sizeof(QNode));
  5. if(p == NULL)
  6. exit(0);
  7. p -> data = e;
  8. p -> next = NULL;
  9. q -> rear -> next = p;
  10. q -> rear = p;
  11. }

    出队列操作:
  1. DeleteQueue(LinkQueue *q, ElemType *e)
  2. {
  3. QueuePtr p;
  4. if(q -> front == q -> rear)
  5. return;
  6. p = q -> front -> next;
  7. *e = p -> data;
  8. q -> front -> next = p -> next;
  9. if(q -> rear == p)
  10. q -> rear = q -> front;
  11. free(p);
  12. }

     销毁队列操作:
  1. DestoryQueue(LinkQueue *q)
  2. {
  3. while(q -> front){
  4. q -> rear = q -> front -> next;
  5. free(q -> front);
  6. q -> front = q -> rear;
  7. }
  8. }

     循环队列:
        循环队列的容量是固定的,它的队头和队尾指针都可以随着元素出入队列而发生变化,这样循环队列逻辑上就好像是一个环形存储空间。
        循环队列的尾指针 rear 将指向下一个存储单元

     定义循环队列:
  1. #define MAXSIZE 100
  2. typedef struct{
  3. ElemType *base;//用于存放内存分配基地址
  4. int front;
  5. int rear;
  6. }

    初始化循环队列:
  1. initQueue(cycleQueue *q)
  2. {
  3. q -> base = (ElemType *)malloc(MAXSIZE *sizeof(ElemType));
  4. if(!q -> base)
  5. exit(0);
  6. q -> front = q -> rear = 0;
  7. }

     入队操作:
  1. InsertQueue(cycleQueue *q, ElemType e)
  2. {
  3. if((q -> rear + 1) % MAXSIZE == q -> front)
  4. return ;
  5. q -> base[q -> rear] = e;
  6. q -> rear = (q -> rear + 1) % MAXSIZE;
  7. }

     出队操作:
  1. DeleteQueue(cycleQueue *q, ElemType *e)
  2. {
  3. if(q -> front == q -> rear)
  4. return ;
  5. *e = q -> base[q -> front];
  6. q -> front = (q -> front + 1) % MAXSIZE;
  7. }
 
0 0
原创粉丝点击