Chinaunix首页 | 论坛 | 博客
  • 博客访问: 162335
  • 博文数量: 41
  • 博客积分: 647
  • 博客等级: 上士
  • 技术积分: 366
  • 用 户 组: 普通用户
  • 注册时间: 2011-08-29 14:13
文章分类

全部博文(41)

文章存档

2013年(11)

2012年(1)

2011年(29)

分类: C/C++

2011-11-30 13:11:59

1,队列的实现
 
 
1,用数组实现的队列
   队列的特征是:先进先出(fifo)
   队列数据结构的操作是:从队列首部出队列,从队列的尾部入队列。
   一般是用动态数组实现队列,在创建队列时队列的元素个数已经确定。
 
/*
 * 用数组实现的循环队列
 *
 * 要注意:队列的头指针和尾指针都在变化
 */
#include "all.h"
#define ERROR -1
#define OK 0
typedef char Elem_type;
struct queue {
 Elem_type *base;  //队列指针
 int front;   //队列头指针
 int rear;   //队列尾指针
 int maxlen;   //队列长度
 int size;   //队列长度
};
typedef struct queue QUEUE;

QUEUE *create_queue(int maxlen)
{
 QUEUE *q;   
 
 q = (QUEUE *)malloc(sizeof(QUEUE));
 if (NULL == q)
  return NULL;
 q->base = (Elem_type *)malloc(sizeof(Elem_type)*maxlen);
 if (NULL == q->base)
  return NULL;
 q->maxlen = maxlen;
 q->front = 0;
 q->rear = 0;
 q->size = 0;
 return q; 
}
 
int is_full(QUEUE *q)
{
 if (q->rear >= q->maxlen)
  return 1;
 else
  return 0;
}
 
//入队
int enqueue(QUEUE *q, Elem_type val)
{
 /*
  * if ((q->rear+1)%q->maxlen == q->front) //队列满,也可以这样判断
  */
 if (q->size >= q->maxlen) {        //队列满
  fprintf(stderr, "error: queue full!\n");
  return ERROR;
 }
 q->base[q->rear] = val; 
 q->rear = (q->rear+1)%q->maxlen; //若rear是maxlen(队列满)就回绕到0的位置
 q->size += 1;
 return OK;
}

//出队
int dequeue(QUEUE *q, Elem_type *val)
{
 if (q->size <= 0) {               //注意边界条件
  printf("error: empty queue!\n");
  return ERROR;
 }
 *val = q->base[q->front];   //取头部元素
 q->front = (q->front+1)%q->maxlen; //调整头指针,若到了队列尾部,绕回
 q->size -= 1; //size-1
 return OK;
}
 
 
//测试例程
#define MAXLEN 5
int main(void)
{
 char a[MAXLEN] = {'\0'};
 QUEUE *q;
 char *p;
 char v;
 fgets(a, MAXLEN, stdin);
 a[strlen(a)-1] = '\0';
 printf("a=[%s]\n", a);
 q = create_queue(MAXLEN-3);
 if (!q) {
  printf("create stack error!\n");
  return 1;
 }
 p = a; 
 while ('\0' != *p) {
  enqueue(q, *p);
  p++;
 }
  
 printf("\n-----dequeue size=[%d]-----\n", q->size);
 while (OK == dequeue(q, &v)) {
    printf("%c\n", v);
 }
 printf("\nend\n");
 return 0;
}
 
 
2,用链表实现的队列
 
/*
 * 链表实现的队列
 *
 * 链表实现的队列思想是: 维护两个指针(头、尾指针)来进行出对和入队的操作。
 * 入队:从链表尾部插入节点
 * 出对:从链表头删除节点,并取得头结点的值。
 *
 * hover 2011-03-17
 */
#include "all.h"

typedef char Elemtype;
//结点结构
struct node {
    struct node *next;
    Elemtype data;
};
typedef struct node Node;
//队列管理结构
struct queue {
    Node *front;
    Node *rear;
    int size;
};
typedef struct queue Queue;

 
//创建队列
Queue *create_queue(int maxlen)
{
    Queue *q;
 
    q = (Queue *)malloc(sizeof(Queue));
    if (!q) {
        fprintf(stderr, "malloc error!\n");
        return NULL;
    }
    q->front = q->rear = NULL;   //不带头结点的链表
    q->size = 0;                 //元素个数是0
    return q;
}
 
//入队 :从链表尾部插入结点
int enqueue(Queue *q, Node *node)
{
    if (!q || !node)
        return  ERROR;
  
    node->next = NULL;      //入队时需要从尾结点插入
    if (is_empty(q)) {      //空队列
        q->rear = node;
        q->front = node;
    } else {
        q->rear->next = node;   //添加结点到尾部
        q->rear = node;         //移动尾结点
    }
    q->size += 1;
    return OK;
}
 
//出对:删除头结点
int dequeue(Queue *q, Elemtype *val)
{
    Node *pnode;
    if (!q)
        return ERROR;
      
    //if (q->front == NULL) {       //空队列
    if (is_empty(q)) {      //空队列
        fprintf(stderr, "empty queue!\n");
        return ERROR;
    }  
    pnode = q->front->next;
    *val = q->front->data;      //得到头结点的值
    free(q->front);
    q->front = pnode;           //删除后移动头指针
    if (NULL == pnode)      //若是最后一个节点
        q->rear = NULL;     //注意:不要忘记更新尾结点
    q->size -= 1;
    return OK;
}
阅读(5331) | 评论(0) | 转发(2) |
0

上一篇:字符串算法

下一篇:栈。。。。

给主人留下些什么吧!~~