6栈与队列

只允许在同一个端点处进行插入、删除的表结构称为栈(stack)

属性:

栈顶(top)指针

栈底(bottom)

进栈(push)

退栈(pop)  

 

特点:

后进先出。或LIFO表  (last in first out)

 

顺序栈的进栈、出栈算法:

#define  EMPTY  -1  //栈空指针值

#define  SUCC  1   //操作成功标记

#define FAIL 0   //操作失败标记

const  int  m=1000;   //栈空间大小

Typedef int element_type;  //元素类型

 

void push(element_type s[ ],int &top,element_type x)  //进栈函数

{

 if(top==m-1)

return FAIL;         

[++top]=x;

return SUCC;

}

 

void push(element_type s[ ],int &top,element_type &x)  //退栈函数

{

if(top==EMPTY )

return FAIL;

x=s[top- -];

return SUCC;         

}

上面是静态数值,空间有限,下面是动态数组。。

 

使用动态数组的进退栈算法

整体变量定义:

#define  SUCC  1                  //操作成功标记

#define  FAIL  0           //操作失败标记

unsigned  m=500;                  //预定的栈空间大小

unsigned  delta=100;            //追加增量

typedef  int  element_type ;      //元素类型

typedef   element_type  *eptr ;   //指针类型

eptr  p;         //指向栈空间

 

开始时预分配栈空间

top=p=(eptr)malloc(m*sizeof(element_type));

 

进栈函数

void  dpush(eptr &p,eptr &top,element_type x)

 //p是当前栈空间起始指针,top是栈顶指针

 //x是要求进栈的元素

{

  if(top==p+m)        //溢出

  {

m+=delta;            //追加增量

     p=(eptr)realloc(p,m*sizeof(element_type));                          //分配更大的空间

    top=p+m-delta;               //重定栈顶指针

  }

 *top=x;                         //x进栈

  ++top;

 }

 

退栈函数

int  dpop(eptr &p, eptr &top,element_type &x)

//p是当前栈空间起始指针,top是栈顶指针

//x接收退栈元素

//返回值  SUCC:退栈成功;FAIL:退栈不成功

  {

   if(top==p) 

return  FAIL;         //栈空

   top--;

   x=*top;                                //x退栈

  return  SUCC ;

  }

 

上讲介绍过链表,栈、队列也可以由一个个结点组成。。。。。。。。

 

链式栈的进栈、退栈算法

 

进栈函数

int  push(ptr &top,element_type x)

 {

ptr p;

   p=new snode;    //申请结点

   if(p==NULL)return  FAIL; //申请失败

   p->data=x; //x进栈

   p->next=top;

   top=p;

   return  SUCC;   //进栈成功

  }

 

退栈函数

int  pop(ptr &top,element_type &x)

  {

ptr  p;

  if(top==NULL)return  FAIL;//退栈不成功. 

x=top->data;

  p=top;

  top=top->next;

  free(p);

  return  SUCC;    //退栈成功

  }

 

 

队列

只允许在一端进行插入,在另一端进行删除的表结构称为队。

属性:

插入端,队尾(rear);删除端,队头(front)

first和last:分别指向队头元素和队尾元素

特点:

先进先出,或FIFO表

 

队列的进队、出队算法也栈类似,可以参考栈的静态、动态方法。下面主要讲讲循环队列和链式队列。

 

循环队列

特点:重复使用已退队元素所占存储单元!

 

注意:循环队列一定要判断队空或队满的情况。

 

队满情况:

1. 情况1: 在程序执行期间,如果要求进队的元素总量不超过数组长度m,就不会出现队满情况 

2. 情况2:  在程序执行期间,需要进队处理的元素 总量多于m个,但任何时刻,队中的元素数目 始终小于m,仍可使用长度为m的数组存储(不会发生队满) 

 

判断方法:

1.开始时,队空,指针first=last=0

2.若一段时间内,只进不出,last赶上first,满

3.若一段时间内,只出不进, first赶上last,空

4.当first等于last时,无所适从

 

循环队列的进队、出队算法

(1)进队函数

int  addq(element_type q[ ], int first,  int &last,element_type x )

       {

         if((last+1)%m==first)

 return 0; //队满

         q[last]=x;

         last=(last+1)%m;.    

return   1;  //进队成功

       }

(2)出队函数

 int delq(element_type q[  ], int &first,  int last,element_type &x )

      {

       if(first==last) 

 return 0;

       x=q[first];

       first=(first+1)%m;

             return    1;

      } 

 

链式队列

链式队采用单向加头链表结构,first为首指针,last为尾指针。

进队:将新结点插在表尾处,last移向新结点。

出队:将队头元素所占结点作为新的头结点(头结点不固定),释放原来的头结点first和last,同时指向头结点作为队空的判断条件。

 

链式队的进出队算法

(1)进队函数

 int  saddq(ptr &last,element_type x)

  {

ptr p;

    p=(ptr)malloc(sizeof(snode)); 

if(p==NULL)

return  FAIL;

  p->data=x;

   last->next=p;

   last=p;

   return  SUCC;  //进队成功

  }

 

(2)出队函数

 int  sdelq(ptr &first,ptr last ,element_type &x)

   {

ptr  p;

  if(first==last)

return FAIL;    //队空

  p=first;

  first=p->next;

  x=first->data;                //x出队

  free(p);

  return  SUCC;    //出队成功

  }

 

 

普通栈的源代码:

// Stack.cpp : 定义控制台应用程序的入口点。

//

---------------------------顺序栈

#include "stdafx.h"

#include<stdio.h>

#include<conio.h>

#include<stdlib.h>

#define MAXSIZE 5

 

bool isPrint()

{

         char ch=getch();

         if(ch=='y'||ch=='Y')

                   return true;

         else

                   return false;

};

int arr[MAXSIZE]={0};

int top=-1;

//进栈

void Push()

{

         printf("请输入一个数据:");

         int data;

         scanf("%d",&data);

         arr[++top]=data;

         printf("剩余栈中空间%d\n",(MAXSIZE-top)-1);

         if(top<(MAXSIZE-1))

         {

         printf("是否继续添加元素(Y/N)\n");

         if(isPrint())

                   Push();

         }

         else

         {

                   printf("栈已满\n");

         };

};

 

//退栈

void Pop()

{

         int x=0;

         x=arr[top--];

         printf("所退的元素是:%d\n",x);

         printf("剩余栈中空间%d\n",(MAXSIZE-top)-1);

         if(top>-1)

         {

         printf("是否继续删除元素(Y/N)\n");

         if(isPrint())

                   Pop();

         }

         else

         {

                   printf("栈已空\n");

         };

};

 

int _tmain(int argc, _TCHAR* argv[])

{

         Push();

         Pop();

         getchar();

         return 0;

}

 

改进后

-----------------------------------------------------------------------------------

// Stack.cpp : 定义控制台应用程序的入口点。

//

 

#include "stdafx.h"

#include<stdio.h>

#include<conio.h>

#include<stdlib.h>

#define MAXSIZE 5

 

int arr[MAXSIZE]={0};

int top=-1;

 

void Pop();

 

int isPrint()

{

         printf("1.进栈;2.出栈\n");

         int k;

         scanf("%d",&k);

         if(k==1)

                   return 1;

         else if(k==2)

                   return 2;

         else

         {

                   printf("输入错误!\n");

                   isPrint();

         };

};

 

//进栈

void Push()

{

         printf("请输入一个数据:");

         int data;

         scanf("%d",&data);

         arr[++top]=data;

         printf("剩余栈中空间%d\n",(MAXSIZE-top)-1);

         if(top<(MAXSIZE-1))

         {

         int k=isPrint();

         if(k==1)

                   Push();

         else

                   Pop();

         }

         else

         {

                   printf("栈已满\n");

                   Pop();

         };

};

 

//退栈

void Pop()

{

         int x=0;

         x=arr[top--];

         printf("所退的元素是:%d\n",x);

         printf("剩余栈中空间%d\n",(MAXSIZE-top)-1);

         if(top>=0)

         {

         int k=isPrint();

         if(k==1)

                   Push();

         else

                   Pop();

         }

         else

         {

                   printf("栈已空\n");

         };

};

 

int _tmain(int argc, _TCHAR* argv[])

{

         Push();

         getch();

         return 0;

}

 

 

-----------------------------------------链式栈

 

// 813.cpp : 定义控制台应用程序的入口点。

//

 

#include "stdafx.h"

#include<stdio.h>

#include<stdlib.h>

#include<conio.h>

 

void isPrint();

 

 

typedef struct Node

{

         int data;

         Node * next;

         Node * prew;

};

 

Node * head=NULL;

Node * top=NULL;

 

//创建节点

Node * Create()

{

         printf("请输入数据:");

         int num;

         scanf("%d",&num);

         Node * pn=(Node *)malloc(sizeof(Node));

         pn->data=num;

         pn->next=NULL;

         pn->prew=NULL;

         return pn;

        

};

//插入节点

void Push()

{       

         Node * p=Create();

         if(head==NULL)

         {

                   head=p;

                   top=p;

                   head->next=NULL;

                   top->next=NULL;

         }

         else

         {

                   top->next=p;

                   p->prew=top;

                   top=p;

                   top->next=NULL;

         };

         isPrint();

        

};

 

void Pop()

{

         Node * p=NULL;

         if(top==head&&head->next==NULL)  //只有一个节点

         {

                   free(head);

                   head=NULL;

         }

         else if(top->next==NULL)

         {

                   p=top;

                   top=top->prew;

                   top->next=NULL;

                   free(p);

         }

         else

         {

                   printf("栈中不存在数据");

         };

         isPrint();

};

 

 

void Select()

{

         Node * ps=NULL;

         ps=head;

         while(ps!=NULL)

         {

                  

                   printf("%d\t",ps->data);

                   ps=ps->next;

         };

         if(head==NULL)

                   {

                            printf("栈中无数据");

                            isPrint();

                  }

         isPrint();

};

 

void isPrint()

{

         printf("\n");

         printf("1.进栈;2.出栈;3.查看\n");

         int k;

         scanf("%d",&k);

         if(k==1)

                   Push();

         else if(k==2)

                   Pop();

         else if(k==3)

                   Select();

         else

         {

                   printf("输入错误!\n");

                   isPrint();

         };

};

 

 

int _tmain(int argc, _TCHAR* argv[])

{

         Push();

         system("pause");

         return 0;

}

 

 

 

 

普通队列的源代码:

// queue.cpp : 定义控制台应用程序的入口点。

//

 

--------------------------------------------- 顺序队

#include "stdafx.h"

#include<stdio.h>

 

#define MAXSIZE  5

int rear=0;

int tail=0;

int arr[MAXSIZE]={0};

 

void isPrint();

 

//进队

void Push()

{

         int num;

         if(tail<MAXSIZE)

         {

                   printf("请输入一个数据:");

                   scanf("%d",&num);

                   arr[tail]=num;

                   tail++;

                   printf("剩余队空间%d",MAXSIZE-tail);

         };

         if(tail>=MAXSIZE)

         {

                   printf("\n队已满");

         };

         isPrint();

};

 

//出队

void Pop()

{

         if(rear!=tail)

         {

                   printf("%d\t",arr[rear]);

                   rear++;

         };

         if(rear==tail)

         printf("\n队已空");

         isPrint();

};

 

void isPrint()

{

         printf("\n");

         printf("1.进队;2.出队\n");

         int k;

         scanf("%d",&k);

         if(k==1)

                   Push();

         else if(k==2)

                   Pop();

         else

         {

                   printf("输入错误!\n");

                   isPrint();

         };

};

 

 

int _tmain(int argc, _TCHAR* argv[])

{

         Push();

         getchar();

         return 0;

}

 

---------------------------------------------------链式队

 

void isPrint();

 

typedef struct Node

{

         int data;

         Node * next;

         Node * prew;

}Node;

 

Node * head=NULL;

Node * end=NULL;

 

//创建节点

Node * Create()

{

         printf("请输入数据:");

         int num;

         scanf("%d",&num);

         Node * pn=(Node *)malloc(sizeof(Node));

         pn->data=num;

         pn->next=NULL;

         pn->prew=NULL;

         return pn;

        

};

//插入节点

void Push()

{       

         Node * p=Create();

         if(head==NULL)

         {

                   head=p;

                   end=p;

                   head->next=NULL;

                   end->next=NULL;

         }

         else

         {

                   p->next=head;

                   head->prew=p;

                   head=p;

         };

         isPrint();

        

};

 

void Pop()

{

         Node * p=NULL;

         if(end==head&&head->next==NULL)  //只有一个节点

         {

                   free(head);

                   head=NULL;

         }

         else if(end->next==NULL)

         {

                   p=end;

                   end=end->prew;

                   end->next=NULL;

                   free(p);

         }

         else

         {

                   printf("队中不存在数据");

         };

         isPrint();

};

 

 

void Select()

{

         Node * ps=NULL;

         ps=head;

         while(ps!=NULL)

         {

                  

                   printf("%d\t",ps->data);

                   ps=ps->next;

         };

         if(head==NULL)

                   {

                            printf("队中无数据");

                            isPrint();

                   }

         isPrint();

};

 

void isPrint()

{

         printf("\n");

         printf("1.进队;2.出队;3.查看\n");

         int k;

         scanf("%d",&k);

         if(k==1)

                   Push();

         else if(k==2)

                   Pop();

         else if(k==3)

                   Select();

         else

         {

                   printf("输入错误!\n");

                   isPrint();

         };

};

 

int _tmain(int argc, _TCHAR* argv[])

{

         Push();

         getchar();

         return 0;

}

 

posted @ 2018-01-09 18:04  gd_沐辰  阅读(159)  评论(0编辑  收藏  举报