栈, 队列, 链表

栈实现的是一种LIFO(last-in, first-out)策略。
栈上的INSERT操作称为压入(PUSH), DELETE操作称为弹出(POP)。
如果试图对一个空栈进行弹出操作, 称之为栈下溢(underflow), S.top超过了栈上限n, 称之为栈上溢(overflow)。

数组栈

数组栈ADT

# pragma once
/*数组栈ADT*/
#include <stdbool.h>
#define MAXSIZE 100
typedef struct stack {
	int val[MAXSIZE];
	int top;
}Stack;

// 操作: 压栈
//前提条件: 栈未满, 若满栈, 返回0
// 后置条件: 压栈完成
bool StackPush(int val, Stack* stack);

//操作: 弹栈
//前提条件: 栈非空, 否则返回0
//后置条件: 弹栈完成
bool StackPop(Stack* stack);

//操作: 检查栈是否空
//后置条件: 栈空返回1, 否则返回0
bool StackIsEmpty(Stack* stack);

//操作: 检查栈是否满
//后置条件: 栈满返回1, 否则返回0
bool StackIsFull(Stack* stack);

//操作: 清空栈
//后置条件: 清空栈
void EmptyStack(Stack* stack);

数组栈实现函数

/stack.c — 栈ADT实现函数, 与stack.h联合编译/

#include "stack.h"
bool StackPush(int val, Stack* stack)
{
	if (StackIsFull(stack))
		return false;
	stack->val[stack->top] = val;
	(stack->top)++;
}

bool StackPop(Stack* stack)
{
	if (StackIsEmpty(stack))
		return false;
	(stack->top)--;
}

bool StackIsEmpty(Stack* stack)
{
	if (stack->top == 0)
		return true;
	else
		return false;
}

bool StackIsFull(Stack* stack)
{
	if (stack->top == MAXSIZE)
		return true;
	else
		return false;
}

void InitializeStack(Stack* stack)
{
	stack->top = 0;
}

链表栈

链表栈ADT


typedef struct node {
	int val;
	struct node* next;
}Node;

typedef struct stacklist {
	Node;
	Node* top;
}StackList;

typedef StackList* Slist;
//操作: 压栈
//前提条件: 栈未满
bool StackListPush(int val, Slist* slist);

//操作: 初始化链表栈
void InitializeSList(Slist* list);

//操作: 弹栈
//前提条件: 栈非空
//后置条件: 弹栈
bool StackListPop(Slist* slist);

//操作: 检查栈是否空
bool StackListIsEmpty(Slist* slist);

//操作: 检查栈是否满
bool StackListIsFull(Slist* slist);

//操作: 清空栈
bool EmptyStackList(Slist* slist);

链表栈实现函数

/*stack.c   --- 栈ADT实现函数, 与stack.h联合编译*/
#include <stdlib.h>
#include "stack.h"
bool StackPush(int val, Stack* stack)
{
	stack->val[stack->top] = val;
	(stack->top)++;
	return true;
}

bool StackPop(Stack* stack)
{
	if (StackIsEmpty(stack))
		return false;
	(stack->top)--;
	return true;
}

bool StackIsEmpty(Stack* stack)
{
	if (stack->top == 0)
		return true;
	else
		return false;
}

bool StackIsFull(Stack* stack)
{
	if (stack->top == MAXSIZE)
		return true;
	else
		return false;
}

void InitializeStack(Stack* stack)
{
	stack->top = 0;
}


//链表栈

static void CopyToNode(Node* aim, int val);

bool StackListPush(int val, Slist* slist)
{
	Node* temp;
	if ((temp = (Node*)malloc(sizeof(Node))) == NULL)
		return false;
	Slist psl = *slist;
	CopyToNode(temp, val);
	if (psl->top == NULL)
	{
		psl->top = temp;
		psl->head->next = temp;
	}
	else
	{
		psl->top->next = temp;
		(psl)->top = psl->top->next;
	}
	return true;
}

void InitializeSList(Slist* list)
{
	Node* newnode = (Node*)malloc(sizeof(Node));
	StackList* new = (StackList*)malloc(sizeof(StackList));
	*list = new;
	new->head = newnode;
	(new)->head->val = 0;
	(*list)->head->next = NULL;
	(*list)->top = NULL;
}

bool StackListPop(Slist* slist)
{
	if (StackIsEmpty(slist))
		return false;
	Node *temp = (*slist)->top;
	Node* newTop=(*slist)->head->next;
	if (newTop == temp)
	{
		(*slist)->head->next = NULL;
		(*slist)->top = NULL;
		free(temp);
	}
	while (newTop->next != temp)
		newTop = newTop->next;
	newTop->next = NULL;
	free(temp);
	(*slist)->top = newTop;
	return true;
}

bool StackListIsEmpty(Slist* slist)
{
	if ((*slist)->top == NULL)
		return true;
	else
		return false;
}


bool EmptyStackList(Slist* slist)
{
	Node* newhead = (*slist)->head->next;
	Node* cur;
	while (newhead != NULL)
	{
		cur = newhead;
		newhead = newhead->next;
		free(cur);
	}
	free(*slist);
	return true; 
}


static void CopyToNode(Node* aim, int val)
{
	aim->val = val;
	aim->next = NULL;
}

链表栈测试函数

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "stack.h"
int main(void)
{
	Slist stack;
	InitializeSList(&stack);
    StackListPush(3, &stack);
	printf("%d", stack->top->val);
	printf("%d", ((stack->head)->next)->val);
	StackListPush(5, &stack);
	printf("%d", stack->top->val);
	printf("%d", ((stack->head)->next)->next->val);
	StackListPop(&stack);
	printf("%d", stack->top->val);
	printf("%d", stack->head->next->val);
	EmptyStackList(&stack);
	return 0;
}

队列

队列是具有FIFO的属性的一种数据结构, 都列有队头和队尾, 队列中的元素存放在Q.head, Q.head - 1, Q.head - 2…Q.tail - 1, 位置1紧邻在位置n后面形成一个环绕。

双端队列(deque)

双端队列的插入和删除操作都可以在两端进行。

双端队列ADT

#pragma once
/*depue.h --- 双端队列ADT*/
#define MAXSIZE 16
typedef struct {
	int que[MAXSIZE];
	int front;
	int rear;
}Deque;


//操作: 初始化队列
void InitializeDeque(Deque* deque);


//操作: 入队
//前提条件: 队列未满, direction为0入左队, 否则如右队
//后置条件: 入队
_Bool EnDeque(_Bool direction, int val, Deque *deque);

// 操作: 出队
//前提条件: 队列非空, direction为0出左队, 否则出右队
_Bool DeDeque(_Bool direction, Deque* deque);

双端队列实现

#include "deque.h"

//局部函数定义
static _Bool DequeIsUnuse(Deque* deque);


void InitializeDeque(Deque* deque)
{
	deque->front = 0;
	deque->rear = 1;
}

_Bool EnDeque(_Bool direction, int val, Deque* deque)
{
	if (DequeIsUnuse(deque))
		return 0;
	if (direction == 0)
	{
		deque->que[deque->front--] = val;
		if (deque->front = -1)
			deque->front = MAXSIZE - 1;
	}
	else
	{
		deque->que[deque->rear++] = val;
		if (deque->rear == MAXSIZE)
			deque->front = 0;
	}
	return 1;
}


_Bool DeDeque(_Bool direction, Deque* deque)
{
	if (DequeIsUnuse(deque))
		return 0;
	if (direction == 0)
	{
		if (deque->front == MAXSIZE - 1)
			deque->front = 0;
		else
			deque->front++;
	}
	else
	{
		if (deque->rear == 0)
			deque->rear = MAXSIZE - 1;
		deque->rear--;
	}
}

static _Bool DequeIsUnuse(Deque* deque)
{
	if (deque->front == deque->rear)
		return 1;
	else
		return 0;
}

链表

哨兵(sentinel)

哨兵是一个哑对象, 链表中对NIL的引用都代替成对L.nil的引用, 这使得正常的双向链表转变为有哨兵的双向循环链表(circular, doubly linked list with a sentinal), 属性L.nil.next指向表头, L.nil.prev指向表尾, 一个链表只能有一个哨兵。

用一个指针实现双向链表


typedef struct node{
	int val;
	struct node* np;
}Node;

typedef struct {
	Node* head;
	Node* tail;
}List;

void InsertList(List* list, Node * new)
{
	if (list->head != NULL)
		list->head->np = (Node *)((unsigned)list->head->np ^ (unsigned)new);
	new->np = list->head;
	list->head = new;
	if (list->tail = NULL)
		list->tail = new;

}

void DeleteList(List* list, int val)
{
	Node* cur = list->head;
	Node* pre = NULL;
	Node* fut;
	while (cur->val != val)
	{
		fut = cur;
		cur = (Node*)((unsigned)cur->np ^ (unsigned)pre);
		pre = fut;
	}
	fut = (Node*)((unsigned)cur->np ^ (unsigned)pre);
	pre->np = (Node*)((unsigned)pre->np ^ (unsigned)cur ^ (unsigned)fut);
	fut->np = (Node*)((unsigned)fut->np ^ (unsigned)cur ^ (unsigned)pre);
	free(cur);
}

Node* SearchList(List* list, int val)
{
	Node* cur = list->head;
	Node* pre = NULL;
	Node* temp;
	while (cur->val != val)
	{
		temp = cur;
		cur = (Node*)((unsigned)cur->np ^ (unsigned)pre);
		pre = temp;
	}
	return cur;
}

对象的分配和释放

自由对象可由

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值