您的位置:首页 > 理论基础 > 数据结构算法

栈和队列(C链表实现)

2017-12-27 14:53 183 查看
  栈和队列是两种很有用的数据结构,栈是先进后出(FILO),队列是先进先出(FIFO)。

  在迷宫求解,括号匹配,递归这些问题里,栈的应用非常广泛,而队列在操作系统的进程排队,线程池里很有用。C中没有现成的栈和队列,这里用链表来模拟一下。设计时分别用到两个结构体,将链表节点部分和控制作用的表头分开,方便管理。

   

在栈的设计中,使用表头指向栈的top ,每次入栈只需将新节点指向表头,表头再指向新节点便可,出栈也是将top指向下一个节点,先前的节点释放。

#include "malloc.h"
#include "stdio.h"
#include "assert.h"

#define OK 0
#define ERRO 1

typedef int status;
typedef int SdataType;

typedef struct Node {
SdataType data;
Node * next;
}Node;
typedef struct Stack {
Node * top;
int size;
}Stack;

//新建Stack
Stack* createStack(void) {
Stack* s = (Stack*)malloc(sizeof(Stack));
assert(s);
s->top = NULL;
s->size = 0;
return s;
}

//因为有size成员,所以不需要判空函数

//入栈函数
status push(Stack* s, SdataType value) {
Node * p = (Node *)malloc(sizeof(Node));
assert(p);
p->data = value;
p->next = s->top;
s->top = p;
s->size++;
return OK;
}

status pop(Stack* s, SdataType* value) {
if (s->size == 0) {
printf("stack empty\n");
return ERRO;
}
else
{
Node* p = s->top;
*value = s->top->data;
s->top = s->top->next;
free(p);
s->size--;
return OK;
}
}

void showStack(Stack* s) {
assert(s);
if (s->size == 0 ) {
printf("stack empty\n");
}
else {
Node* p = s->top;
printf("top->");
while (p->next) {
printf("%d ->", p->data);
p = p->next;
}
printf("%d ->end\n", p->data);

}
}

status destroyStack(Stack *s) {
if (s->top) {
int i;
Node *p = s->top;
for (i = 0; i < s->size; i++) {
s->top = p->next;
free(p);
p = s->top;
}
free(s);
assert(s);
return OK;
}
else
{
printf("stack empty\n");
return ERRO;
}
}
int main(int argc, char **argv) {
Stack* s = createStack();
push(s, 1);
push(s, 2);
showStack(s);
destroyStack(s);

}


对于栈来说,我们只需要管好它的栈顶就行了,但是队列的话得两头都处理,所以表头结构体加一个队尾指针。并且在队列节点中增加了一个头结点,这时为了避免每次入队的时候判断是否时第一个节点带来的多余工作,头结点中内容为空。

#include "malloc.h"
#include "stdio.h"
#include "assert.h"

#define OK 0
#define ERRO 1

typedef int status;
typedef int QdataType;

typedef struct Node {
QdataType data;
Node * next;
}Node;
typedef struct Queue {
Node * head;
Node * rear;
int size;
}Queue;

//新建Queue
Queue* createStack(void) {
Queue* q = (Queue*)malloc(sizeof(Queue));
assert(q);
Node* p = (Node*)malloc(sizeof(Node));  //头结点,其内容为空,只是为了入队时不必判断队为空
assert(p);
p->next = NULL;
p->data = 0;
q->head = q->rear = p;
q->size = 0;
return q;
}

//尾部入,头部出
//进队函数
status enQueue(Queue* q, QdataType value) {
Node * p = (Node *)malloc(sizeof(Node));
assert(p);
p->data = value;
p->next = NULL;
q->rear->next = p;
q->rear = p;
q->size++;
return OK;
}

status deQueue(Queue* q, QdataType* value) {
if (q->size == 0) {
printf("queue empty\n");
return ERRO;
}
else
{
Node* p = q->head->next;
*value = q->head->next->data;
q->head->next = q->head->next->next;
free(p);
q->size--;
return OK;
}
}

void showQueue(Queue* q) {

if (q->size == 0 ) {
printf("queue empty\n");
}
else {
Node* p = q->head->next;
printf("head->");
while (p->next) {
printf("%d ->", p->data);
p = p->next;
}
printf("%d ->end\n", p->data);

}
}

status destroyQueue(Queue *q) {
if (q->size) {
int i;
Node *p = q->head;
for (i = 0; i <= q->size; i++) {
q->head = p->next;
free(p);
p = q->head;
}
free(q);
return OK;
}
else
{
free(q);
return ERRO;
}
}
int main(int argc, char **argv) {
Queue* q = createStack();
QdataType a = 0;
QdataType* data = &a;

enQueue(q, 1);
enQueue(q, 2);
enQueue(q, 3);
showQueue(q);
deQueue(q,data);
showQueue(q);
destroyQueue(q);
return OK;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息