第十七章经典抽象数据类型(一)

本文探讨了栈和队列的基本数据结构实现方法,包括链表和动态数组两种方式,并详细介绍了每种方法的特点及操作函数。针对队列实现中的难点——如何高效利用空间并准确判断队列的状态,提出了两种解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

堆栈,没什么太多要总结的,主要是实现问题,这里自己实现了一下,当然从书本中吸取到的是程序代码效率的提升和assert断言的应用判断。

代码的提升在于top_element的初值是0和1,对于push,pop本来就要改变的函数来说没什么变化,但是对于top这样的函数,只需要返回其顶部数据,但是每一次都要-1的话,就会成为很大的困扰,汇编出来的时候,必然会减去1乘以这个数组的类型大小,这就使得效率降低了。

程序如下所示:

"stack.h"

#ifndef STACK_H
#define STACK_H
/*********************链表实现***************************/
struct Node{
	Node* next;
	int value;
};
void create_stack();
void destory_stack();
void push(int a);
void pop();
bool is_empty();
bool is_full();
int top();
static Node* stack;
/*********************动态数组实现***************************/
//static int top_element = -1;
//static int* stack;
//static int stack_size;
//void create_stack(int size);
//void destory_stack();
//void push(int a);
//void pop();
//bool is_empty();
//bool is_full();
//int top();
#endif
stack.cpp

#include "stack.h"
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
/*********************链表实现***************************/
bool is_empty(){
	return stack == NULL;
}
bool is_full()
{
	return false;
}
void create_stack();
void push(int a){
	assert(!is_full());
	Node* newnode = (Node*)malloc(sizeof(Node));
	assert(newnode!=NULL);
	newnode->next = stack;
	newnode->value = a;
	stack = newnode;
}
void pop(){
	assert(!is_empty());
	Node* first_node = stack;
	stack = stack->next;
	free(first_node);
}
void destory_stack(){
	while(!is_empty())
		pop();
}
int top(){
	assert(!is_empty());
	return stack->value;
}

/*********************动态数组实现***************************/
//void create_stack(int size){
//	assert(stack_size == 0);
//	stack_size = size;
//	stack = (int*)malloc(sizeof(int)*size);
//	assert(stack != NULL);
//}
//
//void destory_stack(){
//	assert(stack_size != 0);
//	stack_size = 0;
//	top_element = -1;
//	free(stack);
//	stack = NULL;//记住清指针
//}
//
//void push(int a){
//	assert(!is_full());
//	stack[++top_element] = a;
//}
//
//void pop(){
//	assert(!is_empty());
//	--top_element;
//}
//
//bool is_empty(){
//	return top_element == -1;
//}
//
//bool is_full(){
//	return top_element == stack_size-1;
//}
//int top(){
//	assert(!is_empty());
//	return stack[top_element];
//}
test.cpp
#include "stack.h"
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
int main(){
	push(3);
	push(4);
	push(6);
	int a = top();
	pop();
	destory_stack();
	return EXIT_SUCCESS;
}
队列实现的困扰在于,如果使用一个数组,我们不想浪费空间的话,之前离开队列空出的位置必须用上,那么怎么获得这个位置就非常重要了,最开始的想法简单来说就是if(rear==size) rear = 0;这样的想法换个方式实现,其实就是%size,所以rear的更新方程就是rear = (rear+1)%size;front也是,但是这个时候判断队列是否为空和满就变得很困难,简单判断2者大小会发现,队列满的时候rear=front,但是队列还有一个元素的时候rear=front,所以根本无法判断。

因此引入了2种方法去判断是否为空为满,

1、定义count表示现在含有元素的多少,非常简单就可以判断,
2、将整个数组空出一个来,不完全填满,这样当(rear+1)%size == front时就是空,(rear+2)%size == front时则满。
Queue.h

#ifndef QUEUE_H
#define QUEUE_H
#include <stdio.h>
/***************************动态数组实现************************************/
//static int* queue;
//static int front = 1;
//static int rear = 0;
//static int queue_size;
//void create_queue(int size);
//void destroy_queue();
//void Delete();
//void Insert(int a);
//bool is_empty();
//bool is_full();
//int queue_front();
//int queue_last();
/***************************链表实现************************************/
struct Node{
	int value;
	Node* next;
};
void create_queue();
void destroy_queue();
void Delete();
void Insert(int a);
bool is_empty();
bool is_full();
Node* queue_front();
Node* queue_last();
static Node* queue;
static Node* last;
#endif
queue.cpp
#include "Queue.h"
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
/***************************动态数组实现************************************/
//void create_queue(int size){
//	assert(queue_size == 0);
//	queue_size = size;
//	queue = (int*)malloc(sizeof(int)*size);
//	assert(queue != NULL);
//}
//
//void destroy_queue(){
//	assert(!is_full());
//	queue_size = 0;
//	free(queue);
//	queue = NULL;
//}
//
//void Delete(){
//	assert(!is_empty());
//	front = (front+1)%queue_size;
//}
//
//void Insert(int a){
//	assert(!is_full());
//	rear = (rear+1)%queue_size;
//	queue[rear] = a;
//}
//
//bool is_empty(){
//	return (rear+1)%queue_size == front;
//}
//
//bool is_full(){
//	return (rear+2)%queue_size == front;
//}
//
//int queue_front(){
//	assert(!is_empty());
//	return queue[front];
//}
//int queue_last(){
//	assert(!is_empty());
//	return queue[rear];
//}
void create_queue();
void destroy_queue(){
	while (!is_empty())
		Delete();
}
void Delete(){
	assert(!is_empty());
	Node* first_node = queue_front();
	//if(queue != last)
	queue = queue->next;
	free(first_node);
}

void Insert(int a){
	assert(!is_full());
	Node* new_node = (Node*)malloc(sizeof(Node));
	assert(new_node!=NULL);
	new_node->value = a;
	new_node->next = NULL;
	if(last == NULL){
		last = new_node;
		queue = new_node;
	}
	else
		last->next = new_node;
	last = new_node;
}

bool is_empty(){
	return queue==NULL;//最开始的时候等于last发现会留下一个值,然后改为NULL,发现queue->next报错,最后在new_node赋初值的时候得以改正,一定要记得!!
}

bool is_full(){
	return false;
}

Node* queue_front(){
	return queue;
}
Node* queue_last(){
	return last;
}
test.cpp
#include "Queue.h"
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

int main(){
	//create_queue(10);
	Insert(3);
	Insert(4);
	Insert(5);
	Insert(6);
	Insert(3);
	Insert(3);
	Insert(3);
	Insert(3);
	//int a = queue_front();
	//int b = queue_last();
	Delete();
	destroy_queue();
	return EXIT_SUCCESS;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值