zoukankan      html  css  js  c++  java
  • 栈、队列

    栈和队列也都是线性表,是操作受限的特殊线性表

    栈 :先进后出

    顺序栈:假设有一个足够大的存储空间data,用于存储栈中的元素,将栈中的元素依次存储到数组中--顺序存储方式--顺序栈。其中设置一个整形变量top,指示栈顶,即栈顶元素的数组下标,也可用来计数元素个数 将数组 data和top作为顺序栈的数据成员。

    #include <iostream>
    #define MAXLEN 100
    typedef int elementType;
    //顺序栈存储定义
    typedef struct sStack{
        elementType data[MAXLEN];//定义一个足够大的数组
        int top;//指示栈顶
    }seqStack;//顺序栈定义  
    //栈初始化
    void initialStack(seqStack &s){
        s.top = -1;
    }
    
    //判断栈空
    bool stackempty(seqStack &s)
    {
        if (s.top == -1)
            return true;
        return false;
    }//简写 return(s.top == -1);
    //判断栈满
    bool stackfull(seqStack &s)
    {
        if (s.top == MAXLEN-1)
            return true;
        return false
    }
    //取栈顶元素
    bool getTop(seqStack &s,elementType &x){
        if(stackempty){
            return false;
        }
        else{
            x = s.data[s.top];
            return true;
        }
    }
    
    //入栈
    bool push(seqStack &s,elementType x){
        if (stackfull)
            return false
        else{
            s.top++;//增加栈顶 
            s.data[s.top] = x;//数据入栈
            return true;
        }
    }
    
    //出栈
    bool pop(seqStack &s, elementType &x){
        if (stackempty){
            return false
        }
        else{
            x = s.data[s.top];
            top--;
            return true;
        }
    }

     顺序栈特点:所有运算的时间复杂度均为O(1);通常一次性申请空间,只能按最大空间需求分配,容易造成空间浪费(可以使用链式栈代替顺序栈)

    链栈  采用链式存储结构实现的栈,可以用单链表结构来表示,结点结构同单链表 链栈可以带头结点,也可以不带头结点。不带头节点栈顶指针top指示首元素节点,带头结点,栈顶指针top->next指示首元素节点

    typedef int elementType;  //elementType 定义为整数类型
    
    typedef struct lsNode
    {
        elementType data;     //链栈结点数据域
        struct lsNode *next;  //链栈结点指针域
    } node,*linkedStack;
    //使后面使用node *top 或 linkedStack top都行
    
    //初始化栈 不带头结点
    void initialStack(node *&top)
    {
        top=NULL;//将栈顶指针置空
    }
    
    //判定栈空
    bool stackEmpty(node* top)
    {
        if(top==NULL)
            return true;  //栈空,返回true
        else
            return false;   //栈不空,返回false
    }
    
    //取栈顶元素
    bool getTop(node * top, elementType &x)
    {
        if(top==NULL)
            return false;  //栈空,返回false
        else
        {
            x=top->data;   //取栈顶元素,用参数x返回
            return true;   //取栈顶成功,返回true
        }
    }
    
    
    //入栈
    void push(node *& top, elementType x)
    {
        node* s;
        
        s=new node;
        s->data=x;
        s->next=top;
        top=s;
    
    }
    
    //出栈
    bool pop(node *& top, elementType &x)
    {
        node* u;
        if(top==NULL)
            return false;   //栈空,返回false
        else
        {
            x=top->data;    //取栈顶元素,由变量x返回
            u=top;          //栈顶指针保存到u
            top=top->next;  //栈顶指针后移一个元素结点
            delete u;       //释放原栈顶结点
            return true;    //出栈成功,返回true
        }
    }
    
    void destroyStack(node *& top)
    {
        node *p,*u;
        p=top;
        while(p)
        {
            u=p;
            p=p->next;
            delete(u);        
        }
        top=NULL;
    }
    
    //交互循环压入元素
    void createLinkedStack(linkedStack &top)
    {        
        elementType x;
        node *p;    
        cout<<"请输入数据元素(整数,-9999退出):"<<endl;
        cout<<"x=";
        cin>>x;
        while(x!=-9999)   //非结束符,循环入栈
        {
            p=new node;
            p->data=x;
    
            p->next=top;
            top=p;
    
            cout<<"x=";
            cin>>x;
        }
    }
    
    

     链式栈特点:使用连续或不连续的存储空间,各数据元素独立存储,依靠指针连接建立逻辑相邻关系,对每个数据元素单独申请结点空间,没有栈满溢出的情况,栈顶指针top唯一确定一个链式栈。

     逆置单链表:

    1、从原链表首元素节点依次取出放入新表即可  头插法

    void reverse(linkedStack & l)
    {
        node *p,*s;
        p = l ->next;
        l->next = NULL;
        while(p)
        {
            s = p;
            p = p->next; //利用s中转 
            s->next = l->next;
            l->next = s
        }
    
    }

     2、定义一个顺序栈,循环每个节点指针入栈,首元素节点指针在栈底,将栈内节点依次弹出按尾插法来重建链表。

    void reverse(linkedStack & l){
        SeqStack S;
        initialStack(S);
        node* p ;
        p = l->next;
        while(p){
            
            S.push(p);
            p = p->next;
        }
        l->next = NULL;
        while(!stackEmpty(S)){
            p = S.pop();
            l->next = p;
        }
        l->next = NULL
    }

     队列 也是线性表,插入和删除只能在一端进行。

     

    普通队列随着删除、插入的进行容易造成假溢出

    循环队列

    #define MAXLEN 100
    typedef int elementType;
    //根据函数接收参数的不同 引用传值还是指针传值   用.给变量赋值  -> 指针赋值
    typedef struct squeue
    {
        elementType data[MAXLEN];
        int front,rear;
    }seqQueue;
    
    void initial(seqQueue * Q)
    {
        Q->front = 0;
        Q->rear = 0;
    }
    bool isEmpty(seqQueue & Q)
    {
        if (Q.front == Q.rear)
            return true;
        return false;
    }
    bool isFull(seqQueue & Q)
    {
        if ((Q.rear+1)%MAXLEN == Q.front)
            return true;
        else 
            return false;
    }
    bool getFront(seqQueue &Q,elementType &x)
    {
        if isEmpty(Q)
            return false;
        else:
            x = Q.data[[Q.front+1] %MAXLEN]
        }
    bool enQueue(seqQueue &Q , elementType x)
    {
        if (isFull(Q))
            return false;
        else
            Q.rear = (Q.rear+1)%MAXLEN;
            Q.data[Q.rear] = x;
            return true;
    }
    bool outQueue(seqQueue &Q, elementType &x)
    {
        if (isEmpty(Q))
            return false;
        else 
            Q.front = (Q.front+1)%MAXLEN;
              x = Q.data[Q.front];
              return true;
    }

     队列的应用   杨辉三角

     

    void yanghuiTriangle(int n)
    {
        seqQueue Q;
        initial(&Q)
        int s1,s2,x;
        cout << 1<<endl;
        enQueue(&Q ,1)
        for (int i = 2; i <= n; i++)
        {
            s1 = 0;
            for (int j = 1; j <= i-1; j++)
            {
                getFront(Q,s2);
                outQueue(&Q,x);
                cout << s1+s2 <<"	";
                enQueue(&Q, s1+s2);  每次保证队列中是上一行的元素 在遍历队列依次相加 得到下一行元素
                s1 = s2;        
            }
            cout << 1<<endl;
            enQueue(&Q,1);
        }
    }

     链队列  节点结构和单链表相同,需要两个指针分别指向队头和队尾。

     

    typedef int elementType;
    typedef struct Node
    {
        elementType data;
        struct Node *next;
    }node;
    typedef struct queue
    {
        node *front;
        node *rear;    
    }linkedQueue;
    void initial(linkedQueue &Q){
        Q.front = new node;
        Q.rear = Q.front;
        Q.front->next = NULL;
    }
    bool isempty(linkedQueue &Q){
        if (Q.rear == Q.front)
            return true;
        else
            return false;
    }
    bool getFront(linkedQueue &Q,elementType &x)
    {
        if (isempty(Q))
        {
            return false;/* code */
        }
        x =( (Q.front)->next)->data;
        return true;
    }
    void enQueue(linkedQueue &Q,elementType x)
    {
        node* p = new node;
        p->data = x;
        p->next = NULL;
        Q.rear ->next =  p;
        Q.rear = p;
    }
    bool outQueue(linkedQueue &Q,elementType &x)
    {
        if (isempty(Q))
        {
            return false;/* code */
        }
        node *p = new node;
        p = Q.front->next;
        x = p->data;
        Q.front->next = p->next;
        delete(p);
        if (Q.front->next == NULL )//只有一个节点时
            Q.rear = Q.front;
        return true
    }
    void destory(linkedQueue &Q){
        node *p,*u;
        p = Q.front;
        while(p){
            u = p;
            p = p->next;
            delete(u);
        }
        Q.front = NULL;
        Q.rear =NULL;
    }
  • 相关阅读:
    8.22
    webstrom安装流程
    8.21
    8.20
    8.20学习笔记
    使用WebClient异步获取http资源
    导航栏,可直接使用
    asp.net mvc5实现单点登录
    使用C#调用Word的接口生成doc文件与html文件
    下载网页并保存
  • 原文地址:https://www.cnblogs.com/suizhixxie/p/10486501.html
Copyright © 2011-2022 走看看