概要

本章和介绍""时的流程一样,先对队列进行介绍,然后分别给出队列的C、C++和Java三种语言的实现。内容包括:
1. 队列的介绍
2. 队列的C实现
3. 队列的C++实现
4. 队列的Java实现

转载请注明出处:http://www.cnblogs.com/skywang12345/p/3562279.html


更多内容: 数据结构与算法系列 目录

队列的介绍

队列(Queue),是一种线性存储结构。它有以下几个特点:
(01) 队列中数据是按照"先进先出(FIFO, First-In-First-Out)"方式进出队列的。
(02) 队列只允许在"队首"进行删除操作,而在"队尾"进行插入操作。
队列通常包括的两种操作:入队列 和 出队列。

1. 队列的示意图

队列中有10,20,30共3个数据。

2. 出队列

出队列前:队首是10,队尾是30。
出队列后:出队列(队首)之后。队首是20,队尾是30。

3. 入队列

入队列前:队首是20,队尾是30。
入队列后:40入队列(队尾)之后。队首是20,队尾是40。

下面介绍队列的实现,分别介绍C/C++/Java三种实现

队列的C实现

共介绍4种C语言实现。
1. C语言实现一:数组实现的队列,并且只能存储int数据。
2. C语言实现二:单向链表实现的队列,并且只能存储int数据。
3. C语言实现三:双向链表实现的队列,并且只能存储int数据。
4. C语言实现四:双向链表实现的队列,能存储任意类型的数据。

1. C语言实现一:数组实现的队列,并且只能存储int数据

实现代码(array_queue.c)

 #include <stdio.h>
#include <malloc.h> /**
* C 语言: 数组实现的队列,只能存储int数据。
*
* @author skywang
* @date 2013/11/07
*/ // 保存数据的数组
static int *arr=NULL;
// 队列的实际大小
static int count; // 创建“队列”
int create_array_queue(int sz)
{
arr = (int *)malloc(sz*sizeof(int));
if (!arr)
{
printf("arr malloc error!");
return -;
}
count = ; return ;
} // 销毁“队列”
int destroy_array_queue()
{
if (arr)
{
free(arr);
arr = NULL;
} return ;
} // 将val添加到队列的末尾
void add(int val)
{
arr[count++] = val;
} // 返回“队列开头元素”
int front()
{
return arr[];
} // 返回并删除“队列开头元素”
int pop()
{
int i = ;;
int ret = arr[]; count--;
while (i++<count)
arr[i-] = arr[i]; return ret;
} // 返回“队列”的大小
int size()
{
return count;
} // 返回“队列”是否为空
int is_empty()
{
return count==;
} void main()
{
int tmp=; // 创建“队列”
create_array_queue(); // 将10, 20, 30 依次推入队列中
add();
add();
add(); // 将“队列开头的元素”赋值给tmp,并删除“该元素”
tmp = pop();
printf("tmp=%d\n", tmp); // 只将“队列开头的元素”赋值给tmp,不删除该元素.
tmp = front();
printf("tmp=%d\n", tmp); add(); // 打印队列
printf("is_empty()=%d\n", is_empty());
printf("size()=%d\n", size());
while (!is_empty())
{
printf("%d\n", pop());
} // 销毁队列
destroy_array_queue();
}

运行结果

tmp=
tmp=
is_empty()=
size()=

结果说明:该示例中的队列,是通过"数组"来实现的!
由于代码中已经给出了详细了注释,这里就不再对函数进行说明了。仅对主函数main的逻辑进行简单介绍。
(01) 在主函数main中,先将 "10, 20, 30"依次入队列。此时,队列的数据是: 10 --> 20 --> 30
(02) 接着通过pop()返回队首元素;pop()操作并不会改变队列中的数据。此时,队列的数据依然是: 10 --> 20 --> 30
(03) 接着通过front()返回并删除队首元素。front()操作之后,队列的数据是: 10 --> 30
(04) 接着通过add(40)将40入队列。add(40)操作之后,队列中的数据是: 10 --> 20 --> 40

2. C语言实现二:单向链表实现的队列,并且只能存储int数据

实现代码(slink_queue.c)

 #include <stdio.h>
#include <malloc.h> /**
* C 语言: 单链表实现“队列”,只能存储int数据。
*
* @author skywang
* @date 2013/11/07
*/ // 单链表节点
struct node {
int val;
struct node* next;
}; // 表头
static struct node *phead=NULL; // 创建节点,val为节点值
static struct node* create_node(val)
{
struct node *pnode=NULL;
pnode = (struct node*)malloc(sizeof(struct node));
if (!pnode)
return NULL;
pnode->val = val;
pnode->next = NULL; return pnode;
} // 销毁单向链表
static int destroy_single_link()
{
struct node *pnode=NULL; while (phead != NULL)
{
pnode = phead;
phead = phead->next;
free(pnode);
}
return ;
} // 将val添加到队列的末尾
static void add(int val)
{
if (!phead)
{
phead = create_node(val);
return ;
} struct node *pnode = create_node(val);
struct node *pend = phead;
while (pend->next)
pend = pend->next; pend->next = pnode;
} // 返回“队列开头元素”
int front()
{
return phead->val;
} // 返回并删除“队列开头元素”
static int pop()
{
int ret = phead->val;
struct node *pnode = phead; phead = phead->next;
free(pnode); return ret;
} // 返回链表中节点的个数
static int size()
{
int count=;
struct node *pend = phead; while (pend)
{
pend = pend->next;
count++;
} return count;
} // 链表是否为空
static int is_empty()
{
return size()==;
} void main()
{
int tmp=; // 将10, 20, 30 依次加入到队列中
add();
add();
add(); // 将“队列开头元素”赋值给tmp,并删除“该元素”
tmp = pop();
printf("tmp=%d\n", tmp); // 只将“队列开头的元素”赋值给tmp,不删除该元素.
tmp = front();
printf("tmp=%d\n", tmp); add(); printf("is_empty()=%d\n", is_empty());
printf("size()=%d\n", size());
while (!is_empty())
{
printf("%d\n", pop());
} // 销毁队列
destroy_single_link();
}

代码说明:"运行结果" 以及 "主函数main的逻辑"都和"C语言实现一"的一样。不同的是,该示例中的队列是通过单向链表实现的。

3. C语言实现三:双向链表实现的队列,并且只能存储int数据

实现代码
双向链表的头文件(double_link.h)

 #ifndef _DOUBLE_LINK_H
#define _DOUBLE_LINK_H // 新建“双向链表”。成功,返回表头;否则,返回NULL
extern int create_dlink();
// 撤销“双向链表”。成功,返回0;否则,返回-1
extern int destroy_dlink(); // “双向链表是否为空”。为空的话返回1;否则,返回0。
extern int dlink_is_empty();
// 返回“双向链表的大小”
extern int dlink_size(); // 获取“双向链表中第index位置的元素的值”。成功,返回节点值;否则,返回-1。
extern int dlink_get(int index);
// 获取“双向链表中第1个元素的值”。成功,返回节点值;否则,返回-1。
extern int dlink_get_first();
// 获取“双向链表中最后1个元素的值”。成功,返回节点值;否则,返回-1。
extern int dlink_get_last(); // 将“value”插入到index位置。成功,返回0;否则,返回-1。
extern int dlink_insert(int index, int value);
// 将“value”插入到表头位置。成功,返回0;否则,返回-1。
extern int dlink_insert_first(int value);
// 将“value”插入到末尾位置。成功,返回0;否则,返回-1。
extern int dlink_append_last(int value); // 删除“双向链表中index位置的节点”。成功,返回0;否则,返回-1
extern int dlink_delete(int index);
// 删除第一个节点。成功,返回0;否则,返回-1
extern int dlink_delete_first();
// 删除组后一个节点。成功,返回0;否则,返回-1
extern int dlink_delete_last(); // 打印“双向链表”
extern void print_dlink(); #endif

双向链表的实现文件(double_link.c)

 #include <stdio.h>
#include <malloc.h> /**
* C 语言: 双向链表,只能存储int数据。
*
* @author skywang
* @date 2013/11/07
*/ // 双向链表节点
typedef struct tag_node
{
struct tag_node *prev;
struct tag_node *next;
int value;
}node; // 表头。注意,表头不存放元素值!!!
static node *phead=NULL;
// 节点个数。
static int count=; // 新建“节点”。成功,返回节点指针;否则,返回NULL。
static node* create_node(int value)
{
node *pnode=NULL;
pnode = (node *)malloc(sizeof(node));
if (!pnode)
{
printf("create node error!\n");
return NULL;
}
// 默认的,pnode的前一节点和后一节点都指向它自身
pnode->prev = pnode->next = pnode;
// 节点的值为value
pnode->value = value; return pnode;
} // 新建“双向链表”。成功,返回0;否则,返回-1。
int create_dlink()
{
// 创建表头
phead = create_node(-);
if (!phead)
return -; // 设置“节点个数”为0
count = ; return ;
} // “双向链表是否为空”
int dlink_is_empty()
{
return count == ;
} // 返回“双向链表的大小”
int dlink_size() {
return count;
} // 获取“双向链表中第index位置的节点”
static node* get_node(int index)
{
if (index< || index>=count)
{
printf("%s failed! the index in out of bound!\n", __func__);
return NULL;
} // 正向查找
if (index <= (count/))
{
int i=;
node *pnode=phead->next;
while ((i++) < index)
pnode = pnode->next; return pnode;
} // 反向查找
int j=;
int rindex = count - index - ;
node *rnode=phead->prev;
while ((j++) < rindex)
rnode = rnode->prev; return rnode;
} // 获取“第一个节点”
static node* get_first_node()
{
return get_node();
} // 获取“最后一个节点”
static node* get_last_node()
{
return get_node(count-);
} // 获取“双向链表中第index位置的元素的值”。成功,返回节点值;否则,返回-1。
int dlink_get(int index)
{
node *pindex=get_node(index);
if (!pindex)
{
printf("%s failed!\n", __func__);
return -;
} return pindex->value; } // 获取“双向链表中第1个元素的值”
int dlink_get_first()
{
return dlink_get();
} // 获取“双向链表中最后1个元素的值”
int dlink_get_last()
{
return dlink_get(count-);
} // 将“value”插入到index位置。成功,返回0;否则,返回-1。
int dlink_insert(int index, int value)
{
// 插入表头
if (index==)
return dlink_insert_first(value); // 获取要插入的位置对应的节点
node *pindex=get_node(index);
if (!pindex)
return -; // 创建“节点”
node *pnode=create_node(value);
if (!pnode)
return -; pnode->prev = pindex->prev;
pnode->next = pindex;
pindex->prev->next = pnode;
pindex->prev = pnode;
// 节点个数+1
count++; return ;
} // 将“value”插入到表头位置
int dlink_insert_first(int value)
{
node *pnode=create_node(value);
if (!pnode)
return -; pnode->prev = phead;
pnode->next = phead->next;
phead->next->prev = pnode;
phead->next = pnode;
count++;
return ;
} // 将“value”插入到末尾位置
int dlink_append_last(int value)
{
node *pnode=create_node(value);
if (!pnode)
return -; pnode->next = phead;
pnode->prev = phead->prev;
phead->prev->next = pnode;
phead->prev = pnode;
count++;
return ;
} // 删除“双向链表中index位置的节点”。成功,返回0;否则,返回-1。
int dlink_delete(int index)
{
node *pindex=get_node(index);
if (!pindex)
{
printf("%s failed! the index in out of bound!\n", __func__);
return -;
} pindex->next->prev = pindex->prev;
pindex->prev->next = pindex->next;
free(pindex);
count--; return ;
} // 删除第一个节点
int dlink_delete_first()
{
return dlink_delete();
} // 删除组后一个节点
int dlink_delete_last()
{
return dlink_delete(count-);
} // 撤销“双向链表”。成功,返回0;否则,返回-1。
int destroy_dlink()
{
if (!phead)
{
printf("%s failed! dlink is null!\n", __func__);
return -;
} node *pnode=phead->next;
node *ptmp=NULL;
while(pnode != phead)
{
ptmp = pnode;
pnode = pnode->next;
free(ptmp);
} free(phead);
phead = NULL;
count = ; return ;
} // 打印“双向链表”
void print_dlink()
{
if (count== || (!phead))
{
printf("%s dlink is empty!\n", __func__);
return ;
} printf("%s dlink size()=%d\n", __func__, count);
node *pnode=phead->next;
while(pnode != phead)
{
printf("%d\n", pnode->value);
pnode = pnode->next;
}
}

双向链表的测试程序(dlink_queue.c)

 #include <stdio.h>
#include "double_link.h" /**
* C 语言: 双向链表实现“队列”,只能存储int数据。
*
* @author skywang
* @date 2013/11/07
*/ // 创建队列
int create_dlink_queue()
{
return create_dlink();
} // 销毁队列
int destroy_dlink_queue()
{
return destroy_dlink();
} // 将val添加到队列的末尾
int add(int val)
{
return dlink_append_last(val);
} // 返回“队列开头元素”
int front()
{
return dlink_get_first();
} // 返回并删除“队列开头元素”
int pop()
{
int ret = dlink_get_first();
dlink_delete_first();
return ret;
} // 返回“队列”的大小
int size()
{
return dlink_size();
} // 返回“队列”是否为空
int is_empty()
{
return dlink_is_empty();
} void main()
{
int tmp=; // 创建“队列”
create_dlink_queue(); // 将10, 20, 30 依次队列中
add();
add();
add(); // 将“队列开头的元素”赋值给tmp,并删除“该元素”
tmp = pop();
printf("tmp=%d\n", tmp); // 只将“队列开头的元素”赋值给tmp,不删除该元素.
tmp = front();
printf("tmp=%d\n", tmp); add(); printf("is_empty()=%d\n", is_empty());
printf("size()=%d\n", size());
while (!is_empty())
{
printf("%d\n", pop());
} // 销毁队列
destroy_dlink_queue();
}

代码说明:"运行结果" 以及 "主函数main的逻辑"都和前两个示例的一样。不同的是,该示例中的队列是通过双向链表实现的。

4. C语言实现四:双向链表实现的队列,能存储任意类型的数据

实现代码
双向链表的头文件(double_link.h)

 #ifndef _DOUBLE_LINK_H
#define _DOUBLE_LINK_H // 新建“双向链表”。成功,返回表头;否则,返回NULL
extern int create_dlink();
// 撤销“双向链表”。成功,返回0;否则,返回-1
extern int destroy_dlink(); // “双向链表是否为空”。为空的话返回1;否则,返回0。
extern int dlink_is_empty();
// 返回“双向链表的大小”
extern int dlink_size(); // 获取“双向链表中第index位置的元素”。成功,返回节点指针;否则,返回NULL。
extern void* dlink_get(int index);
// 获取“双向链表中第1个元素”。成功,返回节点指针;否则,返回NULL。
extern void* dlink_get_first();
// 获取“双向链表中最后1个元素”。成功,返回节点指针;否则,返回NULL。
extern void* dlink_get_last(); // 将“value”插入到index位置。成功,返回0;否则,返回-1。
extern int dlink_insert(int index, void *pval);
// 将“value”插入到表头位置。成功,返回0;否则,返回-1。
extern int dlink_insert_first(void *pval);
// 将“value”插入到末尾位置。成功,返回0;否则,返回-1。
extern int dlink_append_last(void *pval); // 删除“双向链表中index位置的节点”。成功,返回0;否则,返回-1
extern int dlink_delete(int index);
// 删除第一个节点。成功,返回0;否则,返回-1
extern int dlink_delete_first();
// 删除组后一个节点。成功,返回0;否则,返回-1
extern int dlink_delete_last(); #endif

双向链表的实现文件(double_link.c)

 #include <stdio.h>
#include <malloc.h> /**
* C 语言: 双向链表,能存储任意数据。
*
* @author skywang
* @date 2013/11/07
*/ // 双向链表节点
typedef struct tag_node
{
struct tag_node *prev;
struct tag_node *next;
void* p;
}node; // 表头。注意,表头不存放元素值!!!
static node *phead=NULL;
// 节点个数。
static int count=; // 新建“节点”。成功,返回节点指针;否则,返回NULL。
static node* create_node(void *pval)
{
node *pnode=NULL;
pnode = (node *)malloc(sizeof(node));
if (!pnode)
{
printf("create node error!\n");
return NULL;
}
// 默认的,pnode的前一节点和后一节点都指向它自身
pnode->prev = pnode->next = pnode;
// 节点的值为pval
pnode->p = pval; return pnode;
} // 新建“双向链表”。成功,返回0;否则,返回-1。
int create_dlink()
{
// 创建表头
phead = create_node(NULL);
if (!phead)
return -; // 设置“节点个数”为0
count = ; return ;
} // “双向链表是否为空”
int dlink_is_empty()
{
return count == ;
} // 返回“双向链表的大小”
int dlink_size() {
return count;
} // 获取“双向链表中第index位置的节点”
static node* get_node(int index)
{
if (index< || index>=count)
{
printf("%s failed! index out of bound!\n", __func__);
return NULL;
} // 正向查找
if (index <= (count/))
{
int i=;
node *pnode=phead->next;
while ((i++) < index)
pnode = pnode->next; return pnode;
} // 反向查找
int j=;
int rindex = count - index - ;
node *rnode=phead->prev;
while ((j++) < rindex)
rnode = rnode->prev; return rnode;
} // 获取“第一个节点”
static node* get_first_node()
{
return get_node();
} // 获取“最后一个节点”
static node* get_last_node()
{
return get_node(count-);
} // 获取“双向链表中第index位置的元素”。成功,返回节点值;否则,返回-1。
void* dlink_get(int index)
{
node *pindex=get_node(index);
if (!pindex)
{
printf("%s failed!\n", __func__);
return NULL;
} return pindex->p; } // 获取“双向链表中第1个元素的值”
void* dlink_get_first()
{
return dlink_get();
} // 获取“双向链表中最后1个元素的值”
void* dlink_get_last()
{
return dlink_get(count-);
} // 将“pval”插入到index位置。成功,返回0;否则,返回-1。
int dlink_insert(int index, void* pval)
{
// 插入表头
if (index==)
return dlink_insert_first(pval); // 获取要插入的位置对应的节点
node *pindex=get_node(index);
if (!pindex)
return -; // 创建“节点”
node *pnode=create_node(pval);
if (!pnode)
return -; pnode->prev = pindex->prev;
pnode->next = pindex;
pindex->prev->next = pnode;
pindex->prev = pnode;
// 节点个数+1
count++; return ;
} // 将“pval”插入到表头位置
int dlink_insert_first(void *pval)
{
node *pnode=create_node(pval);
if (!pnode)
return -; pnode->prev = phead;
pnode->next = phead->next;
phead->next->prev = pnode;
phead->next = pnode;
count++;
return ;
} // 将“pval”插入到末尾位置
int dlink_append_last(void *pval)
{
node *pnode=create_node(pval);
if (!pnode)
return -; pnode->next = phead;
pnode->prev = phead->prev;
phead->prev->next = pnode;
phead->prev = pnode;
count++;
return ;
} // 删除“双向链表中index位置的节点”。成功,返回0;否则,返回-1。
int dlink_delete(int index)
{
node *pindex=get_node(index);
if (!pindex)
{
printf("%s failed! the index in out of bound!\n", __func__);
return -;
} pindex->next->prev = pindex->prev;
pindex->prev->next = pindex->next;
free(pindex);
count--; return ;
} // 删除第一个节点
int dlink_delete_first()
{
return dlink_delete();
} // 删除组后一个节点
int dlink_delete_last()
{
return dlink_delete(count-);
} // 撤销“双向链表”。成功,返回0;否则,返回-1。
int destroy_dlink()
{
if (!phead)
{
printf("%s failed! dlink is null!\n", __func__);
return -;
} node *pnode=phead->next;
node *ptmp=NULL;
while(pnode != phead)
{
ptmp = pnode;
pnode = pnode->next;
free(ptmp);
} free(phead);
phead = NULL;
count = ; return ;
}

双向链表的测试程序(dlink_queue.c)

 #include <stdio.h>
#include "double_link.h" /**
* C 语言: 双向链表实现“队列”,能存储任意数据。
*
* @author skywang
* @date 2013/11/07
*/ // 创建队列
int create_dlink_queue()
{
return create_dlink();
} // 销毁队列
int destroy_dlink_queue()
{
return destroy_dlink();
} // 将p添加到队列的末尾
int add(void *p)
{
return dlink_append_last(p);
} // 返回“队列开头元素”
void* front()
{
return dlink_get_first();
} // 返回“队列开头的元素”,并删除“该元素”
void* pop()
{
void *p = dlink_get_first();
dlink_delete_first();
return p;
} // 返回“队列”的大小
int size()
{
return dlink_size();
} // 返回“队列”是否为空
int is_empty()
{
return dlink_is_empty();
} typedef struct tag_stu
{
int id;
char name[];
}stu; static stu arr_stu[] =
{
{, "sky"},
{, "jody"},
{, "vic"},
{, "dan"},
};
#define ARR_STU_SIZE ( (sizeof(arr_stu)) / (sizeof(arr_stu[0])) ) static void print_stu(stu *p)
{
if (!p)
return ; printf("id=%d, name=%s\n", p->id, p->name);
} void main()
{
stu *pval=NULL; // 创建“队列”
create_dlink_queue(); // 将10, 20, 30 依次推入队列中
int i=;
for (i=; i<ARR_STU_SIZE-; i++)
{
add(&arr_stu[i]);
} // 将“队列开头的元素”赋值给tmp,并删除“该元素”
pval = (stu*)pop();
print_stu(pval) ; // 只将“队列开头的元素”赋值给tmp,不删除该元素.
pval = front();
print_stu(pval) ; add(&arr_stu[ARR_STU_SIZE-]); printf("is_empty()=%d\n", is_empty());
printf("size()=%d\n", size());
// 打印队列中的所有元素
while (!is_empty())
{
pval = pop();
print_stu(pval) ;
} // 销毁队列
destroy_dlink_queue();
}

运行结果

id=, name=sky
id=, name=jody
is_empty()=
size()=
id=, name=jody
id=, name=vic
id=, name=dan

结果说明:该示例中的队列是通过双向链表实现的,并且能存储任意类型的数据。

队列的C++实现

C++的STL中本身就包含了list类,基本上该list类就能满足我们的需求,所以很少需要我们自己来实现。本部分介绍2种C++实现。
1. C++实现一:数组实现的队列,能存储任意类型的数据。
2. C++实现二:C++的 STL 中自带的"队列"(list)的示例。

1. C++实现一:数组实现的队列,能存储任意类型的数据

实现代码
队列的实现文件(ArrayQueue.h)

 #ifndef ARRAY_QUEUE_HXX
#define ARRAY_QUEUE_HXX #include <iostream>
using namespace std; template<class T> class ArrayQueue{
public:
ArrayQueue();
~ArrayQueue(); void add(T t);
T front();
T pop();
int size();
int is_empty(); private:
T *arr;
int count;
}; // 创建“队列”,默认大小是12
template<class T>
ArrayQueue<T>::ArrayQueue()
{
arr = new T[];
if (!arr)
{
cout<<"arr malloc error!"<<endl;
}
} // 销毁“队列”
template<class T>
ArrayQueue<T>::~ArrayQueue()
{
if (arr)
{
delete[] arr;
arr = NULL;
}
} // 将val添加到队列的末尾
template<class T>
void ArrayQueue<T>::add(T t)
{
arr[count++] = t;
} // 返回“队列开头元素”
template<class T>
T ArrayQueue<T>::front()
{
return arr[];
} // 返回并删除“队列末尾的元素”
template<class T>
T ArrayQueue<T>::pop()
{
int i = ;;
T ret = arr[]; count--;
while (i++<count)
arr[i-] = arr[i]; return ret;
} // 返回“队列”的大小
template<class T>
int ArrayQueue<T>::size()
{
return count;
} // 返回“队列”是否为空
template<class T>
int ArrayQueue<T>::is_empty()
{
return count==;
} #endif

队列的测试程序(Main.cpp)

 #include <iostream>
#include "ArrayQueue.h"
using namespace std; /**
* C++ : 数组实现“队列”,能存储任意数据。
*
* @author skywang
* @date 2013/11/07
*/
int main()
{
int tmp=;
ArrayQueue<int> *astack = new ArrayQueue<int>(); // 将10, 20, 30 依次推入队列中
astack->add();
astack->add();
astack->add(); // 将“队列开头元素”赋值给tmp,并删除“该元素”
tmp = astack->pop();
cout<<"tmp="<<tmp<<endl; // 只将“队列开头的元素”赋值给tmp,不删除该元素.
tmp = astack->front();
cout<<"tmp="<<tmp<<endl; astack->add(); cout<<"is_empty()="<<astack->is_empty()<<endl;
cout<<"size()="<<astack->size()<<endl;
while (!astack->is_empty())
{
tmp = astack->pop();
cout<<tmp<<endl;
} return ;
}

运行结果

tmp=
tmp=
is_empty()=
size()=

结果说明:关于"队列的声明和实现都在头文件中"的原因,是因为队列的实现利用了C++模板,而"C++编译器不能支持对模板的分离式编译"。

2. C++实现二:C++的 STL 中自带的"队列"(list)的示例

实现代码(StlQueue.cpp)

 #include <iostream>
#include <queue>
using namespace std; /**
* C++ : STL中的队列(queue)的演示程序。
*
* @author skywang
* @date 2013/11/07
*/
int main ()
{
int tmp=;
queue<int> iqueue; // 将10, 20, 30 依次加入队列的末尾
iqueue.push();
iqueue.push();
iqueue.push(); // 删除队列开头的元素
iqueue.pop(); // 将“队列开头的元素”赋值给tmp,不删除该元素.
tmp = iqueue.front();
cout<<"tmp="<<tmp<<endl; // 将40加入到队列的末尾
iqueue.push(); cout << "empty()=" << iqueue.empty() <<endl;
cout << "size()=" << iqueue.size() <<endl;
while (!iqueue.empty())
{
tmp = iqueue.front();
cout<<tmp<<endl;
iqueue.pop();
} return ;
}

运行结果

tmp=
empty()=
size()=

队列的Java实现

和C++一样,JDK包Queue中的也提供了"队列"的实现。JDK中的Queue接口就是"队列",它的实现类也都是队列,用的最多的是LinkedList。本部分介绍给出2种Java实现
1. Java实现一:数组实现的队列,能存储任意类型的数据。
2. Java实现二:Java的 Collection集合 中自带的"队列"(LinkedList)的示例。

1. Java实现一:数组实现的队列,能存储任意类型的数据

实现代码(ArrayQueue.java)

 /**
* Java : 数组实现“队列”,只能存储int数据。
*
* @author skywang
* @date 2013/11/07
*/
public class ArrayQueue { private int[] mArray;
private int mCount; public ArrayQueue(int sz) {
mArray = new int[sz];
mCount = 0;
} // 将val添加到队列的末尾
public void add(int val) {
mArray[mCount++] = val;
} // 返回“队列开头元素”
public int front() {
return mArray[0];
} // 返回“栈顶元素值”,并删除“栈顶元素”
public int pop() {
int ret = mArray[0];
mCount--;
for (int i=1; i<=mCount; i++)
mArray[i-1] = mArray[i];
return ret;
} // 返回“栈”的大小
public int size() {
return mCount;
} // 返回“栈”是否为空
public boolean isEmpty() {
return size()==0;
} public static void main(String[] args) {
int tmp=0;
ArrayQueue astack = new ArrayQueue(12); // 将10, 20, 30 依次推入栈中
astack.add(10);
astack.add(20);
astack.add(30); // 将“栈顶元素”赋值给tmp,并删除“栈顶元素”
tmp = astack.pop();
System.out.printf("tmp=%d\n", tmp); // 只将“栈顶”赋值给tmp,不删除该元素.
tmp = astack.front();
System.out.printf("tmp=%d\n", tmp); astack.add(40); System.out.printf("isEmpty()=%b\n", astack.isEmpty());
System.out.printf("size()=%d\n", astack.size());
while (!astack.isEmpty()) {
System.out.printf("size()=%d\n", astack.pop());
}
}
}

运行结果

tmp=10
tmp=20
isEmpty()=false
size()=3
size()=20
size()=30
size()=40

结果说明:ArrayQueue是通过数组实现的队列,而且ArrayQueue中使用到了泛型,因此它支持任意类型的数据。

2. Java实现二:Java的 Collection集合 中自带的"队列"(LinkedList)的示例

实现代码(QueueTest.java)

 import java.util.Stack;

 /**
* 用“栈”实现队列
*
* @author skywang
*/
public class StackList<T> { // 向队列添加数据时:(01) 将“已有的全部数据”都移到mIn中。 (02) 将“新添加的数据”添加到mIn中。
private Stack<T> mIn = null;
// 从队列获取元素时:(01) 将“已有的全部数据”都移到mOut中。(02) 返回并删除mOut栈顶元素。
private Stack<T> mOut = null;
// 统计计数
private int mCount = 0; public StackList() {
mIn = new Stack<T>();
mOut = new Stack<T>();
mCount = 0;
} private void add(T t) {
// 将“已有的全部数据”都移到mIn中
while (!mOut.empty())
mIn.push(mOut.pop()); // 将“新添加的数据”添加到mIn中
mIn.push(t);
// 统计数+1
mCount++;
} private T get() {
// 将“已有的全部数据”都移到mOut中
while (!mIn.empty())
mOut.push(mIn.pop());
// 统计数-1
mCount--; // 返回并删除mOut栈顶元素
return mOut.pop();
} private int size() {
return mCount;
}
private boolean isEmpty() {
return mCount==0;
} public static void main(String[] args) {
StackList slist = new StackList(); // 将10, 20, 30 依次推入栈中
slist.add(10);
slist.add(20);
slist.add(30); System.out.printf("isEmpty()=%b\n", slist.isEmpty());
System.out.printf("size()=%d\n", slist.size());
while(!slist.isEmpty()) {
System.out.printf("%d\n", slist.get());
}
}
}

运行结果

tmp=10
tmp=20
isEmpty()=false
size()=3
tmp=20
tmp=30
tmp=40

队列的图文解析 和 对应3种语言的实现(C/C++/Java)的更多相关文章

  1. 栈的图文解析 和 对应3种语言的实现(C/C++/Java)

    概要 本章会先对栈的原理进行介绍,然后分别通过C/C++/Java三种语言来演示栈的实现示例.注意:本文所说的栈是数据结构中的栈,而不是内存模型中栈.内容包括:1. 栈的介绍2. 栈的C实现3. 栈的 ...

  2. 栈的图文解析 和 对应3种语言的实现(C/C++/Java)【转】

    概要 本章会先对栈的原理进行介绍,然后分别通过C/C++/Java三种语言来演示栈的实现示例.注意:本文所说的栈是数据结构中的栈,而不是内存模型中栈.内容包括:1. 栈的介绍2. 栈的C实现3. 栈的 ...

  3. 选择排序的3种语言实现方法(C java python)

    1.选择排序的思路是:遍历数组,第一遍找出所有成员的最小值,放到数组下标为0的位置,第二遍从剩余内容中,再次找出最小值,放到数组下标为1的位置,以此类推,遍历完成所有的数组内容,最后结果就是:数组是按 ...

  4. 数据结构图文解析之:队列详解与C++模板实现

    0. 数据结构图文解析系列 数据结构系列文章 数据结构图文解析之:数组.单链表.双链表介绍及C++模板实现 数据结构图文解析之:栈的简介及C++模板实现 数据结构图文解析之:队列详解与C++模板实现 ...

  5. 数据结构图文解析之:直接插入排序及其优化(二分插入排序)解析及C++实现

    0. 数据结构图文解析系列 数据结构系列文章 数据结构图文解析之:数组.单链表.双链表介绍及C++模板实现 数据结构图文解析之:栈的简介及C++模板实现 数据结构图文解析之:队列详解与C++模板实现 ...

  6. 数据结构图文解析之:数组、单链表、双链表介绍及C++模板实现

    0. 数据结构图文解析系列 数据结构系列文章 数据结构图文解析之:数组.单链表.双链表介绍及C++模板实现 数据结构图文解析之:栈的简介及C++模板实现 数据结构图文解析之:队列详解与C++模板实现 ...

  7. 数据结构图文解析之:栈的简介及C++模板实现

    0. 数据结构图文解析系列 数据结构系列文章 数据结构图文解析之:数组.单链表.双链表介绍及C++模板实现 数据结构图文解析之:栈的简介及C++模板实现 数据结构图文解析之:队列详解与C++模板实现 ...

  8. 数据结构图文解析之:AVL树详解及C++模板实现

    0. 数据结构图文解析系列 数据结构系列文章 数据结构图文解析之:数组.单链表.双链表介绍及C++模板实现 数据结构图文解析之:栈的简介及C++模板实现 数据结构图文解析之:队列详解与C++模板实现 ...

  9. 数据结构图文解析之:二叉堆详解及C++模板实现

    0. 数据结构图文解析系列 数据结构系列文章 数据结构图文解析之:数组.单链表.双链表介绍及C++模板实现 数据结构图文解析之:栈的简介及C++模板实现 数据结构图文解析之:队列详解与C++模板实现 ...

随机推荐

  1. Hibernate入门3.配置映射文件深入

    Hibernate入门3.配置映射文件深入 2013.11.27 前言: 之前的两节是在Java项目中如何使用hibernate,并且通过一个简单地项目实践,期间有很多的错误,一般都是因为配置包的问题 ...

  2. JQ中mouseover和mouseenter的区别

    我最近也在学习JQuery,所以最近对JQ中的一些小问题进行总结,方便学习. 在对于刚开始学习JQ的初学者来说,mouseover事件和mouseenter事件总是傻傻分不清楚,毕竟刚开始学习的时候, ...

  3. 转:最简单的基于 DirectShow 的视频播放器

    50行代码实现的一个最简单的基于 DirectShow 的视频播放器 本文介绍一个最简单的基于 DirectShow 的视频播放器.该播放器对于初学者来说是十分有用的,它包含了使用 DirectSho ...

  4. android如何播放和录制音频

    视频录制功能正在走来,在Androidsdk中有与之相关的类:android.media.MediaRecorder.当然,因为模拟器上没有提供必要的硬件设施,所以在学习过程中并不能实现.Media能 ...

  5. 十进制转二进制and位运算符

    先给大家送个福利! ---------------简单口算-------------------------- 10 >>  1010   除2取余倒写 /* 十进制转二进制规则是:除二取 ...

  6. android 虚线

    <?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http: ...

  7. 使用cxf开发webservice应用时抛出异常

    在使用cxf开发webservice应用时,报出了类似下面的错误 JAXB: [javax.xml.bind.UnmarshalException: unexpected element (uri:& ...

  8. ECShop在任何页面调用最新文章并变成随机文章

    一.让最新文章变成随机文章 在根目录 打开index.php文件 查找代码 ' ORDER BY a.article_type DESC, a.add_time DESC LIMIT ' . $GLO ...

  9. iOS开发 - AVPlayer实现流音频边播边存

    边播边下有三套左右实现思路,本文使用AVPlayer + AVURLAsset实现. 概述 1. AVPlayer简介 AVPlayer存在于AVFoundation中,可以播放视频和音频,可以理解为 ...

  10. sql优化之(DMV)

    原文地址:http://technet.microsoft.com/zh-cn/library/bb838723.aspx Microsoft SQL Server 2005 提供了一些工具来监控数据 ...