c语言 栈和队列的实现

前提知识

顺序表

优点:可以随机访问,cpu高速缓存利用率高,不涉及(较少)进行插入和删除操作,应该使用顺序表

一般而言,我们使用顺序表(数组)的形式建立 栈这一数据结构。

 


栈(stack)又名堆栈,它是一种运算受限的线性表。其限制是仅允许在表的一端进行插入和删除运算。这一端被称为栈顶,相对地,把另一端称为栈底。

其特点是先进后出,模仿c++stl的stack和queue,我们用c语言实现这2个数据结构 。

较为常用的,栈只能对栈顶进行操作,而且鉴于加载缓存的因素,我们可以使用动态开辟线性表的方式实现

#pragma once
#define N 100
typedef int DataType;
#include 
#include 

typedef struct Stack//动态栈
{
	DataType* _array;//
	int _top; // 表示有效元素个数 表示栈顶位置
	int _capcity;
}Stack;

//初始化
void StackInit(Stack* ps);

// 入栈
void StackPush(Stack* ps, DataType data);

// 出栈
void StackPop(Stack* ps);

// 获取栈顶元素
DataType StackTop(Stack* ps);

// 有效元素的个数
int StackSize(Stack* ps);

// 检测栈是否为空
int StackEmpty(Stack* ps);




void StackInit(Stack* ps)
{
	assert(ps);

	ps->_array = (DataType*)malloc(sizeof(DataType));
	ps->_top = 0;
	ps->_capcity = 1;
}

void StackDestory(Stack * ps)
{
	assert(ps);
	if (ps->_array)
	{
		free(ps->_array);
		ps->_array= NULL;
		ps->_capcity = ps->_top = 0;
	}
}

void  StackPush(Stack* ps, DataType data)
{
	assert(ps);

	if (!(ps->_top < ps->_capcity))//如果栈顶小于容量为假  则需要扩容
	{
		ps->_array = (DataType*)realloc(ps->_array, sizeof(DataType)*(ps->_capcity * 2));
		//此刻扩容后,有可能返回一个新的地址,需要断言
		assert(ps->_array);
		ps->_capcity *= 2;
	}
	ps->_array[ps->_top++] = data;
}

void StackPop(Stack* ps)
{
	assert(ps->_array);
	if (ps->_top < 0)
	{
		return;
	}
	ps->_top--;
}
DataType StackTop(Stack* ps)
{
	assert(ps->_array);
	assert(ps->_top > 0);

	return ps->_array[ps->_top - 1];

}int StackEmpty(Stack* ps)
{
	assert(ps);
	return ps->_top == 0 ? 0 : 1;
}

int StackSize(Stack* ps)
{
	assert(ps);
	return ps->_top;
}

当然,我们写树和哈希表时,可以使用静态栈



//函数和动态栈是一样的
void StackInit(Stack* s)
{
	assert(s);
	s->_top = 0;
}

// 入栈
void StackPush(Stack* s, DataType data)
{
	assert(s);
	if(MAX_SIZE == s->_top)
	{
		printf("栈已满,放不了!!!\n");
		return;
	}

	s->_array[s->_top++] = data;
}

// 出栈
void StackPop(Stack* s)
{
	if(StackEmpty(s))
		return;

	s->_top--;
}

// 获取栈顶元素
DataType StackTop(Stack* s)
{
	assert(!StackEmpty(s));
	return s->_array[s->_top-1];
}

// 有效元素的个数
int StackSize(Stack* s)
{
	assert(s);
	return s->_top;
}

// 检测栈是否为空
// 空栈---0 
// 非空---1
int StackEmpty(Stack* s)
{
	assert(s); 
	return s->_top == 0?0:1;
}

队列

队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。 

队列则需要使用链表实现


#pragma once
#include 
#include 

#define  NULL 0

extern struct BTNode;
typedef struct BTNode*  QDataType;

typedef struct Node
{
	QDataType _data;
	struct Node* _pNext;
}Node, *PNode;

typedef struct Queue
{
	PNode _pHead;//front
	PNode _pTail;//back
}Queue;

void QueueInit(Queue* q);
void QueuePush(Queue* q, QDataType data);
void QueuePop(Queue* q);
QDataType QueueFront(Queue* q);
QDataType QueueBack(Queue* q);
int QueueSize(Queue* q);
int QueueEmpty(Queue* q);


PNode BuyNode(QDataType data)
{
	PNode pNewNode = (PNode)malloc(sizeof(Node));
	if(NULL == pNewNode)
	{
		assert(0);
		return NULL;
	}

	pNewNode->_data = data;
	pNewNode->_pNext = NULL;

	return pNewNode;
}

void QueueInit(Queue* q)
{
	assert(q);
	q->_pHead = q->_pTail = NULL;
}

void QueuePush(Queue* q, QDataType data)
{
	assert(q);
	if(NULL == q->_pHead)
	{ 
		q->_pHead = q->_pTail = BuyNode(data);
	}
	else
	{
		q->_pTail->_pNext = BuyNode(data);
		q->_pTail = q->_pTail->_pNext;
	}
}

void QueuePop(Queue* q)
{
	PNode pDelNode = q->_pHead;
	if(pDelNode)
	{
		q->_pHead = pDelNode->_pNext;
		free(pDelNode);
	}
}

QDataType QueueFront(Queue* q)
{
	assert(q);
	return q->_pHead->_data;
}

QDataType QueueBack(Queue* q)
{
	assert(q);
	return q->_pTail->_data;
}

int QueueSize(Queue* q)
{
	int count = 0;
	PNode pCur = q->_pHead;
	while(pCur)
	{
		++count;
		pCur = pCur->_pNext;
	}

	return count;
}

int QueueEmpty(Queue* q)
{
	return NULL == q->_pHead;
}

 

你可能感兴趣的:(数据结构)