栈和队列基础算法

  1. 以不带头结点的单链表存储栈,设计初始化栈、判断栈是否为空、进栈和出栈等相应的算法。
typedef struct LNode    {    //定义单链表结点结构
    ElemType data;
   struct LNode * next;
}LNode, *LinkStack;

Status InitStack(LinkStack &L)  {
    //初始化栈
    L = NULL;
    return OK;
}

    Status StackEmpty(LinkStack L)  {  //判断栈是否为空
        return (L==NULL);
    }

    Status EnStack(LinkStack &L, ElemType e)    {  //入栈
        p = (LNode *)malloc(sizeof(LNode));
     if (!p) exit(OVERFLOW);
       p->data = e;
       p->next = L;       
L=p;    // L指向新加入结点

return OK;  
}

Status DeStack(LinkStack &L, ElemType &e)   { //出栈,相当于将L所指的结
//点从链表上摘除
    if (L==NULL) return ERROR;   //栈空,出错
   e=L->data;
   p = L;
   L=p->next;
   free(p);        //释放L指向结点所占用的空间

   return OK;
}
  1. 假设表达式中允许包含三种括号:圆括号、方括号和大括号。编写一个算法判断表达式中的括号是否正确配对。
    算法思想:设置一个栈S,扫描表达式exp,遇到‘(’、‘[’或者‘{’,则压入栈中;若当前字符是‘)’, 弹出栈顶元素,若不是对应的‘(’, 设置标志位为“不配对”;若当前字符是‘]’, 弹出栈顶元素,若不是对应的‘[’, 设置标志位为“不配对”;若当前字符是‘}’, 弹出栈顶元素,若不是对应的‘{’, 设置标志位为“不配对”;其余情况下则继续处理后续字符。当扫描完exp,若此时栈S为空,则以括号配对返回1,否则返回0。

Status match (char *exp)    {
SqStack S;
   InitStack(S);
   char c;
   int b = 1, i = 0;  //b为标志位=1时表示括号配对
   while (exp[i] != ‘\0’ && b ==1)  { 
//遇到‘(’、‘[’或者‘{’,则压入栈中
        if (exp[i] == ‘(’ || exp[i] == ‘[’ || exp[i] == ‘{’) 
          Push(S, exp[i]);
       else if (exp[i] == ‘)’)  {   //若当前是‘)’
          if (!StackEmpty(S))   {
Pop(S, c);         //弹出栈顶元素
                if (c != ‘(’)        // 若不是对应的‘(’
                    b = 0;        //设置标志位为“不配对”
            }
            else
                b = 0;
        }
       else if (exp[i] == ‘]’)  {    //若当前是‘]’
            if (!StackEmpty(S)) {
Pop(S, c);            //弹出栈顶元素
            if (c!= ‘[’)        // 若不是对应的‘[’
                 b=0;       //设置标志位为“不配对”
            }
            else
                b = 0;              
        }
       else if (exp[i] == ‘}’)  {   //若当前是‘}’
           if (!StackEmpty(S))  {
Pop(S, c);         //弹出栈顶元素
            if (c!= ‘{’)         // 若不是对应的‘[’
                b = 0;          //设置标志位为“不配对”
            else
                b = 0;
       }
       i ++;       //继续处理下一个字符
    }// end of while
    return (b && StackEmpty(S);
}
  1. 假设用循环单链表实现循环队列,该队只使用一个队尾指针rear。请设计出相应的存储结构和如下基本运算算法。
    a) 初始化队列InitQueue(Q):建立一个新的空队列Q。
    b) 入队列Enter(Q, x):将元素x插入到队列Q中。
    c) 出队列Delete(Q, x):从队列Q中删除一个元素。
    d) 取队首元素Gethead(Q,x):返回当前的队首元素。
typedef struct LNode    {    //定义循环单链表结点结构
    ElemType data;
   struct LNode * next;
}LNode, *QueuePtr;

typedef struct{
    QueuePtr  rear;
}CircularQueue;

Status InitQueue(CircularQueue &Q)  { //初始化队列,其中只包含一个头结点
    Q.rear = (QueuePtr)malloc(sizeof(LNode));  //rear指向该头结点
   if (!Q.rear) exit(OVERFLOW);         
   Q.rear->next = Q.rear;                //该结点的链域回指自身  

   return OK;
}

   Status Enter(CircularQueue &Q, ElemType x)   {//入队,只能在链表尾插入
        p = (LNode *)malloc(sizeof(LNode)) ;
        if (!p) exit(OVERFLOW);  
       p->data = x;
        p->next = Q.rear->next;        //新结点指向原来链表中的头结点
       Q.rear->next = p;         //原来链表中的尾结点的链域指向新加入结点
       Q.rear = p;               //rear指向新加入结点

        return OK;
    }
    Status Delete(CircularQueue &Q, ElemType &x) {//出队,只能在链表头结点后
// 删除第一个结点
        if (Q.rear == Q.rear->next) return ERROR;  //队列为空,出错
       x = Q.rear->next->next->data;
       if (Q.rear == Q.rear->next->next){//原链表中除头结点外,只有一个结点
            p = Q.rear->next;           //p指向头结点
          free(p->next);              //释放掉唯一结点所占据的空间
          Q.rear = p;             //rear指向头结点
          p->next = p;         //头结点指针域回指自身
       }
       else  {
            p=Q.rear->next->next;      //p指向链表中第一个结点
          Q.rear->next->next = p->next; //修改头结点指针域,让其指向p后结点
          free(p);                   //释放p所指向的结点的空间
        }
       return OK;
    }

    Status Gethead(CircularQueue Q, ElemType &x) {// 取队首元素
        if (Q.rear == Q.rear->next) return ERROR;  //队列为空,出错
        p=Q.rear->next->next;     //p指向链表中第一个结点,即队头结点
       x = p->data;
       return OK;
   }

你可能感兴趣的:(c语言)