zoukankan      html  css  js  c++  java
  • 数据结构 【栈与队列】

     栈

    栈满足下列两点:

    1.栈只能从表的一端存取数据,另一端是封闭的。
    2.在栈中,无论是存数据还是取数据,都必须遵循"先进后出"的原则,即最先进栈的元素最后出栈。
    总结:栈是一种只能从表的一端存取数据且遵循 "先进后出" 原则的线性存储结构。

    如图:栈存储结构存储 {1,2,3,4}

     栈的顺序表实现:

    顺序表就是采用数组+尾指针的方式,尾指针一直指向最后一个元素,这里特殊的地方在于,栈为空时,尾指针指向-1.

    #include <stdio.h>
    #define Size 100
    
    typedef struct stacktag
    {
        int a[Size];
        int top;
    }stack;
       
    #入栈
    int rush(int* a,int top,int elem){
        if(++top>=Size)
        {
            printf("栈已满
    ");
            return --top;
        }
        a[++top]=elem;
        printf("插入元素:%d
    ",a[top]);
        return top;
    }
    
    #出栈
    int pop(int * a,int top){ if (top==-1) { printf("空栈"); return -1; } printf("弹栈元素:%d ",a[top]); top--; return top; } int main () { stack stack1; stack1.top = -1; printf("初始化成功 "); stack1.top = rush(stack1.a,stack1.top,1); stack1.top = rush(stack1.a,stack1.top,5); stack1.top = pop(stack1.a,stack1.top); return 0; }
    初始化成功
    插入元素:1
    插入元素:5
    弹栈元素:5
    

     栈的链表实现:

    使用链表实现注意一点:

    数据插入采用头插法,数据每次弹出头部的元素

    #include <stdio.h>
    #include<malloc.h>
    
    //声明链表节点类型
    typedef struct LISTtag LISTtagNode;
    struct    LISTtag{
        int value;
        LISTtagNode *next;
    };
    int size=0;
    
    
    //创建链表
    LISTtagNode * create(){
        LISTtagNode *head;
        head = (LISTtagNode*)malloc(sizeof(LISTtagNode));
        head->next =  NULL;
        return head;
    }
    
    
    //在链表头新增节点
    int push(LISTtagNode *head,int value){
        if(head == NULL){
            return -1;
        }
        //新建节点
        LISTtagNode *node;
        node = (LISTtagNode*)malloc(sizeof(LISTtagNode));
        //节点赋值,此节点跟在头节点后
        node->value = value;
        node->next = head->next;
        head->next = node;
        size++;
        return 1;
    }
    
    
    //打印链表
    int PrindLinKList(LISTtagNode *head){
         if(head == NULL){
            return -1;
        }
        LISTtagNode *t = head;
        while (t->next != NULL) {
            t = t->next;
            printf("%d ", t->value);
        }
        return 1;
    }
    
    
    int pop(LISTtagNode *head){
        if(head ==NULL){
            return -1;
        }
        LISTtagNode *node;
        int index = 0;
        while(head->next!=NULL&&index<1){
            node = head->next;
            index++;
        }
        if(index == 1){
             printf("
    %d ",node->value);
            if(head->next->next != NULL){
                head->next = head->next->next;  
            }else{
                head->next =NULL;
            }
            free(node);
            size--;
            return 1;
        }  
        return -1;
    }
    
    int top(LISTtagNode *head){
        if(head ==NULL){
            return -1;
        }
        LISTtagNode *node;
        int index = 0;
        while(head->next!=NULL&&index<1){
            node = head->next;
            index++;
        }
        if(index == 1){
            printf("%d ",node->value);
            return 1;
        }
        return -1;
    }
    
    int empty(LISTtagNode *head){
        if(head ==NULL){
            return -1;
         }
        if(head->next!=NULL){
            return 0;
        }
        return 1;
    }
    
    int length(LISTtagNode *head){
        if(head ==NULL){
            return -1;
         }
        return size;
    }
    
    int main () {
        LISTtagNode *head = create();
        push(head,7);
        push(head,9);
        push(head,23);
        push(head,43);
        push(head,45);
        push(head,65);
        printf("
    正序打印链表:");
        PrindLinKList(head);
        printf("
    链表长度:%d",length(head));
        pop(head);
        printf("
    正序打印链表:");
        PrindLinKList(head);
        printf("
    链表长度:%d",length(head));
        return 0;
    }

    队列

    队列满足下列两点:

    1.队列从一端表存储数据,从另一端是读取数据。
    2.数据的入队和出队遵循"先进先出"的原则;

    总结:队列是一种从表的一端存储数据,从另一端读取数据,满足“先进先出”的数据结构。

    队列的实现:

    #include <stdio.h>
    #define max 5//表示顺序表申请的空间大小
    int enQueue(int *a,int front,int rear,int data){
        //添加判断语句,如果rear超过max,则直接将其从a[0]重新开始存储,如果rear+1和front重合,则表示数组已满
        if ((rear+1)%max==front) {
            printf("空间已满");
            return rear;
        }
        a[rear%max]=data;
        rear++;
        return rear;
    }
    int  deQueue(int *a,int front,int rear){
        //如果front==rear,表示队列为空
        if(front==rear%max) {
            printf("队列为空");
            return front;
        }
        printf("%d ",a[front]);
        //front不再直接 +1,而是+1后同max进行比较,如果=max,则直接跳转到 a[0]
        front=(front+1)%max;
        return front;
    }
    int main() {
        int a[max];
        int front,rear;
        //设置队头指针和队尾指针,当队列中没有元素时,队头和队尾指向同一块地址
        front=rear=0;
        //入队
        rear=enQueue(a,front,rear, 1);
        rear=enQueue(a,front,rear, 2);
        rear=enQueue(a,front,rear, 3);
        rear=enQueue(a,front,rear, 4);
        //出队
        front=deQueue(a, front, rear);
        //再入队
        rear=enQueue(a,front,rear, 5);
        //再出队
        front=deQueue(a, front, rear);
        //再入队
        rear=enQueue(a,front,rear, 6);
        //再出队
        front=deQueue(a, front, rear);
        front=deQueue(a, front, rear);
        front=deQueue(a, front, rear);
        front=deQueue(a, front, rear);
        return 0;
    }
    1 2 3 4 5 6  

    使用环形表实现顺序队列的方法需要注意的是,顺序队列在判断数组是否已满时,出现下面情况:

    • 当队列为空时,队列的头指针等于队列的尾指针;
    • 当数组满员时,队列的头指针等于队列的尾指针;

    顺序队列初始状态没有存储任何元素,因此 top 指针和 rear 指针重合,且由于顺序队列底层实现靠的是数组,因此 top 和 rear 实际上是两个变量,它的值分别是队头元素和队尾元素所在数组位置的下标。

    顺序队列的存储状态不同,但是判断条件相同。为了对其进行区分,最简单的解决办法是:牺牲掉数组中的一个存储空间,判断数组满员的条件是:尾指针的下一个位置和头指针相遇,就说明数组满了,即程序中第 5 行所示。

  • 相关阅读:
    mininet和ryu控制器的连接
    Linux服务器(Ubuntu14.04)添加远程连接VNC Server
    KVM的前世今生
    Ubuntu下搭建ryu环境
    Ubuntu下搭建Mininet环境
    手机蓝牙
    常见的js算法面试题收集,es6实现
    前端笔试题面试题记录(上)
    关于js中onclick字符串传参问题(html="")
    Angular $scope和$rootScope事件机制之$emit、$broadcast和$on
  • 原文地址:https://www.cnblogs.com/-wenli/p/12180857.html
Copyright © 2011-2022 走看看