1 / 36

数据结构

数据结构. C 语言版. 内 容 3.1 栈的概念 3.2 栈的存储结构 3.3 顺序栈的操作算法 3.4 链栈的操作算法 3.5 栈的应用举例 --- 表达式求值 3.6 队列的概念 3.7 队列的存储结构 3.8 循环队列的操作算法 3.9 链队的操作算法. 第三章 : 栈和队列. 3.1 栈的概念 1. 定义: 栈 (Stack) 是限定仅在表的一端进行插入或删除操作的线性表。 2. 栈的示意图 P44 3. 栈的抽象数据类型定义 P45. 3.2 栈的存储结构。 有两种存储结构 :.

pillan
Download Presentation

数据结构

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 数据结构 C语言版

  2. 内 容 • 3.1栈的概念 • 3.2栈的存储结构 • 3.3顺序栈的操作算法 • 3.4链栈的操作算法 • 3.5栈的应用举例---表达式求值 • 3.6队列的概念 • 3.7队列的存储结构 • 3.8循环队列的操作算法 • 3.9链队的操作算法

  3. 第三章:栈和队列 3.1栈的概念 1.定义: 栈(Stack) 是限定仅在表的一端进行插入或删除操作的线性表。 2.栈的示意图 P44 3.栈的抽象数据类型定义 P45

  4. 3.2栈的存储结构。 有两种存储结构:

  5. 1、顺序栈

  6. 顺序栈的类型定义: //-- -- --栈的顺序存储表示-- -- --#define STACK_NINT_SIZE 100;//存储空间初始分配量#define STACKINCREMENT 10; //存储空间分配增量typedef struct{SElemType *base; //在栈构造之前和销毁之后,base的值为NULLSElemType *top; //栈顶指针int stacksize; //当前已分配的存储空间,以元素为单位}SqStack

  7. //-- -- --基本操作的函数原型说明-- -- --Status InitStack(SqStack &S);//构造一个空栈SStatus GetTop(SqStack S,SElemType &e);//若栈不空,则用e返回S的栈顶元素,并返回OK;否则返回ERRORStatus Push(SqStack &S,SElemType e);//插入元素e为新的栈顶元素Status Pop(SqStack &S,SElemType &e);//若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERROR

  8. 2、链栈

  9. 链栈的类型定义: typedef struct LNode{//结点类型ElemType data;struct LNode *next;}Lnode,*Linkstack;Linkstack S;

  10. 3.3顺序栈的操作算法 1建立一个空栈Status InitStack(SqStack &S){//构造一个空栈SS.base=(SElemType *)malloc(STACK_INIT_SIZE*sizeof(SElemType));if(!S.base)exit(overflow); //存储分配失效S.top=S.base;S.stacksize=STACK_INIT_SIZE;return OK;}//InitStack

  11. 2.取栈顶元素Status GetTop(SqStack S,SElemType &e) //若栈不空,则用e返回S的栈顶元素,并返回OK;否则返回ERRORif(S.top==S.base) return ERROR;e=*(S.top-1);return OK;}//GetTop

  12. 3.压栈pushStatus Push(SqStack &S,SElemType e){//插入元素e为新的栈顶元素if(S.top-S.base>=S.stacksize){//栈满,追加存储空间S.base=(SElemType*)realloc(S.base,(S.stacksize+ STACKINCREMENT)*sizeof(SElemType));if(!S.base)exit(OVERFLOW);//存储分配失败S.top=S.base+S.stacksize;S.stacksize+=STACKINCREMENT;}*S.top++=e;return OK;}//push

  13. 4.出栈popstatus Pop(SqStack &S,SElemType &e){ //若栈不为空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERRORif(S.top==S.base)return ERROR;e=*--S.top;return OK;}//Pop

  14. 5 判断栈是否为空 int Empty(SqStack S){//若栈为空,则返回0,否则返回1if(s.top==s.base) return (0);else return (1);} 6 判断栈是否为满 int Full(SqStack S){//若栈为满,则返回0,否则返回1if(s.top-s.base)>=s.stacksize return (0);else return (1);}

  15. 思考:两个栈共享同一段内容空间,为了使得空间利用率最高,应如何分配栈空间?思考:两个栈共享同一段内容空间,为了使得空间利用率最高,应如何分配栈空间?

  16. 3.4链栈的操作算法 1.建立一个空栈 Status InitLStack (Linkstack &S){S=NULL;return ok;}//InitLStack

  17. 2.取栈顶元素 Status GettopLStack (Linkstack &S,SElemType &e){//若栈不为空,则用e返回S的栈顶元素,并返回OK,否则返回ERROR.if(S==NULL) return ERROR;e=S->data;return(OK);}//GettopLStack

  18. 3.压栈Push Status PushLStack(Linkstack &S,SElemType e){//插入元素e为新的栈顶元素Lnode *p;p=(Lnode *)malloc(sizeof(Lnode));p->data=e;p->next=S;S=p;}//PushLStack

  19. 4.出栈Pop Status PopLStack(Linkstack &S,SElemType &e){//若栈不为空,则删除S的栈顶元素,用e返回其值,并返回OK,否则返回ERROR if(s==NULL) return ERROR;e=S->data;S=S->link;return OK;}//PopLStack

  20. 5.判断栈是否为空 int link_empty(Linkstack &S){//若栈为空则返回1,否则返回0if(S==NULL) return(1);else retrun(0);}

  21. 3.5栈的应用举例---表达式求值 算法的基本思想是: (1)首先置操作数栈为空栈,表达式起始符“#”为运算符的栈底元素; (2)依次读入表达式中每个字符,若是操作数则进OPND栈,若是运算符,则和OPTR栈的栈顶运算符比较优符后作相应操作,直至整个表达式求值完毕(即OPTR栈的栈顶元素和当前读入的字符均为“#”)。 算法描述p53 *栈与递归的实现

  22. 3.6队列的概念 1、定义:队列是一种先进先出(FIFO:First In First Out)的线性表。它只允许在表的一端进行插入,而在另一端删除元素。 2、示意图

  23. 3、队列的抽象数据类型定义 队列的抽象数据类型定义: ADT Queue{ 数据对象:D={ai|ai∈ElemSet,i=1,2,...,n,n≥0} 数据关系:R1={<ai-1,ai>|ai-1,ai∈D,i=2,...,n} 约定其中a1端为队列头,an为队列尾。 基本操作: InitQueue(&Q) 操作结果:构造一个空队列Q。 DestroyQueue(&Q) …… } ADT Queue p59

  24. 4、双端队列 a 定义:双端队列是限定插入和删除操作在表的两端进行的线性表。 b 双端队列的示意图

  25. 3.7队列的存储结构 ★有两种存储结构 ★顺序队列的示意图

  26. ★链队列的示意图

  27. 3.8循环队列的操作算法 1、循环队列的基本思想: 在顺序队列中,头指针front始终指向队列头元素,而尾指针rear始终指向队列尾元素的下一个位置,随着进队、出队操作的进行,有可能会出rear指针已到达队列存储空间的终点,而队列的实际可用空间并未占满现象。为了避免这种现象的发生,一个巧妙的办法是将顺序队列臆造为一个环状空间,称之为循环队列。如图所示:

  28. 2、循环队列的队空队满条件 为了方便起见,约定:初始化建空队时,令front=rear=0,当队空时:front=rear当队满时:front=rear 亦成立因此只凭等式front=rear无法判断队空还是队满。有两种方法处理上述问题:(1)另设一个标志位以区别队列是空还是满。(2)少用一个元素空间,约定以“队列头指针front在队尾指针rear的下一个位置上”作为队列“满”状态的标志。即:队空时: front=rear队满时: (rear+1)%maxsize=front

  29. 3、循环队列的类型定义: //-- -- --循环队列---队列的顺序存储结构-- -- #define MAXQSIZE 100 //最大队列长度typedef struct{QELemType *base ; //初始化的动态分配存储空间int front; //头指针,若队列不空,指向队列头元素int rear; //尾指针,若队列不空,指向队列尾元素的下一个位置}SqQueue;

  30. 4、建立空的循环队列的算法 Status InitQueue(SqQueue &Q){//构造一个空队列QQ.base=(QElemType *)malloc(MAXQSIZE *sizeof(QElemType));if(!Q.base)exit(WVERFLOW);//存储分配失败Q.front=Q.rear=0;return OK; }

  31. 5、求循环队列中元素的个数 int QueueLength(SqQueue Q){//返回Q的元素个数,即队列的长度return(Q.rear-Q.front+MAXQSIZE)%MAXQSIZE;} 6、进队算法 Status EnQueue(SqQueue &Q,QElemType e){//插入元素为Q的新的队尾元素if((Q.rear+1) % MAXQSIZE==Q.front)returnERROR;//队列满Q.base[Q.rear]=e;Q.rear=(Q.rear+1) % MAXQSIZE;return OK;}

  32. 7、出队算法 Status DeQueue(SqQueue &Q,QElemType &e){//若队列不空,则删除Q的队头元素,用e返回其值,并返回OK;否则返回ERRORif(Q.front==Q.rear) return ERROR;e=Q.base[Q.front];Q.front=(Q.front+1)%MAXQSIZE;return OK;}

  33. 3、9链队的操作算法 1、链队的类型定义 //-- -- -单链队列---队列的链式存储结构-- --typedefstruct QNode {QElemType data;struct QNode *next;}QNode, *QueuePtr;typedefstruct {QueuePtr front;//队头指针QueuePtr rear;//队尾指针}LinkQueue;

  34. 2、建立空的链队 Status InitQueue(LinkQueue &Q){//构造一个空队列QQ.front=Q.rear=(QueuePtr)malloc(sizeof(QNode));if(!Q.front)exit(OVERFLOW);Q.front->next=NULL;return OK;}

  35. 3、进队算法 Status EnQueue(LinkQueue &Q,QElemType e){//插入元素e为Q的新的队尾元素p=(QueuePtr)malloc(sizeof(QNode));if(!p) exit(OVERFLOW);p->data=e; p->next=NULL;Q.rear->next=p;Q.rear=p;return OK;}

  36. 4、出队算法 Status DeQueue(LinkQueue &Q,QElemType &e){//若队列不空,则删除Q的队头元素,用e返回其值,并返回OK;否则返回ERRORif(Q.front==Q.rear) return ERROR;p=Q.front->nxet;e=p->data;Q.front->next=p->next;if(Q.rear==p) Q.rear=Q.front;free(p);return OK;}

More Related