周末写代码
--------------------------------2018.8.7---------------------------
1. stack 栈
stack 后进先出(LIFO)结构。下面用数组实现栈,用malloc使栈的容量可扩展。
stack.c
这里要特别注意:
(1) Destroy()函数中,free(s->data); 以及 s->data = NULL; 否则出现野指针。因为在Init()中用了malloc;
(2) 另外,取栈顶元素 Top() 函数 不要用返回值,因为如果栈空就没有元素可以返回。用指针传参好了: void Top(Stack *s, datatype * topElement)
(3) 初始化函数 bool Init()要加入判断条件,判断s->data 是否是NULL,因为malloc 若在heap里面分配内存不成功就返回NULL,因此初始化函数也返回bool,初始化不成功返回false
#include "stack.h"
#include <stdio.h>
static int realsize = MAXSIZE;
// initialize the stack
bool Init(Stack *s)
{
s->data = (datatype *)malloc(sizeof(datatype) * MAXSIZE);
s->top = -1;
if (s->data != NULL)
return true;
else
return false;
}
// is the stack empty?
bool isEmpty(Stack *s)
{
if(s->top == -1)
{
return true;
}
else
{
return false;
}
}
// enlarge the capacity of the stack
void enlarge(Stack *s)
{
if(s->top == realsize - 1)
{
realsize *= 2;
s->data = (datatype *)realloc(s->data, realsize * sizeof(datatype));
}
}
// push element into the stack
void Push(Stack *s, datatype element)
{
enlarge(s);
s->top++;
s->data[s->top] = element;
}
// pop element out of the stack
void Pop(Stack *s)
{
if(!isEmpty(s))
{
s->top--;
}
else
{
printf("stack is empty, can not be poped!\n");
}
}
// get the top element of the stack
void Top(Stack *s, datatype * topElement)
{
if(!isEmpty(s))
{
*topElement = s->data[s->top];
}
else
{
printf("stack is empty, no top element!\n");
}
}
// destroy the stack
void Destroy(Stack *s)
{
s->top = -1;
free(s->data);
s->data = NULL;
}
stack.h
#ifndef STACK_H
#define STACK_H
#include<stdbool.h>
#include<stdlib.h>
#define MAXSIZE 10
typedef int datatype;
//Sequence Stack
typedef struct stack
{
datatype *data; // array
int top;
} Stack;
// initialize the stack
bool Init(Stack *s);
// is the stack empty?
bool isEmpty(Stack *s);
// enlarge the capacity of the stack
void enlarge(Stack *s);
// push element into the stack
void Push(Stack *s, datatype element);
// pop element out of the stack
void Pop(Stack *s);
// get the top element of the stack
void Top(Stack *s, datatype * topElement);
// destroy the stack
void Destroy(Stack *s);
#endif
main.c
#include "stack.h"
#include <stdio.h>
int main(void)
{
// build a stack
Stack * s = (Stack*)malloc(sizeof(Stack));
// initialize the stack
if (!Init(s))
return 1;
// is empty?
if (isEmpty(s))
printf("stack is empty \n");
else
printf("stack is not empty \n");
// push 22 elements into the stack
for (datatype i = 0; i < 22; ++i)
Push(s, i);
// what is the top element
datatype i = -1;
datatype * topElement = &i;
Top(s, topElement);
printf("%d\n", *topElement);
// pop 10 elements out of the stack
for (datatype i = 0; i < 10; ++i)
Pop(s);
// what is the top element of the stack now?
i = -1;
Top(s, topElement);
printf("%d\n", *topElement);
// destroy the stack
Destroy(s);
// what is the top element of the stack now?
i = -1;
Top(s, topElement);
printf("%d\n", *topElement);
return 0;
}
CMakeLists.txt
cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
project(stack)
add_compile_options(-std=c11)
add_executable (stack main.c stack.c)
结果如下:
2. Queue 队列
队列是先进先出(FIFO)结构。下面用链表实现队列
queue.c
#include "queue.h"
#include <stdlib.h>
// initialize a queue
void InitQueue(Queue* queue)
{
if (queue == NULL)
return;
queue->tail = (Node*)malloc(sizeof(Node));
if (queue->tail == NULL)
return;
queue->tail->data = -1;
queue->head = queue->tail;
queue->tail->next = NULL;
}
// push a element into the queue
void PushQueue(Queue* queue, datatype data)
{
if (queue == NULL)
return;
Node * newNode = (Node*)malloc(sizeof(Node));
if (newNode == NULL)
return;
newNode->data = data;
newNode->next = NULL;
queue->tail->next = newNode;
queue->tail = newNode;
}
// pop a element out of the queue
void PopQueue(Queue* queue)
{
if (queue == NULL)
return;
if (IsEmpty(queue))
return;
datatype popValue = queue->head->data;
Node *popNode = queue->head;
queue->head = queue->head->next;
free(popNode);
popNode = NULL;
}
// is the queue empty?
bool IsEmpty(Queue* queue)
{
return (queue->head == queue->tail);
}
// destroy the queue
void DestroyQueue(Queue* queue)
{
if (queue == NULL)
return;
while(!IsEmpty(queue))
{
PopQueue(queue);
}
free(queue->tail);
// free(queue->head);
}
// print the queue
void PrintQueue(Queue* queue)
{
if (queue == NULL)
return;
if(IsEmpty(queue))
{
printf("empty queue.\n");
return;
}
Node* curNode= queue->head->next;
while(curNode)
{
if (curNode->next !=NULL)
printf("%d==>", curNode->data);
else
printf("%d ", curNode->data);
curNode = curNode->next;
}
printf("\n");
}
queue.h
#ifndef QUEUE_H
#define QUEUE_H
#include <stdio.h>
#include<stdbool.h>
typedef int datatype;
typedef struct node
{
datatype data;
struct node* next;
} Node;
typedef struct queue
{
Node* head;
Node* tail;
} Queue;
// initialize a queue
void InitQueue(Queue*);
// push a element into the queue
void PushQueue(Queue*, datatype);
// pop a element out of the queue
void PopQueue(Queue* queue);
// print the queue
void PrintQueue(Queue* queue);
// is the queue empty?
bool IsEmpty(Queue* queue);
// destroy the queue
void DestroyQueue(Queue* queue);
#endif
main.c
#include "queue.h"
#include <stdlib.h>
int main(void)
{
Queue * queue = (Queue*)malloc(sizeof(Queue));
InitQueue(queue);
for (datatype i = 0; i != 4; ++i)
PushQueue(queue, i);
PrintQueue(queue);
PopQueue(queue);
PrintQueue(queue);
for (int i = 0; i != 10; ++i)
PopQueue(queue);
PrintQueue(queue);
for (datatype i = 0; i != 5; ++i)
PushQueue(queue, i);
PrintQueue(queue);
DestroyQueue(queue);
PrintQueue(queue);
free(queue);
queue = NULL;
return 0;
}
CMakeLists.txt
cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
project(stack)
add_compile_options(-std=c11)
add_executable (stack main.c stack.c)
结果: