Data Structure Study Notes - stacks and queues


ps: This article just to summarize data structure learning notes, easy to forget after inspection, so some pictures can borrow the picture on the book, hope to understand.

Definition (a) of the stack

Stack (Stack) is a table defining a linear only insertion and deletion operations in the trailer. We allow the insertion and deletion of one end called stack (Top) , and the other end is called the stack bottom (bottom) , the stack does not contain any data elements called empty stack. Stack also known LIFO (Last In First Out) linear form , referred LIFO structure.
Stack insert operation, called into the stack, also known as push, push . As shown below:
      Here Insert Picture Description
stack deletion, also called out stack, and some called popped , as shown in FIG.

Basic operation (b) of the stack

ADT 栈(stack)
	Data
	    同线性表。元素具有相同的类型,相邻元素具有前驱和后继关系。
	Operation
	    InitStack ( *S ):初始化操作.建立一个空栈S。
	    DestroyStack ( *S ):若栈存在,則销毁它。
	    ClearStack (*S):将栈清空。
	    StackEmpty ( S ):若栈为空,返回true,否則返回 false。
	    GetTop (S,*e):若栈存在且非空,用e返回S的栈顶元素。
	    Push (*S,e):若栈S存在,插入新元素e到栈S中并成为栈頂元素。
	    Pop (*S,*e):删除栈S中栈顶元素,并用e返回其值。
	    StackLength (S):返回回栈S的元素个数。
	endADT

  Because the stack itself is a linear table, so linear form of the chain and sequentially stored on the storage section in question for the stack is also applicable.

Sequential storage structure and implementation (c) of the stack

  Generally defined by a top variable only the top element position in the array, the stack when an element is present, top equal to 0, hero usually empty stack top as a determination condition equal to -1.
  Stack structure definition:

/* 顺序栈结构 */
typedef int SElemType; /* SElemType类型根据实际情况而定,这里假设为int */
typedef struct
{
        SElemType data[MAXSIZE];
        int top; /* 用于栈顶指针 */
}SqStack;

  Ordinary circumstances stack \ empty case stack and full stack diagram is as follows:
        Here Insert Picture Description

1, the stack of sequential storage structure - onto the stack.

  I.e., stack pointer onto the stack plus one, a new value is assigned to the element stack space (push):

/* 插入元素e为新的栈顶元素 */
Status Push(SqStack *S,SElemType e)
{
        if(S->top == MAXSIZE -1) /* 栈满 */
        {
                return ERROR;
        }
        S->top++;				/* 栈顶指针增加一 */
        S->data[S->top]=e;  /* 将新插入元素赋值给栈顶空间 */
        return OK;
}

2, the stack structure stored in the order - the pull operation

  Operation removes the top element from the stack, the stack pointer is decremented by one (pop):

/* 若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERROR */
Status Pop(SqStack *S,SElemType *e)
{ 
        if(S->top==-1)
                return ERROR;
        *e=S->data[S->top];	/* 将要删除的栈顶元素赋值给e */
        S->top--;				/* 栈顶指针减一 */
        return OK;
}

  The above-described operation time complexity are O (. 1) .

(Iv) two stack shared space

  Using an array to store two stacks, two end points are two stacks of arrays bottom of the stack, if two stacks increasing element is extending to the middle of the two endpoints.
    Here Insert Picture Description
Stack two shared space structure:

// 两栈共享结构
typedef struct {
    ElemType data[MAXSIZE]; // 用于存储元素值
    int top1; // 用于指示栈1的栈顶指针
    int top2; // 用于指示栈2的栈顶指针
}SqStack;

  push method stack two shared space:

// 插入元素e为新的栈顶元素
Status Push(SqStack *S, ElemType e, int stackNumber)
{
    if (S->top1 + 1 == S->top2)  // 栈满时,添加失败
    {
        return ERROR;
    }
    // 给栈1添加新元素
    if (stackNumber == 1) 
        S->data[++S->top1] = e; // 将新元素添加到栈1的栈顶
    else 						// 给栈2添加新元素
        S->data[--S->top2] = e; // 将新元素添加到栈2的栈顶
    return OK;
}

  pop stack shared space of two methods:

// 若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK,否则返回ERROR
Status Pop(SqStack *S, ElemType *e, int stackNumber) 
{
    // 栈1弹出元素
    if (stackNumber == 1) {  
        if (S->top1 == -1)    // 栈为空时,弹出元素失败
            return ERROR;
        *e = S->data[S->top1--]; // 将栈顶元素的值赋给e元素,栈1的栈顶指针减1
    } 
    else 		// 栈2弹出元素
    { 
        if (S->top2 == MAXSIZE) 
            return ERROR;
        *e = S->data[S->top2++]; // 将栈顶元素的值赋给e元素,栈2的栈顶指针加1
    }

    return OK;
}

  Learn the like using such a data structure, usually when the space requirement when two stacks having two opposite meaningful relationships and requires the same data type can stack.

(E) Storage Structure and realization of the stack

Storage Structure of the stack, referred to as link stack . For the link stack is not required because the head node stack pointer may replace the role of the first node, and the link stack absence of full stack if the stack is empty, that is, top = NULL.
            Here Insert Picture Description
  Chain structure is as follows:

/* 链栈结构 */
typedef struct StackNode
{
        SElemType data;
        struct StackNode *next;
}StackNode,*LinkStackPtr;

typedef struct LinkStack
{
        LinkStackPtr top;
        int count;
}LinkStack;

1, the stack of linked storage structure - onto the stack.

              Here Insert Picture Description
Sample code:

/* 插入元素e为新的栈顶元素 */
Status Push(LinkStack *S,SElemType e)
{
        LinkStackPtr s=(LinkStackPtr)malloc(sizeof(StackNode)); 
        s->data=e; 
        s->next=S->top;		/* 把当前的栈顶元素赋值给新结点的直接后继,见图中① */
        S->top=s;         /* 将新的结点s赋值给栈顶指针,见图中② */
        S->count++;
        return OK;
}

2, the stack of linked storage structure - the pull operation

                Here Insert Picture Description
Sample code:

/* 若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERROR */
Status Pop(LinkStack *S,SElemType *e)
{ 
        LinkStackPtr p;
        if(StackEmpty(*S))
                return ERROR;
        *e=S->top->data;
        p=S->top;					/* 将栈顶结点赋值给p,见图中③ */
        S->top=S->top->next;    /* 使得栈顶指针下移一位,指向后一结点,见图中④ */
        free(p);                    /* 释放结点p */        
        S->count--;
        return OK;
}

  Above time complexity are also O (. 1) , such as over the course of stack elements unpredictable variations, the best link stack ; if the variation in the controllable range, with the order of the stack better.

(F) defined queue

Queue (Queue) is allowed only in the insertion end and at the other end of the linear table delete operation. , The queue is a FIFO (First In First Out) linear form , referred to as FIFO. Permit insertion period is called the tail end, allowing delete called queue head .
      Here Insert Picture Description

(Vii) the basic operation of the queue

ADT 队列 (Queue)
Data
    同线性表。元素具有相同的类型,相邻元素具有前驱和后继关系 。
Operation
    InitQueue(*Q) 		:初始化操作,建立一个空队列Q。
    DestroyQueue(*Q) 	:若队列Q存在,则销毁它。
    ClearQueue(*Q)		:将队列Q清空。
    QueueEmpty(Q) 		:若队列Q为空,返回true,否则返回false。
    GetHead(Q,*e) 		:若队列Q存在且非空,用e返回队列Q的队头元素。
    EnQueue(*Q,e) 		:若队列Q存在,插入新元素e到队列Q中并成为对尾元素 。
    DeQueue(*Q,*e) 		:删除队列Q中队头元素,并用e返回其值。
    QueueLength(Q) 		:返回队列Q的元素个数
endADT

(Viii) circular queue

1, less than the order of the queue

  假设我们有一个队列里面有n个元素,入队列操作就是在队尾加入一个新元素,不移动其他元素,其时间复杂度为O(1)
    Here Insert Picture Description
  因为队列是先进先出,而出队操作时队头出队的时候队列中其他元素都要向前移动,其时间复杂度为O(n)
  为了解决出队操作的麻烦引入了两个指针:front 指针指向队头元素,rear 指针指向队尾元素的下一个元素。当front = rear时队列为空。
    Here Insert Picture Description
  这样虽然解决一定问题但是如果队列经过出队操作后我队列前是空闲的,其队尾元素已被占用(rear)移动到数组外。如下图所示:
    Here Insert Picture Description
  这样的情况叫做“假溢出”。因此可看出顺序队列有很多的问题,因此我们引入了新的结构——循环队列。

2、顺序队列定义及操作

  我们把队列头尾相接的顺序存储结构叫做循环队列。例如刚才rear指针指向数组外的情况,我们可将他重新指到队列头未被占用的空间,就可解决问题。
    Here Insert Picture Description
  此种情况我们需要讨论的问题队列何时为满队列:假设队列最大尺寸为QueueSize,队列满的条件为 (rear+1)%QueueSize == front(取模是为了整合rear与front大小)计算队列长度公式为 (rear - front + QueueSize)% QueueSize。
循环队列顺序存储结构如下:

/* 循环队列的顺序存储结构 */
typedef int QElemType; /* QElemType类型根据实际情况而定,这里假设为int */
typedef struct
{
	QElemType data[MAXSIZE];
	int front;    	/* 头指针 */
	int rear;		/* 尾指针,若队列不空,指向队列尾元素的下一个位置 */
}SqQueue;

循环队列初始化:

/* 初始化一个空队列Q */
Status InitQueue(SqQueue *Q)
{
	Q->front=0;
	Q->rear=0;
	return  OK;
}

循环队列入队操作:

/* 若队列未满,则插入元素e为Q新的队尾元素 */
Status EnQueue(SqQueue *Q,QElemType e)
{
	if ((Q->rear+1)%MAXSIZE == Q->front)	/* 队列满的判断 */
		return ERROR;
	Q->data[Q->rear]=e;			/* 将元素e赋值给队尾 */
	Q->rear=(Q->rear+1)%MAXSIZE;/* rear指针向后移一位置, */
								/* 若到最后则转到数组头部 */
	return  OK;
}

循环队列出队操作:

/* 若队列不空,则删除Q中队头元素,用e返回其值 */
Status DeQueue(SqQueue *Q,QElemType *e)
{
	if (Q->front == Q->rear)			/* 队列空的判断 */
		return ERROR;
	*e=Q->data[Q->front];				/* 将队头元素赋值给e */
	Q->front=(Q->front+1)%MAXSIZE;	/* front指针向后移一位置, */
									/* 若到最后则转到数组头部 */
	return  OK;
}

(九)队列的链式存储及实现

Storage Structure queue, in fact, the linear form of a single linked list, only the end of the feed head, we call it a queue chain.
Chain queue structure:

typedef int QElemType; /* QElemType类型根据实际情况而定,这里假设为int */
typedef struct QNode	/* 结点结构 */
{
   QElemType data;
   struct QNode *next;
}QNode,*QueuePtr;

typedef struct			/* 队列的链表结构 */
{
   QueuePtr front,rear; /* 队头、队尾指针 */
}LinkQueue;

Chain team operating team included:

/* 插入元素e为Q的新的队尾元素 */
Status EnQueue(LinkQueue *Q,QElemType e)
{ 
	QueuePtr s=(QueuePtr)malloc(sizeof(QNode));
	if(!s) /* 存储分配失败 */
		exit(OVERFLOW);
	s->data=e;
	s->next=NULL;
	Q->rear->next=s;	/* 把拥有元素e的新结点s赋值给原队尾结点的后继,见图中① */
	Q->rear=s;		/* 把当前的s设置为队尾结点,rear指向s*/
	return OK;
}

Chain operations team squad list:

/* 若队列不空,删除Q的队头元素,用e返回其值,并返回OK,否则返回ERROR */
Status DeQueue(LinkQueue *Q,QElemType *e)
{
	QueuePtr p;
	if(Q->front==Q->rear)
		return ERROR;
	p=Q->front->next;		/* 将欲删除的队头结点暂存给p,见图中① */
	*e=p->data;				/* 将欲删除的队头结点的值赋值给e */
	Q->front->next=p->next;/* 将原队头结点的后继p->next赋值给头结点后继,见图中② */
	if(Q->rear==p)		/* 若队头就是队尾,则删除后将rear指向头结点*/
		Q->rear=Q->front;
	free(p);
	return OK;
}

Reference books: "Westward data structure"

Published 11 original articles · won praise 3 · Views 253

Guess you like

Origin blog.csdn.net/weixin_42647166/article/details/104693860