C语言数据结构拉练----队列,堆栈

数据结构 = 结构定义 + 结构操作

1 队列(循环队列消除假溢出)

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define COLOR(a, b) "\033[" #b "m" a "\033[0m"
#define GREEN(a) COLOR(a, 32)

1.1 结构定义

(1)数组, (2)队首, 队尾, (3)队列容量, (4)队列长度

typedef struct Queue {
	int *data;
	int head, tail;
	int size;
	int length;
} Queue;

1.2 结构操作

初始化/清除

Queue *init(int n) {
	Queue *q = (Queue *)malloc(sizeof(Queue));
	q->data = (int *)malloc(sizeof(int) * n);
	q->size = n;
	q->length = 0;
	q->head = q->tail = 0;
	return q;
}

void clear(Queue *q) {
	if(!q) return;
	free(q->data);
	free(q);
	return;
}

显示队首, 队列空标识

int front(Queue *q) {
	return q->data[q->head];
}

int empty(Queue *q) {
	return q->length == 0;
}

循环队列扩容

采用malloc, 不建议使用realloc
malloc返回值为NULL即为开辟新空间失败

int expand(Queue* q) {
	int extr_size = q->size;
	int *p;
	while (extr_size) {
		p = (int *)malloc(sizeof(int) * (q->size + extr_size));
		if (p) break;
		extr_size >> 1;
	}
	if (!p) return 0;
	for (int i = q->head, j = 0; j < q->length; ++i, ++j) {
		p[j] = q->data[i % q->length];
	}
	free(q->data);
	q->data = p;
	q->size += extr_size;
	q->head = 0;
	q->tail = q->length;
	return 1;
}

入队/出队/显示

int push(Queue* q, int val) {
	if (!q) return 0;
	if (q->length == q->size) {
		if (!expand(q)) return 0;
		printf(GREEN("expand success! Queue->size(%d)\n"), q->size);
	}
	q->data[q->tail] = val;
	q->tail++;
	if (q->tail == q->size) q->tail = 0;
	q->length++;
	return 1;
}

int pop(Queue* q) {
	if (!q) return 0;
	if (empty(q)) return 0;
	q->head++;
	if (q->head == q->size) q->head = 0;
	q->length--;
	return 1;
}

void output(Queue* q) {
	if (!q) return;
	printf("Queue : {");
	for (int i = q->head, j = 0; j < q->length; i++, j++) {
		j != 0 && printf(", ");
		printf("%d", q->data[i % q->size]);
	}
	printf("}\n");
	return;
}

1.3 例程

int main() {
	srand(time(0));
	#define max_op 20
	Queue *q = init(1);
	for (int i = 0; i < max_op; ++i) {
		int val = rand() % 100;
		int op = rand() % 4;
		switch (op) {
			case 0:
			case 1:
			case 2: {
				printf("push %d to the Queue : %s\n", 
				val, push(q, val) ? "Success" : "Fail");	
			} break;
			case 3: {
				printf("pop from the Queue : %s\n",
				pop(q) ? "success": "Fail");
			} break;
		}
		output(q);
	}
	#undef max_op
	clear(q);
	return 0;
}

2 栈

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define COLOR(a, b) "\033[" #b "m" a "\033[0m"
#define GREEN(a) COLOR(a, 32)

2.1 结构定义

(1) 数组, (2)栈顶, (3) 容量, (4)长度

typedef struct Stack {
	int *data;
	int top;
	int size;
} Stack;

2.2 结构操作

初始化/清除

Stack *init(int n) {
	Stack *s = (Stack *)malloc(sizeof(Stack));
	s->size = n;
	s->data = (int *)malloc(s->size * sizeof(Stack));
	s->top = -1;
	return s;
}

void clear(Stack* s) {
	if (!s) return;
	free(s->data);
	free(s);
	return;
}

读出栈顶, 栈空标识

int top(Stack* s) {
	return s->data[s->top];
}

int empty(Stack* s) {
	return s->top == -1;
}

栈空间扩容

使用realloc时预先设置相关类型指针,以免原数据丢失

int expand(Stack* s) {
	int extr_size = s->size;
	int *p;
	while (extr_size) {
		p = (int *)realloc(s->data, sizeof(int) * (s->size + extr_size));
		if (p) break;
		extr_size >> 1;
	}
	if (!extr_size) return 0;
	s->data = p;
	s->size += extr_size;
	return 1;
}

入栈/出栈/显示

int push(Stack* s, int val) {
	if (!s) return 0;
	if (s->top == s->size-1) {
		if (!expand(s)) return 0;
		printf(GREEN("expand success, s->size = % d\n"), s->size);
	}
	s->data[++(s->top)] = val;
	return 1;
}

int pop(Stack *s) {
	if (!s) return 0;
	if (empty(s)) return 0;
	s->top -= 1;
	return 1;
}

void output(Stack* s) {
	if (!s) return;
	printf("Stack : {");
	for (int i = 0; i <= s->top; ++i) {
		i && printf(", ");
		printf("%d", s->data[i]);
	}
	printf("}\n");
	return;
}

2.3 例程

int main() {
	srand(time(0));
	#define max_op 20
	Stack* s = init(1);
	for (int i = 0; i < max_op; ++i) {
		int val = rand() % 100;
		int op = rand() % 4;
		switch (op) {
			case 0:
			case 1:
			case 2: {
				printf("push %d into Stack : %s\n", 
				val, push(s, val) ? "Success" : "Fail");
			} break;
			case 3: {
				printf("pop from Stack : %s\n",
				pop(s) ? "Success" : "Fail");
			} break;
		}
		output(s);
	}
	clear(s);
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值