February 29, 2018

数据结构(c语言):堆栈和队列

本章介绍c语言实现的堆栈和队列。

特殊的线性表:堆栈和队列

推荐一个数据结构可视化编辑网站 传送门:https://visualgo.net/en
堆栈是只允许在栈顶进行插入删除操作的线性表,队列是只允许在队尾插入、队头删除的线性表。

堆栈的顺式实现:

                  
#include 
#include 
#define Size 10

typedef struct seqstack {
	int * head;//声明了一个名为head的长度不确定的数组,也叫“动态数组”
	int top;//记录栈顶位置
	int size;//记录堆栈分配的存储容量
}seqstack;


seqstack init() {
	seqstack t;
	t.head = (int*)malloc(Size*sizeof(int));
	t.top = 0;
	t.size = Size;
	return t;
}

int push(seqstack *t, int e) {
	if (t->top == t->size) {
		t->head = (int)realloc(t->head, (t->size + 1)*sizeof(int));//改变head指向的内存空间大小
		if (!t->head) {
			printf("存储分配失败");
			return 0;
		}
		t->size++;
	}
	t->head[t->top] = e;
	t->top++;
	return 1;
}

int pop(seqstack *t) {
	if (t->top == 0) {
		printf("堆栈已空");
		return -1;
	}
	t->top--;
	return t->head[t->top];
}

int size(seqstack *t) {
	return t->top;
}

void display(seqstack *t) {
	for (int i = t->top-1; i>=0; i--) {
		printf("%d", t->head[i]);
	}
	printf("\n");
}

int main() {
	seqstack t1 = init();
	for (int i = 1; i <= Size; i++) {
		push(&t1, i);
	}
	printf("原顺序表:\n");
	display(&t1);

	printf("出栈:");
	int e = pop(&t1);
	printf("%d\n", e);
	printf("出栈后:\n");
	display(&t1);

	printf("将元素8入栈:\n");
	push(&t1, 8);
	display(&t1);

	return 0;
}
                  
                

堆栈的链式实现:

                  
#include 
#include 
#define Size 10

typedef struct LinkStack {
	int e;
	struct LinkStack *next;
}LinkStack;


LinkStack * init() {
	LinkStack *p = (LinkStack*)malloc(sizeof(LinkStack));
	p->next = NULL;
	return p;
}

int push(LinkStack *p, int e) {
	LinkStack *m = (LinkStack*)malloc(sizeof(LinkStack));
	m->e = e;
	m->next = p->next;
	p->next = m;
	return 1;
}

int pop(LinkStack *p) {
	LinkStack *m = p->next;
	if (m == NULL) {
		printf("堆栈已空");
		return -1;
	}
	p->next = p->next->next;
	int e = m->e;
	free(m);
	return e;
}

int size(LinkStack *p) {
	LinkStack *m = p;
	int size = 0;
	while (m->next != NULL) {
		m = m->next;
		size++;
	}
	return size;
}

void display(LinkStack *p) {
	LinkStack *m = p;
	while (m->next != NULL) {
		m = m->next;
		printf("%d", m->e);
	}
	printf("\n");
}

int main() {
	LinkStack *p = init();
	for (int i = 1; i <= Size; i++) {
		push(p, i);
	}
	printf("原顺序表:\n");
	display(p);

	printf("出栈:");
	int e = pop(p);
	printf("%d\n", e);
	printf("出栈后:\n");
	display(p);

	printf("将元素8入栈:\n");
	push(p, 8);
	display(p);

	return 0;
}
                  
                

队列的顺式实现:

                  
#include 
#include 
#define Size 10

typedef struct SeqQueue {
	int * head;//声明了一个名为head的长度不确定的数组,也叫“动态数组”
	int rear;//队尾指针
	int front;//队头指针
	int count;//计数器
	int size;//记录堆栈分配的存储容量
}SeqQueue;

SeqQueue init() {
	SeqQueue t;
	t.head = (int*)malloc(Size*sizeof(int));
	t.rear = 0;
	t.front = 0;
	t.count = 0;
	t.size = Size;
	return t;
}

int isEmpty(SeqQueue *t) {
	return t->count == 0 ? 1 : 0;
}

int isFull(SeqQueue *t) {
	return (t->count > 0 && t->rear == t->front) ? 1 : 0;
}

int offer(SeqQueue *t, int e) {
	if(isFull(t) == 1){
		t->head = (int)realloc(t->head, (t->size + 1)*sizeof(int));//改变head指向的内存空间大小
		if (!t->head) {
			printf("存储分配失败");
			return 0;
		}
		t->rear = t->size;
		t->size++;
	}
	t->head[t->rear] = e;
	t->rear = (t->rear + 1) % t->size;
	t->count++;
	return 1;
}

int poll(SeqQueue *t) {
	if (isEmpty(t) == 1) {
		printf("队列已空");
		return -1;
	}
	int e = t->head[t->front];
	t->front = (t->front + 1) % t->size;
	t->count--;
	return e;
}

int size(SeqQueue *t) {
	return t->size;
}

void display(SeqQueue *t) {
	if (isEmpty(t) == 0) {
		int i = t->front;
		int c = 0;
		while (c < t->count) {
			printf("%d", t->head[i]);
			i = (i + 1) % t->size;
			c++;
		}
		printf("\n");
	}
}


int main() {
	SeqQueue t1 = init();
	for (int i = 1; i <= Size; i++) {
		offer(&t1, i);
	}
	printf("原顺序表:\n");
	display(&t1);

	printf("出栈:");
	int e = poll(&t1);
	printf("%d\n", e);
	printf("出栈后:\n");
	display(&t1);

	printf("将元素8入栈:\n");
	offer(&t1, 8);
	display(&t1);

	return 0;
}
                  
                

队列的链式实现:

                  
#include 
#include 
#define Size 10

typedef struct Node {
	int e;
	struct Node *next;
}Node;

typedef struct LinkQueue {
	Node *front;//队头指针
	Node *rear;//队尾指针
}LinkQueue;

LinkQueue * init() {
	LinkQueue *p = (LinkQueue*)malloc(sizeof(LinkQueue));
	p->front = NULL;
	p->rear = NULL;
	return p;
}

int offer(LinkQueue *p, int e) {
	Node *m = (Node*)malloc(sizeof(Node));
	m->e = e;
	m->next = NULL;
	if (p->rear != NULL) {
		p->rear->next = m;
	}
	p->rear = m;
	if (p->front == NULL) {//如果队头为空,需要修改队头
		p->front = m;
	}
	return 1;
}

int poll(LinkQueue *p) {
	if (p->front == NULL) {
		printf("队列已空");
		return -1;
	}
	Node *m = p->front;
	int e = m->e;
	p->front = p->front->next;
	if (p->front == NULL) {//删除最后一个节点后,要置队尾为空
		p->rear = NULL;
	}
	free(m);
	return e;
}

int size(LinkQueue *p) {
	Node *m = p->front;
	int size = 0;
	while (m != NULL) {
		m = m->next;
		size++;
	}
	return size;
}

void display(LinkQueue *p) {
	Node *m = p->front;
	while (m != NULL) {
		printf("%d", m->e);
		m = m->next;
	}
	printf("\n");
}


int main() {
	LinkQueue *p = init();
	for (int i = 1; i <= Size; i++) {
		offer(p, i);
	}
	printf("原顺序表:\n");
	display(p);

	printf("出栈:");
	int e = poll(p);
	printf("%d\n", e);
	printf("出栈后:\n");
	display(p);

	printf("将元素8入栈:\n");
	offer(p, 8);
	display(p);

	return 0;
}