栈
一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操
作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。不含任
何元素的栈称为空栈,栈又称为后进先出的线性表。
分类
由于站结构是一种线性结构,所以它的实现方式也有很多种,最常见的是链表和顺序表实现的栈结构,本篇介绍的是基于带头节点双向单链表栈结构
话不多说,上代码
LinkStack.h
#pragma once
// 基于带头节点双向单链表栈
#include <stdlib.h>
#include <stddef.h>
#include <errno.h>
#define Datatype char
// 与基于顺序表的栈相比,链表栈长度不定,每次建立节点
typedef struct LinkStack {
Datatype data;
struct LinkStack* next;
struct LinkStack* prev;
} LinkStack;
// 栈初始化为空栈
void LinkStackInit(LinkStack* head);
// 栈销毁
void LinkStackDestroy(LinkStack* head);
// 入栈
void LinkStackPush(LinkStack* head, Datatype value);
// 出栈
void LinkStackPop(LinkStack* head);
// 取栈顶元素, 输出型参数value用来接收栈顶的值,函数返回值返回函数是否是执行成功
int LinkStackTop(LinkStack* head, Datatype* value);
LinkStack.c
#include "LinkStack.h"
// 创建节点
LinkStack* Creat(Datatype value) {
LinkStack* node = malloc(sizeof(LinkStack));
node->data = value;
return node;
}
// 销毁节点
void Destroy(LinkStack* node) {
free(node);
}
// 栈初始化为空栈
void LinkStackInit(LinkStack* head) {
// 非法输入
if(head == NULL) {
perror("LinkStackInit");
return;
}
head->next = head;
head->prev = head;
}
// 栈销毁
void LinkStackDestroy(LinkStack* head) {
// 非法输入
if(head == NULL) {
perror("Destroy");
return;
}
// 空栈
if(head->next == NULL) {
return;
}
LinkStack* cur = head->next;
while(head != NULL) {
LinkStack* tmp = cur;
cur = cur->next;
Destroy(tmp);
}
}
// 入栈,尾插
void LinkStackPush(LinkStack* head, Datatype value) {
// 非法输入
if(head == NULL) {
perror("push");
return;
}
// 创建新节点
LinkStack* new_node = Creat(value);
LinkStack* tail = head->prev;
new_node->next = head;
head->prev = new_node;
new_node->prev = tail;
tail->next = new_node;
}
// 出栈,尾删
void LinkStackPop(LinkStack* head) {
// 非法输入
if(head == NULL) {
perror("push");
return;
}
// 空栈
if(head->next == head) {
return;
}
LinkStack* tail_prev = head->prev->prev;
LinkStack* tmp = head->prev;
tail_prev->next = head;
head->prev = tail_prev;
Destroy(tmp);
}
// 取栈顶元素, 输出型参数value用来接收栈顶的值,函数返回值返回函数是否是执行成功
int LinkStackTop(LinkStack* head, Datatype* value) {
// 非法输入
if(head == NULL) {
perror("top");
value = NULL;
return 0;
}
// 空栈
if(head->next == head) {
value = NULL;
return 0;
}
*value = head->prev->data;
return 1;
}
/* *********************************************
* ******************* test ********************
* *********************************************/
#if 1
#include <stdio.h>
#define FUNCTION() printf("\n==================== %s ====================\n", __FUNCTION__);
// 链表打印函数
void print(LinkStack* head, const char* msg) {
printf("%s\n", msg);
// 空链表
if(head->next == NULL) {
printf("空链表\n");
return;
}
printf("%s\n", msg);
// 正序打印
printf("正序:\n");
LinkStack* cur = head->next;
while(cur != head) {
printf("[%c | %p] ", cur->data, cur);
cur = cur->next;
}
// 倒序打印
printf("\n倒序:\n");
cur = head->prev;
while(cur != head) {
printf("[%c | %p] ", cur->data, cur);
cur = cur->prev;
}
printf("\n");
// 打印栈
printf("栈顶\n");
cur = head->prev;
while(cur != head) {
printf("[%c | %p]\n", cur->data, cur);
cur = cur->prev;
}
printf("栈底\n");
}
// 入栈测试
void TestPush() {
FUNCTION();
LinkStack* head = Creat(0);
LinkStackInit(head);
LinkStackPush(head, 'a');
LinkStackPush(head, 'b');
LinkStackPush(head, 'c');
LinkStackPush(head, 'd');
print(head, "入栈四个");
}
// 出栈测试
void TestPop() {
FUNCTION();
LinkStack* head = Creat(0);
LinkStackInit(head);
LinkStackPush(head, 'a');
LinkStackPush(head, 'b');
LinkStackPush(head, 'c');
LinkStackPush(head, 'd');
print(head, "入栈四个");
LinkStackPop(head);
print(head, "出栈一个");
LinkStackPop(head);
print(head, "出栈两个");
LinkStackPop(head);
print(head, "出栈三个");
LinkStackPop(head);
print(head, "出栈四个");
LinkStackPop(head);
print(head, "空栈出栈");
}
// 取栈顶元素测试
void TestTop() {
FUNCTION();
LinkStack* head = Creat(0);
LinkStackInit(head);
LinkStackPush(head, 'a');
LinkStackPush(head, 'b');
LinkStackPush(head, 'c');
LinkStackPush(head, 'd');
print(head, "入栈四个");
Datatype value = 0;
int ret = LinkStackTop(head, &value);
printf("ret is %d, value is %c\n", ret, value);
}
int main() {
TestPush();
TestPop();
TestTop();
}
#endif
本篇包含代码是现在CentOS6.5
如有错误,请斧正