Background development study notes (four stacks, queues)

Stacks and queues relatively simple, straightforward description description, on a list speak a little more, this time briefly explain stack and columns.

4.1 Stack

4.1.1 stack structure

Stack structure, in other blog also said a lot, here to talk briefly, the stack is a linear structure, a stack of elements can only last-out (Frist In Last Out abbreviation FILO), the first to enter the storage element to bottom of the stack , and finally into elements called the top of the stack , the stack operation can only operate in the top of the stack.
Structure stack array or linked list may be used to implement
the following array to achieve as long as:

typedef struct Stack
{
	int 		top;				//栈顶指针
	int			size;				//栈的大小
	Elemtype 	*data;				//栈的元素
}_Stack;

4.1.2 Stack operation

  1. Stack
    stack operation (push) is to add a new element to the position of the top of the stack, then this new element is the top of the stack.
/**
    * @brief  入栈,内部支持扩容
    * @param  
    * @retval 
    */ 
    int stack_push(struct Stack *s, Elemtype data)
    {
		if(s == NULL)
			return -1;

		if(s->top >= s->size)   //这个是要等于,因为有0
		{
			int new_len = (s->size>>1) + s->size;
			//printf("len = %d %d %d\n", s->size>>1, s->size, new_len);
			s->data = realloc(s->data, new_len*sizeof(Elemtype));   	//扩容1.5倍,realloc可以复制之前数据到新的内容区
			if(s == NULL)
				return -2;

			s->size = new_len;
		}

		s->data[s->top] = data;
		s->top++;
		
        return 0;
    }
  1. Pop
    pop operations (pop) is to remove the element from the stack, but can only be removed from the top of the stack of elements, one element out of the top element of the stack will be called the new top of the stack
/**
	* @brief  出栈,
	* @param  
	* @retval 
	*/ 
	int stack_pop(struct Stack *s, Elemtype *data)
	{
		if(s == NULL || data == NULL)
			return -1;

		//可以做减少容量的操作

		if(s->top == 0)
			return -2;

		*data = s->data[--s->top];    //这个是指向栈顶的,需要先减
		return 0;
	}

4.1.3 Additional: Stack face questions

1. Effective brackets
leetcode 20 question:
given only includes a '(', ')', '{', '}', '[', ']' string, determines whether the string is valid.

Valid string must meet:

Left bracket must be closed by a closing parenthesis of the same type.
Left parenthesis must be closed in the correct order.
Note the empty string can be considered a valid string.

This question is leetcode do first question, but it feels a little tired leetcode brush c language, and consequently need package, but now it comes to these fundamental data structures, or used to write c, in leetcode can use c ++, directly call c ++ encapsulated stack. Before we have a good package of a stack, it can now be used to try.

This question is the use of a stack of functions, advanced after we came in every part of the left parenthesis are push, when to the right parenthesis, put get the top element, and a right parenthesis determine what just came in match, if not match, it returns a failure, if the match, then the stack, and then continue to the next round.

Code:

/**
	* @brief  有效括号
	* @param  s: 字符串
	* @retval 
	*/ 
	int stack_ValidParentheses(char *s)
	{
		//1.创建一个栈
		struct Stack st;
		stack_creat(&st, 10);

		//2.分解字符串,c语言只能用指针遍历
		char *c = s;
		while(*c != '\0')
		{
			//3.判断是否是左括号,是的话就入栈,否则取出栈顶元素做判断
			if(*c == '(' || *c == '[' || *c == '{')
			{
				stack_push(&st, *c);
			}
			else
			{
				int cc;
				//先做检测,如果栈为空,返回失败
				if(stack_len(&st) == 0)
					return -1;
				stack_pop(&st, &cc);
				
				//判断是否跟输入的一致
				if(*c == ')' && cc != '(' ||
					*c == ']' && cc != '[' ||
					*c == '}' && cc != '{' )
				{
					return -1;
				}
			}
			c++;
		}

		//4.如果栈为空,就说明匹配成功,反则失败
		if(stack_len(&st) == 0)
			return 0;
		return -1;
	}

The implementation language, but the grammar are different, specific ideas are the same.

2. The minimum stack
designed to support a push, pop, top operation, the stack can be retrieved and smallest elements in constant time.

push (x) - the element x push the stack.
pop () - delete elements of the stack.
top () - get the top element.
getMin () - retrieve the minimum element in the stack.

This question still had first heard during the interview, had very ignorant force, can not think, it is clear that the results of the interview was brushed, met again to see the answer on the programmer small gray number of public feeling design the good, the algorithm is to take brush.

Good understanding on drawing, painting a map like to understand:

  • First apply two stacks, a stack is a normal memory storage element, the other is a spare tire stack stored minimum value
    Here Insert Picture Description
  • Drawing
    the minimum stack design of the stack and the stack before us a little bit different, first of all the first element of the stack 4, it will be into two stacks, because the minimum stack is now empty, so the first value is the minimum.
    Here Insert Picture Description
    Only the second element 9 is then pushed onto the stack, the stack must make a judgment before the stack top element B if element 9 is smaller than the stack, the stack B, the result is now 9> 4, which is not stack B.
    Here Insert Picture Description
    The third element is 3, and then compares this time 3 <4 so that the stack B.
    Here Insert Picture Description
  • Stack
    actually stack must take into account the B stack, the stack, we also need to take into account. When the stack will determine what the top element of the stack B, if the values are equal, stack B is also a stack, the stack so that the top element of B is the current minimum stack, in line with the complexity of obtaining the minimum value of the stack is O (1)
    Here Insert Picture Description
  • Obtaining the minimum value of
    direct access to the top element in the stack B.

Clear thinking have been described, it is not difficult to write the code:

/**
	* @brief  最小栈创建
	* @param  
	* @retval 
	*/ 
	static struct Stack gs_stA;
	static struct Stack gs_stB;
	int stackMin_init(void)
	{
		//1.创建一个栈A
		stack_creat(&gs_stA, 10);
		stack_creat(&gs_stB, 10);
		
		return 0;
	}

	int stackMin_push(Elemtype data)
	{
		//1.入栈
		Elemtype temp;
		
		//判断栈B是否为空,为空直接进栈
		if(stack_len(&gs_stB) == 0)
		{
			stack_push(&gs_stB, data);
		}
		else
		{
			//跟栈顶元素判断,如果小于栈顶元素进栈
			stack_top(&gs_stB, &temp);
			if(data <= temp)
			{
				stack_push(&gs_stB, data);
			}
		}

		//栈A都需要进栈
		stack_push(&gs_stA, data);
		
		return 0;
	}

	Elemtype stackMin_pop(void)
	{
		//1.出栈
		Elemtype tempA, tempB;

		//栈A先出栈
		stack_pop(&gs_stA, &tempA);


		//看看栈B的栈顶元素
		if(stack_len(&gs_stB) != 0)
		{
			stack_top(&gs_stB, &tempB);
		
	        if(tempA == tempB)
				stack_pop(&gs_stB, &tempB);	
		}
		
		return 0;
	}

	Elemtype stackMin_top(void)
	{
		//1.出栈
		Elemtype tempA;

		//栈A先出栈
		stack_top(&gs_stA, &tempA);
		
		return tempA;
	}

	Elemtype stackMin_getMin(void)
	{
		//最小值
		Elemtype temp;
		
		//判断栈B是否为空,不为空就获取最小值
		if(stack_len(&gs_stB) != 0)
		{
			stack_top(&gs_stB, &temp);
			return temp;
		}
		
		return -1;
	}

4.2 queue

4.2.1 queue structure

Queue (Queue) is a linear data structure, different from the first in the stack, only the elements in the queue FIFO (first IN First Out, referred to as FIFO). The outlet end of the queue called the team head, the inlet end of the queue called the tail. The team can only enter from the tail, the only team from the team head.
Queue may be a linked list an array. I use an array to achieve here

typedef struct Queue
{
	int			front;				//对头指针
	int 		rear;				//队尾指针
	int 		size;				//队列的大小
	Elemtype	*data;				//队列的元素
}_Queue;

4.2.2 circular queue

Why just say circular queue is basically we use circular queue, the queue basic no use, so the direct use of circular queue.
Circular queue is the use of space has left the team element, so that the tail pointer refers back to the top of the array, so this column will cycle up.
Superscript +1 queue full condition is determined :( queue tail) superscript HOL% = array length.

4.2.3 Operation circular queue

1. enqueued
into the team (the enqueue) the new element is put into the queue, only the tail element into position, the new position of a new element will be the tail. Add a new expansion operation.

/**
	* @brief  入队
	* @param  
	* @retval 
	*/ 
	//旧代码,保留做对比
	int queue_enter(struct Queue *q, Elemtype data)
	{
		assert(q);

		//判断队列是否满
		if((q->rear+1)%q->size == q->front)
			return -1;

		q->data[q->rear] = data;
		q->rear = (q->rear+1)%q->size;
		
		return 0;
	}

	//新添加了扩容操作
    int queue_enter(struct Queue *q, Elemtype data)
	{
		assert(q);

		//判断队列是否满
		if((q->rear+1)%q->size == q->front)
		{
			//申请新的内存扩容
			int new_len = (q->size>>1)+q->size;
			q->data = realloc(q->data, sizeof(Elemtype)*new_len);
			assert(q->data);
			//如果front<rear就没有问题,扩容后的数据也是直接添加到后面
			//如果front>rear,在旧的数组空间,就被分为两截,所以要把0到rear的一截复制到q->size后面,来完成扩容,最后修改rear指针
			if(q->rear < q->front)
			{
				int i;
				int old_len = q->size;
				for(i=0; i<q->rear; i++)
				{
					q->data[old_len++] = q->data[i]; 
				}
				q->rear = old_len;
			}

			q->size = new_len;
		}
			
		q->data[q->rear] = data;
		q->rear = (q->rear+1)%q->size;
		
		return 0;
	}

2. dequeue
dequeue operation (dequeue) the element is removed from the queue, only the head is removed from the team, the team of an element is a new one in the head.

/**
	* @brief  出队
	* @param  
	* @retval 
	*/ 
	int queue_delete(struct Queue *q, Elemtype *data)
	{
		assert(q);
		assert(data);

		//判断队列是否为空
		if(q->rear == q->front)
			return -1;

		*data = q->data[q->front];
		q->front = (q->front+1)%q->size;
		
		return 0;
	}

3. traverse the
circular queue traversal is still a little meaning, so here implements a

/**
		* @brief  遍历栈
		* @param  
		* @retval 
		*/ 
		int queue_traversal(struct Queue *q)
		{
			if(q == NULL)
				return -1;
	
			int i = 0;
			int head = (q->front)%q->size;
			int tail = (q->rear)%q->size;
			printf("traversal %d %d\n", head, tail);
			for(i=head; i != tail; i=(i+1)%q->size)   //这样遍历
			{		
				printf("%d ", q->data[i]);
			}
			printf("\n");
			
			return 0;
		}

4.2.4 Additional: face questions on columns

Buyer No, you can later add

4.3 Hash Table

Buyer No, added later

Queue temporarily not face questions, but leetcode above question queue a lot, you can go to brush, I do not brush here first, and then will go to the brush, and now even hash table to nothing, but the focus is achieved hash table hash function, after careful study of the notes had to do.

Published 32 original articles · won praise 26 · views 20000 +

Guess you like

Origin blog.csdn.net/C1033177205/article/details/103329713