zoukankan      html  css  js  c++  java
  • 王道数据结构——栈和队列

    本文主要讲解了数据结构中操作受限的线性表:栈和队列。

    知识结构如下图所示:

      定义

      基本操作

      顺序存储结构

      链式存储结构

    队列

      定义

      基本操作

      顺序存储结构

      链式存储结构

    定义:只允许在一端进行插入或删除的线性表。

    栈的基本操作

    InitStack(&S);初始化一个空栈

    StackEmpty(&S);判断一个栈是否为空

    Push(&S, x);进栈(若未满)

    Pop(&S, &x);出栈(若非空)

    GetTop(S, &x);读取栈顶元素(若非空,用x返回栈顶元素)

    ClearStack(&S);销毁栈,并释放栈S所用的存储空间

    栈的顺序存储结构

     1 #include<cstdio>
     2 #define Maxsize 50
     3 
     4 typedef struct{
     5     int data[Maxsize];
     6     int top;
     7 }SqStack;
     8 
     9 void InitStack(SqStack &S){
    10     S.top = -1;
    11 }
    12 bool StackEmpty(SqStack &S){
    13     if(S.top == -1)
    14         return true;
    15     return false;
    16 }
    17 bool Push(SqStack &S, int x){
    18     if(S.top == Maxsize - 1)
    19         return false;
    20     S.data[++S.top] = x;
    21     return true;
    22 }
    23 bool Pop(SqStack &S, int &x){
    24     if(S.top == -1)
    25         return false;
    26     x = S.data[S.top--];
    27     return true;
    28 }
    29 bool GetTop(SqStack &S, int &x){
    30     if(S.top == -1)
    31         return false;
    32     x = S.data[S.top];
    33     return true;
    34 }
    35 bool ClearStack(SqStack &S){
    36     //free(S);
    37 }
    38 
    39 int main()
    40 {
    41     SqStack s;
    42     InitStack(s);
    43     for(int i = 0; i < 10; i++)
    44         if(Push(s,i))
    45             printf("%d入栈
    ", i);
    46     while(!StackEmpty(s)){
    47         int x; 
    48         GetTop(s, x);
    49         printf("栈顶元素是%d
    ", x);
    50         if(Pop(s, x))
    51             printf("%d出栈
    ", x);
    52     }
    53     ClearStack(s);
    54     return 0;    
    55 } 

    栈的链式存储结构

     1 #include<cstdio>
     2 #include<cstdlib> 
     3 typedef struct Linknode{
     4     int data;
     5     struct Linknode *next;
     6 } *LiStack;//栈结点类型指针
     7  
     8 void InitStack(LiStack &S){
     9     S = NULL;
    10 }
    11 bool StackEmpty(LiStack &S){
    12     if(S == NULL)
    13         return true;
    14     return false;
    15 }
    16 //不带头结点的头插法 
    17 bool Push(LiStack &S, int x){
    18     Linknode* n = NULL;
    19     n = (Linknode*)malloc(sizeof(Linknode));
    20     if(!n)
    21         return false;
    22     
    23     n->data = x;
    24     n->next = S;
    25     S = n;
    26     return true;
    27 }
    28 bool Pop(LiStack &S, int &x){
    29     if(!S)
    30         return false;
    31     x = S->data;
    32     Linknode *p = S;
    33     S = S->next;
    34     free(p);
    35     return true;
    36 }
    37 bool GetTop(LiStack &S, int &x){
    38     if(!S)
    39         return false;
    40     x = S->data;
    41     return true;
    42 }
    43 bool ClearStack(LiStack &S){
    44     Linknode *p = S;
    45     while(p != NULL){
    46         Linknode *t = p;
    47         p = p->next;
    48         free(t);
    49         p = p->next; 
    50     }
    51     free(p);
    52 }
    53 int main()
    54 {
    55     LiStack s;
    56     InitStack(s);
    57     for(int i = 0; i < 10; i++)
    58         if(Push(s,i))
    59             printf("%d入栈
    ", i);
    60     while(!StackEmpty(s)){
    61         int x; 
    62         GetTop(s, x);
    63         printf("栈顶元素是%d
    ", x);
    64         if(Pop(s, x))
    65             printf("%d出栈
    ", x);
    66     }
    67     ClearStack(s);
    68     return 0;
    69 }

    队列

    定义,也是一种操作受限的线性表,只允许在表的一端进行插入,而在另一端进行删除。

    基本操作

    InitQueue(&Q);初始化

    QueueEmpty(Q);队列是否为空

    EnQueue(&Q, x);若队列未满,入队

    DeQueue(&Q, &x);若队列非空,出队

    GetHead(Q, &x);读取队头元素,若队列非空,将队头元素赋值给x

    ClearQueue(&Q);清空队列,并回收内存

    队列的顺序存储结构

     1 #include<cstdio>
     2 
     3 #define MaxSize 50
     4 typedef struct{
     5     int data[MaxSize];
     6     int front,rear;
     7 } SqQueue;
     8 
     9 void InitQueue(SqQueue &Q)//初始化
    10 {
    11     Q.front = Q.rear = 0;
    12 }
    13 bool QueueEmpty(SqQueue Q)//队列是否为空
    14 {
    15     if(Q.front == Q.rear)
    16         return true;//空为真,非空为假 
    17     return false; 
    18 }
    19 bool EnQueue(SqQueue &Q, int x)//若队列未满,入队
    20 {
    21     //if(Q.rear == MaxSize) return false;//判断条件错误,可能假溢出 
    22     Q.data[Q.rear++] = x; 
    23     return true; 
    24 } 
    25 bool DeQueue(SqQueue &Q, int &x)//若队列非空,出队
    26 {
    27     if(Q.front == Q.rear)
    28         return false;
    29     x = Q.data[Q.front++];
    30     return true;
    31 }
    32 bool GetHead(SqQueue Q, int &x)//读取队头元素,若队列非空,将队头元素赋值给x
    33 {
    34     if(Q.front == Q.rear)
    35         return false;
    36     x = Q.data[Q.front];
    37     return true;
    38 }
    39 void ClearQueue(SqQueue &Q)//清空队列,并回收内存
    40 {
    41     Q.front = Q.rear = 0;
    42 }
    43 int main()
    44 {
    45     SqQueue Q;
    46     InitQueue(Q);
    47     for(int i = 0; i < 10; i++){
    48         if(EnQueue(Q, i)){
    49             int x;
    50             GetHead(Q, x);
    51         }
    52     } 
    53     while(!QueueEmpty(Q))
    54     {
    55         int x;
    56         GetHead(Q, x);
    57         printf("当前队头元素是%d
    ", x);
    58         DeQueue(Q, x);
    59         printf("出队的元素是%d
    ", x);
    60     }
    61     ClearQueue(Q);
    62     return 0;
    63 }

    循环队列的l顺序存储结构

    为了解决当队尾追上队头时判满和判空时的矛盾有三种方法,分别是

     1 #include<cstdio>
     2 
     3 #define MaxSize 10
     4 /*顺序循环队列出现队尾追上队首的情况
     5 方法一,牺牲一个存储空间
     6 初始为Q.front == Q.rear,队满为(Q.rear + 1)%MaxSize == Q.front*/ 
     7 typedef struct{
     8     int data[MaxSize];
     9     int front,rear;
    10 } SqQueue;
    11 
    12 void InitQueue(SqQueue &Q)//初始化
    13 {
    14     Q.front = Q.rear = 0;
    15 }
    16 bool QueueEmpty(SqQueue Q)//队列是否为空
    17 {
    18     if(Q.front == Q.rear)
    19         return true;//空为真,非空为假 
    20     return false; 
    21 }
    22 bool EnQueue(SqQueue &Q, int x)//若队列未满,入队
    23 {
    24     if((Q.rear + 1)%MaxSize == Q.front) return false;//队列满 
    25     Q.data[Q.rear] = x; 
    26     Q.rear = (Q.rear + 1) % MaxSize; 
    27     return true; 
    28 } 
    29 bool DeQueue(SqQueue &Q, int &x)//若队列非空,出队
    30 {
    31     if(Q.front == Q.rear)
    32         return false;
    33     x = Q.data[Q.front];
    34     Q.front = (Q.front + 1) % MaxSize;
    35     return true;
    36 }
    37 bool GetHead(SqQueue Q, int &x)//读取队头元素,若队列非空,将队头元素赋值给x
    38 {
    39     if(Q.front == Q.rear)
    40         return false;
    41     x = Q.data[Q.front];
    42     return true;
    43 }
    44 int Length(SqQueue Q){
    45     return (Q.rear - Q.front + MaxSize) % MaxSize;
    46 }
    47 void ClearQueue(SqQueue &Q)//清空队列,并回收内存
    48 {
    49     Q.front = Q.rear = 0;
    50 }
    51 int main()
    52 {
    53     SqQueue Q;
    54     InitQueue(Q);
    55     for(int i = 0; i < 15; i++){
    56         if(EnQueue(Q, i)){
    57             int x;
    58             GetHead(Q, x);
    59         }
    60         else
    61             printf("%d入队失败
    ", i); 
    62     } 
    63     while(!QueueEmpty(Q))
    64     {
    65         int x;
    66         GetHead(Q, x);
    67         printf("当前队头元素是%d
    ", x);
    68         DeQueue(Q, x);
    69         printf("出队的元素是%d
    ", x);
    70     }
    71     ClearQueue(Q);
    72     return 0;
    73 }
    View Code
     1 #include<cstdio>
     2 #include<cstring> 
     3 #define MaxSize 10
     4 /*顺序循环队列出现队尾追上队首的情况
     5 方法二 
     6 初始为Q.front = Q.rear = Q.size = 0,队满为Q.size == MaxSize*/ 
     7 typedef struct{
     8     int data[MaxSize];
     9     int front,rear;
    10     int size;
    11 } SqQueue;
    12 
    13 void InitQueue(SqQueue &Q)//初始化
    14 {
    15     memset(Q.data, 0, sizeof(Q.data));
    16     Q.front = Q.rear = Q.size = 0;
    17 }
    18 bool QueueEmpty(SqQueue Q)//队列是否为空
    19 {
    20     if(Q.size == 0)
    21         return true;//空为真,非空为假 
    22     return false; 
    23 }
    24 bool EnQueue(SqQueue &Q, int x)//若队列未满,入队
    25 {
    26     if(Q.size == MaxSize) return false;//队列满 
    27     Q.data[Q.rear] = x; 
    28     Q.size++;
    29     Q.rear = (Q.rear + 1) % MaxSize; 
    30     return true; 
    31 } 
    32 bool DeQueue(SqQueue &Q, int &x)//若队列非空,出队
    33 {
    34     if(Q.size == 0)
    35         return false;
    36     x = Q.data[Q.front];
    37     Q.front = (Q.front + 1) % MaxSize;
    38     Q.size--;
    39     return true;
    40 }
    41 bool GetHead(SqQueue Q, int &x)//读取队头元素,若队列非空,将队头元素赋值给x
    42 {
    43     if(Q.size == 0)
    44         return false;
    45     x = Q.data[Q.front];
    46     return true;
    47 }
    48 int Length(SqQueue Q){
    49     return Q.size;
    50 }
    51 void ClearQueue(SqQueue &Q)//清空队列,并回收内存
    52 {
    53     Q.front = Q.rear = 0;
    54 }
    55 int main()
    56 {
    57     SqQueue Q;
    58     InitQueue(Q);
    59     for(int i = 0; i < 15; i++){
    60         if(EnQueue(Q, i)){
    61             int x;
    62             GetHead(Q, x);
    63         }
    64         else
    65             printf("%d入队失败
    ", i); 
    66     } 
    67     while(!QueueEmpty(Q))
    68     {
    69         int x;
    70         GetHead(Q, x);
    71         printf("当前队头元素是%d
    ", x);
    72         DeQueue(Q, x);
    73         printf("出队的元素是%d
    ", x);
    74     }
    75     ClearQueue(Q);
    76     return 0;
    77 }
    View Code
     1 #include<cstdio>
     2 #include<cstring> 
     3 #define MaxSize 10
     4 /*顺序循环队列出现队尾追上队首的情况
     5 方法三 
     6 初始为Q.front = Q.rear = 0,tag = false
     7 当Q.front == Q.rear时,tag == false 为队列插入导致队满
     8 tag == true 为队列删除导致队空*/ 
     9 typedef struct{
    10     int data[MaxSize];
    11     int front,rear;
    12     bool tag; 
    13 } SqQueue;
    14 
    15 void InitQueue(SqQueue &Q)//初始化
    16 {
    17     memset(Q.data, 0, sizeof(Q.data));
    18     Q.front = Q.rear = 0;
    19     Q.tag = false; 
    20 }
    21 bool QueueEmpty(SqQueue Q)//队列是否为空
    22 {
    23     if(Q.front == Q.rear && Q.tag == false)
    24         return true;//空为真,非空为假 
    25     return false; 
    26 }
    27 bool EnQueue(SqQueue &Q, int x)//若队列未满,入队
    28 {
    29     if(Q.front == Q.rear && Q.tag == true) return false;//队列满 
    30     Q.data[Q.rear] = x; 
    31     Q.rear = (Q.rear + 1)%MaxSize;
    32     Q.tag = true; //可能队满 
    33     return true; 
    34 } 
    35 bool DeQueue(SqQueue &Q, int &x)//若队列非空,出队
    36 {
    37     if(Q.front == Q.rear && Q.tag == false)
    38         return false;
    39     x = Q.data[Q.front];
    40     Q.front = (Q.front + 1)%MaxSize;
    41     Q.tag = false; //可能队空 
    42     return true;
    43 }
    44 bool GetHead(SqQueue Q, int &x)//读取队头元素,若队列非空,将队头元素赋值给x
    45 {
    46     if(Q.front == Q.rear && Q.tag == false)
    47         return false;
    48     x = Q.data[Q.front];
    49     return true;
    50 }
    51 int Length(SqQueue Q){
    52     return (Q.rear - Q.front + MaxSize) % MaxSize;
    53 }
    54 void ClearQueue(SqQueue &Q)//清空队列,并回收内存
    55 {
    56     memset(Q.data, 0, sizeof(Q.data));
    57     Q.front = Q.rear = 0;
    58     Q.tag = false; 
    59 }
    60 int main()
    61 {
    62     SqQueue Q;
    63     InitQueue(Q);
    64     for(int i = 0; i < 15; i++){
    65         if(EnQueue(Q, i)){
    66             int x;
    67             GetHead(Q, x);
    68         }
    69         else
    70             printf("%d入队失败
    ", i); 
    71     } 
    72     while(!QueueEmpty(Q))
    73     {
    74         int x;
    75         GetHead(Q, x);
    76         printf("当前队头元素是%d
    ", x);
    77         DeQueue(Q, x);
    78         printf("出队的元素是%d
    ", x);
    79     }
    80     ClearQueue(Q);
    81     return 0;
    82 }
    View Code

    队列的链式存储结构

     1 #include <cstdio>
     2 #include <cstdlib>
     3 typedef struct LinkNode{
     4     int data;
     5     struct LinkNode *next; 
     6 }LinkNode;
     7 typedef struct{
     8     LinkNode *front, *rear;
     9 }LinkQueue;
    10 
    11 /*初始化为带头结点的链式队列*/
    12 void InitQueue(LinkQueue &Q)//初始化
    13 {
    14      Q.front = Q.rear = (LinkNode*)malloc(sizeof(LinkNode));
    15      Q.front->next = NULL;//也即 Q.rear->next =NULL 
    16 }
    17 bool QueueEmpty(LinkQueue Q)//队列是否为空
    18 {
    19     if(Q.front == Q.rear)
    20         return true;//空为真,非空为假 
    21     return false; 
    22 }
    23 bool EnQueue(LinkQueue &Q, int x)//若队列未满,入队
    24 {
    25     LinkNode *p = (LinkNode*)malloc(sizeof(LinkNode));
    26     p->data = x;
    27     p->next=NULL;
    28     
    29        Q.rear->next = p;
    30     Q.rear = p; 
    31     return true; 
    32 } 
    33 bool DeQueue(LinkQueue &Q, int &x)//若队列非空,出队
    34 {
    35     if(Q.front == Q.rear)
    36         return false;
    37     LinkNode *p = Q.front->next;
    38     x = p->data;
    39     Q.front->next = p->next;
    40     if(p == Q.rear)
    41         Q.rear = Q.front;//原队列中只有一个结点,删除后变空 
    42     free(p);
    43     return true;
    44 }
    45 bool GetHead(LinkQueue Q, int &x)//读取队头元素,若队列非空,将队头元素赋值给x
    46 {
    47     if(Q.front == Q.rear)
    48         return false;
    49     x = Q.front->next->data;
    50     return true;
    51 }
    52 int Length(LinkQueue Q){
    53     LinkNode *p = Q.front->next;//带有头结点的形式统一 
    54     int cnt = 0;
    55     while(p != NULL){
    56         cnt++;
    57         p = p->next;
    58     }
    59     return cnt;
    60 }
    61 void ClearQueue(LinkQueue &Q)//清空队列,并回收内存
    62 {
    63     LinkNode *p = Q.front->next;//带有头结点的形式统一 
    64     while(p != NULL){
    65         LinkNode *tmp = p;
    66         p = p->next;
    67         free(tmp);
    68     }
    69     Q.front->next = Q.rear->next = NULL;
    70 }
    71 int main()
    72 {
    73     LinkQueue Q;
    74     InitQueue(Q);
    75     for(int i = 0; i < 10; i++){
    76         if(EnQueue(Q, i)){
    77             printf("%d入队成功
    ", Q.rear->data);
    78         }
    79         else
    80             printf("%d入队失败
    ", i);
    81     }    
    82     printf("入队后队列中元素的个数是%d
    ", Length(Q));
    83     while(!QueueEmpty(Q)){
    84         int x;
    85         GetHead(Q, x);
    86         printf("当前队首元素%d
    ", x);
    87         DeQueue(Q, x);
    88         printf("出队元素是%d
    ", x);
    89     }
    90     ClearQueue(Q); 
    91     printf("清空后队列中元素的个数是%d
    ", Length(Q));
    92     return 0;    
    93 } 
  • 相关阅读:
    springboot-项目属性配置
    网络编程
    HttpServlet---getLastModified与缓存
    TCP的三次握手和四次挥手
    数据库事务隔离级别-- 脏读、幻读、不可重复读
    js 数组,字符串,json互相转换
    表格单元格td设置宽度无效的解决办法
    判断IE版本的HTML语句详解,如:<!--[if IE 9]> 仅IE9可识别 <![endif]-->
    IE主页被篡改为360导航终极处理办法
    前端常见问题
  • 原文地址:https://www.cnblogs.com/wenzhixin/p/11723679.html
Copyright © 2011-2022 走看看