栈实现的是一种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;
}
对象的分配和释放
自由对象可由
791

被折叠的 条评论
为什么被折叠?



