基于C语言的数据结构_队列 学习笔记

目录

03队列实现原理

03.1顺序队列

03.2循环队列

03.3双端队列

04队列的实际应用

04.1解码


03队列实现原理

先进先出

0

1

2

3

4

...

n

a1

a2

a3

a4

a5

定义两个指针 head 与 tail

头head:终是指向头元素位置
尾tail:即将放入元素位置

入队列: tail 操纵
出队列 :head 操纵

应用: 排队买票 排货架

03.1顺序队列

顺序队列会遇到一个问题 那就是当有数据出栈的时候 head向后指向  那么前面的数据空间就不能再用了。(专业术语称之为假溢出 )你可能没有存那么多项,可就是存不下了。

为了防止数据的假溢出我们使用循环队列。

03.2循环队列

入队列由tail 操纵 当tail到达了未元素再入队列 tail就需要移到第一个元素位置 当然也有一个前提队列未满 得有空间让你入队列

queue[tail] = c;
tail = (tail + 1) % SIZE;

判断队列是否已满 牺牲一个数据空间

return (tail + 1) % SIZE == head;

出队列 有head 操纵 当head到达了未元素再出队列 head就需要移到第一个元素位置 当然也有一个前提队列不为空 

ch = queue[head];
head = (head + 1) % SIZE;

判断队列为不为空 ——如果head == tail就是队列取完了 为空了

具体代码实现

#include <stdio.h>

#define SIZE	512

char queue[SIZE];

int head = 0, tail = 0;

void enqueue(char c);
char dequeue(void);
int is_empty(void);
int is_full(void);

int main(void)
{
	char c = 'A';
	int i;
	for(i = 0; i < 3; i++)
	{
		if(!is_full())
		{
			enqueue(c);
			c++;
		}
	}

	while(!is_empty())
	{
		putchar(dequeue());
	}
	printf("\n");

	return 0;
}

void enqueue(char c)
{
	queue[tail] = c;
	tail = (tail + 1) % SIZE;
}

char dequeue(void)
{
	char ch;
	ch = queue[head];
	head = (head + 1) % SIZE;

	return ch;
}

int is_empty(void)
{
	return head == tail;
}

int is_full(void)
{
	return (tail + 1) % SIZE == head;
}

03.3双端队列

在循环队列中 入队列是尾入(tail) 出队列是头出(head)那么能不能这样的设计

tail 和 head 既可以入队列也可以出队列!

双端循环队列

        head端出队列
                c = queue[head]
                head = (head+1)%SIZE;
        head端入队列
                (head-1+SIZE)%SIZE;
                queue[head]=b
        tail端出队列
                tail = (tail-1+size)%size;
                c = queue[tail];
        tail端入队列
                queue[tail] = c;
                tail = (tail+1)%size;
        队列是否为空
                head == tail
        队列是否为满:
                (tail+1)%size == head;

代码实现

#include <stdio.h>
#include <string.h>

#define SIZE	512

char queue[SIZE];

int head = 0, tail = 0;

void tail_enqueue(char c);
char tai_dequeue(void);
void head_enqueue(char c);
char head_dequeue(void);
int is_empty(void);
int is_full(void);
int is_palindrom(char *pt);

int main(void)
{
	char str[100];

	printf("Please enter a string:");
	gets(str);

	if(is_palindrom(str))
		printf("str is a palindrom\n");
	else
		printf("str is not a palindrom\n");

	return 0;
}

void tail_enqueue(char c)
{
	queue[tail] = c;
	tail = (tail + 1) % SIZE;
}

char tail_dequeue(void)
{
	tail = (tail - 1 + SIZE) % SIZE;
	return queue[tail];
}

void head_enqueue(char c)
{
	head = (head - 1 + SIZE) % SIZE;
	queue[head] = c;
}

char head_dequeue(void)
{
	char ch;
	ch = queue[head];
	head = (head + 1) % SIZE;

	return ch;
}

int is_empty(void)
{
	return head == tail;
}

int is_full(void)
{
	return (tail + 1) % SIZE == head;
}

int is_palindrom(char *pt)
{
	int i, len;
	len = strlen(pt);
	char c1, c2;

	for(i = 0; i < len; i++)
		if(!is_full())
			tail_enqueue(pt[i]);

	while(!is_empty())
	{
		c1 = head_dequeue();
		if(!is_empty())
			c2 = tail_dequeue();
		else
			break;

		if(c1 == c2)
			continue;
		else
			return 0;
	}
	return 1;
}

04队列的实际应用

04.1解码

已知一个数列组合是经过加密后的一串数字,那么现在知道这串加密后的数字,并且知道如何破解的方法,求加密前数字的组合是什么。破解的方法:首先将第1个数删除,紧接着将第2个数放到这串数的末尾,再将第3个数删除并将第4个数放到这串数的末尾,再将 第5个数删除……直到剩下最后一个数,将最后一个数也删除。按照刚才删 除的顺序,把这些删除的数连在一起就是原始的数据。

我们用循环队列实现

#include <stdio.h>
#include <string.h>

#define SIZE	512

char queue[SIZE];

int head = 0, tail = 0;

void enqueue(char c);
char dequeue(void);
int is_empty(void);
int is_full(void);

int main(void)
{
	char code[10];
	int n;
	int i = 0;
	char num;

	printf("Please enter a code:");
	gets(code);

	for(n = 0; n < strlen(code); n++)
	{
		if(!is_full())
			enqueue(code[n]);
	}

	while(!is_empty())
	{
		code[i++] = dequeue();
		if(!is_empty())
		{
			num = dequeue();
			if(!is_full())
				enqueue(num);
		}
	}

	printf("Orignal code is :");
	for(i = 0; i < strlen(code); i++)
		printf("%c", code[i]);
	printf("\n");

	return 0;
}

void enqueue(char c)
{
	queue[tail] = c;
	tail = (tail + 1) % SIZE;
}

char dequeue(void)
{
	char ch;
	ch = queue[head];
	head = (head + 1) % SIZE;

	return ch;
}

int is_empty(void)
{
	return head == tail;
}

int is_full(void)
{
	return (tail + 1) % SIZE == head;
}

猜你喜欢

转载自blog.csdn.net/shelter1234567/article/details/129738533