--栈
-栈的概念
栈:一种特殊的线性表,只允许在栈顶进行插入和删除元素操作,即“头删头插”,栈的这种特性使它在处理递归性质的问题和算法中非常有用
-栈的特点
1.后进先出:栈的基本操作确保了最后被添加的元素总是被第一个删除
2.单端操作:所有的添加和移除操作仅在栈的同一端进行,这一端被称为栈顶,另一端被称为栈底
栈操作图示:
-链式栈
链式栈概念
链式栈:插入操作和删除操作均在链表头部进行,链表尾部就是栈底,栈顶指针就是链表的头指针
本质:栈顶指针+链表
-链式栈示例代码
main.c
#include "stack.h"
void menu();
int main(){
int select;
stack_t* stack = NULL;
do{
menu();
printf("请选择:");
scanf("%d",&select);
switch(select){
case 1:
if(stack==NULL){
stack_init(&stack);
}
pop(stack);
break;
case 2:
if(stack==NULL){
stack_init(&stack);
}
push(stack);
break;
case 3:
stack_is_empty(stack);
break;
case 4:
display_stack_top(stack);
break;
case 5:
clear_stack(&stack);
exit(EXIT_FAILURE);
break;
}
}while(1);
return 0;
}
void menu(){
printf("---------stack---------\n");
printf("1.出栈 pop\n");
printf("2.入栈 push\n");
printf("3.判断栈是否为空\n");
printf("4.查看栈顶元素\n");
printf("5.退出\n");
printf("---------END-----------\n");
}
stack.c
#include "stack.h"
void stack_init(stack_t** stack){
stack_t* p_stack=(stack_t*)malloc(sizeof(stack_t));
if(p_stack==NULL){
printf("malloc failure.\n");
return;
}
p_stack->size=0;
linkedlist_init(&(p_stack->head));
*stack=p_stack;
}
void push(stack_t* stack){
datatype_t* stu=(datatype_t*)malloc(sizeof(datatype_t));
if(stu==NULL){
printf("malloc failure:%s\n",strerror(errno));
printf("入栈失败\n");
return;
}
memset(stu,0,sizeof(datatype_t));
while(getchar()!='\n');
printf("请输入姓名:");
fgets(stu->name,sizeof(stu->name)-1,stdin);
stu->name[strlen(stu->name)-1]='\0';
printf("请输入id:");
fgets(stu->id,sizeof(stu->id)-1,stdin);
stu->id[strlen(stu->id)-1]='\0';
bool res=linkedlist_insert_head(stack->head,stu);
if(res){
stack->size++;
printf("入栈成功\n");
}else{
printf("入栈失败\n");
}
}
void stack_is_empty(stack_t* stack){
if(stack==NULL || stack->size==0){
printf("栈为空\n");
}else{
printf("栈不为空\n");
}
}
void pop(stack_t* stack){
datatype_t* res=linkedlist_remove_head(stack->head);
if(res==NULL){
printf("没有数据!\n");
return;
}
printf("姓名:%s,学号:%s\n",res->name,res->id);
free(res);
res=NULL;
stack->size--;
}
void clear_stack(stack_t** stack){
linkedlist_clean(&((*stack)->head));
free(*stack);
*stack=NULL;
}
void display_stack_top(stack_t* stack){
datatype_t* res=linkedlist_get_headdata(stack->head);
if(res==NULL){
printf("栈为空\n");
return;
}
printf("stack top:\n");
printf("姓名:%s,学号:%s\n",res->name,res->id);
}
stack.h
#ifndef __HEAD_STACK_H__
#define __HEAD_STACK_H__
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <stdbool.h>
#include <errno.h>
#include "linkedlist.h"
typedef struct{
node_t* head;
int size;
}stack_t;
extern void stack_init(stack_t** stack);
extern void push(stack_t*);
extern void display_stack_top(stack_t*);
extern void stack_is_empty(stack_t*);
extern void pop(stack_t*);
extern void clear_stack(stack_t**);
#endif
linkedlist.c
#include "linkedlist.h"
void linkedlist_init(node_t** p_head){
node_t* p_node = (node_t*)malloc(sizeof(node_t));
if(p_node==NULL){
printf("malloc failure:%s\n",strerror(errno));
return;
}
memset(p_node,0,sizeof(node_t));
p_node->next = *p_head;
*p_head = p_node;
}
// 添加的方法
bool linkedlist_insert_head(node_t* p_head,datatype_t* val){
//将data添加到链表的头部
// 1、封装成节点
node_t* p_node = (node_t*)malloc(sizeof(node_t));
if(p_node==NULL){
printf("malloc failure:%s\n",strerror(errno));
return false;
}
memset(p_node,0,sizeof(node_t));
p_node->data = val;
p_node->next = NULL;
// 2、改变指针的指向
p_node->next = p_head->next;
p_head->next = p_node;
return true;
}
// 打印链表中所有的结点数据
void linkedlist_display(node_t* head){
node_t* cur = head->next;
if(cur==NULL){
printf("栈为空\n");
return;
}
printf("[name:%s,id:%s]-->",cur->data->name,cur->data->id);
}
bool linkedlist_is_empty(node_t* head){
return head==NULL || (head->next==NULL?true:false);
}
// 删除节点根据值
datatype_t* linkedlist_remove_head(node_t* head){
if(linkedlist_is_empty(head)){
return NULL;
}else{
node_t* delnode = head->next;
datatype_t* data=delnode->data;
head->next = head->next->next;
free(delnode);
delnode=NULL;
return data;
}
}
void linkedlist_clean(node_t** head){
if(*head == NULL){
return;
}
node_t* pre = *head;
while(pre->next!=NULL){
node_t* delnode = pre->next;
pre->next = pre->next->next;
free(delnode);
delnode=NULL;
}
free(*head);
*head= NULL;
}
datatype_t* linkedlist_get_headdata(node_t* head){
if(linkedlist_is_empty(head)){
return NULL;
}else{
return head->next->data;
}
}
linkedlist.h
#ifndef __HEAD_LINKED_LIST_H__
#define __HEAD_LINKED_LIST_H__
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <stdbool.h>
#include <errno.h>
typedef struct{
char id[128];
char name[128];
}datatype_t;
// 定义结构体类型
typedef struct Node{
// 数据域
datatype_t* data;
// 指针域
struct Node* next;
}node_t;
extern bool linkedlist_insert_head(node_t* p_head,datatype_t* val);
extern void linkedlist_display(node_t* head);
extern void linkedlist_init(node_t** p_head);
extern bool linkedlist_is_empty(node_t* head);
extern datatype_t* linkedlist_remove_head(node_t* head);
extern void linkedlist_clean(node_t** head);
extern datatype_t* linkedlist_get_headdata(node_t*);
#endif