<2014 05 16> 线性表、栈与队列——一个环形队列的C语言实现

  栈与队列都是具有特殊存取方式的线性表,栈属于先进后出(FILO),而队列则是先进先出(FIFO)。栈能够将递归问题转化为非递归问题,这是它的一个重要特性。除了FILO、FIFO这样的最普遍存取方式外,还有一些扩展的数据结构,如双端队列、双栈、超队列、超栈等,它们是一种扩展与变异结构。

  线性表有顺序存储和链接存储两类,这是针对计算机的线性存储空间作出的分类。前者可以是数组,后者可以是链表。字符串是线性表最常见的应用。

  这里我用C语言实现了一个基于数组环形队列,它具有固定的队列空间。相比于链表实现,它非常小巧和高效,特别是在负载可预计的情况下。

//fifo.h

#ifndef __FIFO_H__

#define __FIFO_H__



#define FIFO_LENGTH 20

#define EMPTY    0x00

#define FULL    0x01

#define NORMAL  0x02



typedef struct require_fifo{

    int item[FIFO_LENGTH];

    int read_ptr;

    int write_ptr;

    int flag;

}fifo;



extern fifo* fifo_create(void);

extern void fifo_destroy(fifo* fifo_ptr);

extern void fifo_in(fifo* fifo_ptr, int data);

extern int fifo_out(fifo* fifo_ptr);



#endif
//fifo.c

#include <stdio.h>

#include <unistd.h>

#include <stdlib.h>

#include <memory.h>

#include "fifo.h"



fifo* fifo_create(void);

void fifo_destroy(fifo* fifo_ptr);

void fifo_in(fifo* fifo_ptr, int data);

int fifo_out(fifo* fifo_ptr);



fifo* fifo_create(void){

    fifo *fifo_ptr = malloc(sizeof(fifo));

    memset(fifo_ptr, 0, sizeof(fifo));

    fifo_ptr->write_ptr = 0;

    fifo_ptr->read_ptr = 0;

    fifo_ptr->flag = EMPTY;

    return fifo_ptr;

}



void fifo_destroy(fifo* fifo_ptr){

    free(fifo_ptr);

    printf("destroy fifo \n");

}



void fifo_in(fifo* fifo_ptr, int data){

    if(fifo_ptr->flag != FULL ){

        fifo_ptr->item[fifo_ptr->write_ptr] = data;

        fifo_ptr->write_ptr ++;

        fifo_ptr->write_ptr %= FIFO_LENGTH;

        if((fifo_ptr->write_ptr - fifo_ptr->read_ptr) == -1){

            fifo_ptr->flag = FULL;

        }else{

            fifo_ptr->flag = NORMAL;

        }

        //printf("write_ptr = %d \n", fifo_ptr->write_ptr);

    }else{

        printf("fifo is full, write invalide\n");

    }

}



int fifo_out(fifo* fifo_ptr){

    int data = 0;



    if(fifo_ptr->flag != EMPTY){

        data = fifo_ptr->item[fifo_ptr->read_ptr];

        fifo_ptr->read_ptr ++;

        fifo_ptr->read_ptr %= FIFO_LENGTH;

        if((fifo_ptr->write_ptr - fifo_ptr->read_ptr) == 0){

            fifo_ptr->flag = EMPTY;    

        }

        //printf("read_ptr = %d \n", fifo_ptr->read_ptr);

        return data;

    }else{

        printf("fifo is empty, read invalide\n");

        return -1;

    }



    return -1;

}

  我们可以写一个测试代码来测试它的性能:

#include <stdio.h>

#include <pthread.h>

#include <signal.h>

#include <unistd.h>

#include <sys/types.h>

#include "../fifo.h"



pthread_mutex_t lock_fifo;

fifo* myfifo;



void * producer_thread1(void *pin){

    pin = NULL;

    while(1){

        pthread_mutex_lock(&lock_fifo);

        fifo_in(myfifo, 1);

        pthread_mutex_unlock(&lock_fifo);

        printf("producer1 put 1 into myfifo\n");

        usleep(2000000);

    }

        return((void*)0);

}



void * producer_thread2(void *pin){

    pin = NULL;

    while(1){

        pthread_mutex_lock(&lock_fifo);

        fifo_in(myfifo, 2);

        pthread_mutex_unlock(&lock_fifo);

        printf("producer2 put 2 into myfifo\n");

        usleep(1500000);

    }

        return((void*)0);

}



void * consumer_thread1(void *pin){

    int require = 0;

    pin = NULL;

    

    while(1){

        pthread_mutex_lock(&lock_fifo);

        require = fifo_out(myfifo);

        pthread_mutex_unlock(&lock_fifo);

        printf("    consumer1 get %d form myfifo\n", require);

        usleep(1000000);

    }

        return((void*)0);

}



void * consumer_thread2(void *pin){

    int require = 0;

    pin = NULL;

    

    while(1){

        pthread_mutex_lock(&lock_fifo);

        require = fifo_out(myfifo);

        pthread_mutex_unlock(&lock_fifo);

        printf("    consumer2 get %d form myfifo\n", require);

        usleep(1000000);

    }

        return((void*)0);

}



void keyboard_exit(int signo){

    printf("exit by keyboard \n");

    fifo_destroy(myfifo);

    _exit(0);

}



int main(){

    pthread_t th_producer1, th_producer2, th_consumer1, th_consumer2;

    void * ret;

    

    pthread_mutex_init(&lock_fifo, NULL);

    myfifo = fifo_create();

    signal(SIGINT, keyboard_exit);

    pthread_create(&th_producer1, NULL, producer_thread1, 0);    

    pthread_create(&th_producer2, NULL, producer_thread2, 0);    

    pthread_create(&th_consumer1, NULL, consumer_thread1, 0);    

    pthread_create(&th_consumer2, NULL, consumer_thread2, 0);    

    

    pthread_join(th_producer1, &ret);

    pthread_join(th_producer2, &ret);

    pthread_join(th_consumer1, &ret);

    pthread_join(th_consumer2, &ret);



    while(1){

        printf("thread error\n");

    }

    return 1;

}

  写一个gcc的Makefile文件来编译链接:

CC = gcc

CFLAGS := -g -Wall 

LIB := -lpthread 

OBJ = ../fifo.o ./test.o

all: demo



demo:test fifo

    $(CC) $(CFLAGS) -o ./demo $(OBJ) $(LIB)



test:

    $(CC) $(CFLAGS) -o ./test.o -c ./test.c

fifo:

    $(CC) $(CFLAGS) -o ../fifo.o -c ../fifo.c



clean:

    rm ./test.o ./demo ../fifo.o





.PHONY: $(PHONY) clean

  在test目录下运行./demo。

  输出结果:

                            write_ptr = 1 

producer1 put 1 into myfifo

                            write_ptr = 2 

producer2 put 2 into myfifo

                            read_ptr = 1 

    consumer1 get 1 form myfifo

                            read_ptr = 2 

    consumer2 get 2 form myfifo

fifo is empty, read invalide

    consumer1 get -1 form myfifo

fifo is empty, read invalide

    consumer2 get -1 form myfifo

                            write_ptr = 3 

producer2 put 2 into myfifo

                            write_ptr = 4 

producer1 put 1 into myfifo

                            read_ptr = 3 

    consumer1 get 2 form myfifo

                            read_ptr = 4 

    consumer2 get 1 form myfifo

                            write_ptr = 5 

producer2 put 2 into myfifo

                            read_ptr = 5 

。。。。

。。。。

^Cexit by keyboard 

destroy fifo 

 

你可能感兴趣的:(C语言)