数据结构(C语言版)-2.栈和队列

顺序栈

  • SeqStack.h
cpp 复制代码
#ifndef __SEQSTACK_H__
#define __SEQSTACK_H__
#define MAXSIZE 100
typedef int datatype;
typedef struct 
{
	datatype data[MAXSIZE]; // 栈底下标从0开始,空栈top=-1
	int top;  // 栈顶指针:除空栈外始终指向栈顶元素位置
}SeqStack;

SeqStack* Init_SeqStack();
int Empty_SeqStack(SeqStack* s);
void Push_SeqStack(SeqStack* s, datatype x);
void Pop_SeqStack(SeqStack*, datatype* x);
void Top_SeqStack(SeqStack* s, datatype *x);
#endif // !__SEQSTACK_H__
  • SeqStack.c
cpp 复制代码
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include"SeqStack.h"
SeqStack* Init_SeqStack()
{
	SeqStack* seq = (SeqStack*)malloc(sizeof(SeqStack));
	seq->top = -1;
	return seq;
}
int Empty_SeqStack(SeqStack* s)
{
	return s->top == -1 ? 1 : 0;
}
void Push_SeqStack(SeqStack* s, datatype x)
{
	// 入栈是栈顶指针先++
	if (s->top == MAXSIZE - 1)
	{
		printf("Stack is Full\n");
	}
	else 
	{
		s->top++;
		s->data[s->top] = x;
	}
}
void Pop_SeqStack(SeqStack* s, datatype* x)
{
	if (Empty_SeqStack(s))
	{
		printf("Stack is empty!\n");
	}
	else 
	{
		*x = s->data[s->top];
		s->top--;
	}
}
void Top_SeqStack(SeqStack* s, datatype* x)
{
	if (Empty_SeqStack(s))
	{
		printf("Stack is empty!\n");
	}
	else
	{
		*x = s->data[s->top];
	}
}

回文序列

  • 注意应该是先将\0压栈,放在栈底
c 复制代码
int is_palindrome(char str[])
{
	SeqStack* seq = Init_SeqStack();
	Push_SeqStack(seq, '\0'); // 将/0放在最后加入
	char* p = str;
	while (*p != '\0')
	{
		Push_SeqStack(seq,*p);
		p++;
	}
	//Push_SeqStack(seq, *p); // 将/0也加入  应该放在栈底
	char str2[MAXSIZE];
	int i = 0;
	Pop_SeqStack(seq, &str2[i]);
	while (str2[i]!='\0')
	{
		i++;
		Pop_SeqStack(seq, &str2[i]);
	}
	int res = strcmp(str,str2);
	if (res == 0)
	{
		printf("is palindrome\n");
		return 1;
	}
	else
	{
		printf("is Not palindrome\n");
		return 0;
	}
}

多个顺序栈共享一个栈

链栈

  • 注意当在main中的指针没有分配内存,而将这个指针传入一个参数为一级指针中函数时
cpp 复制代码
void Push_LinkedStack(StackNode* s, datatype x)
{
	StackNode* tmp = (StackNode*)malloc(sizeof(StackNode));
	tmp->data = x;
	tmp->next = NULL;

	if (s == NULL)
		s = tmp;
	else 
	{
		tmp->next = *s;
		*s = tmp;
	}
}

//----------------------
StackNode* s = Init_LinkedStack();
Push_LinkedStack(s, 1);

结果如图所示

  • 同理
cpp 复制代码
void Pop_LinkedStack(StackNode*s, datatype* x)
{
	if (Empty_LinkedStack(s))
		printf("\nStack is empty!\n");
	else
	{
		*x = s->data;
		StackNode* tmp = s;
		s = s->next;
		free(tmp);
	}
}

//--------
StackNode* s = Init_LinkedStack();
Pop_LinkedStack(s, &x);
  • LinkedStack.h
cpp 复制代码
#ifndef __LINKEDSTACK_H__
#define __LINKEDSTACK_H__
typedef int datatype;
typedef struct node
{
	datatype data;
	struct node* next;
}StackNode;

StackNode* Init_LinkedStack();
int Empty_LinkedStack(StackNode* s);
void Push_LinkedStack(StackNode** s, datatype x);
void Pop_LinkedStack(StackNode**, datatype* x);
void Top_LinkedStack(StackNode* s, datatype* x);

#endif // !__LINKEDSTACK_H__
  • LinkedStack.c
c 复制代码
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include"LinkedStack.h"
StackNode* Init_LinkedStack()
{
	return NULL;
}
int Empty_LinkedStack(StackNode* s)
{
	return s == NULL ? 1 : 0;
}
void Push_LinkedStack(StackNode** s, datatype x)
{
	StackNode* tmp = (StackNode*)malloc(sizeof(StackNode));
	tmp->data = x;
	tmp->next = NULL;

	if (*s == NULL)
		*s = tmp;
	else 
	{
		tmp->next = *s;
		*s = tmp;
	}
}
void Pop_LinkedStack(StackNode**s, datatype* x)
{
	if (Empty_LinkedStack(*s))
		printf("\nStack is empty!\n");
	else
	{
		*x = (*s)->data;
		StackNode* tmp = (*s);
		(*s) = (*s)->next;
		free(tmp);
		printf("*s=NULL:%d\n",*s==NULL);
	}
}
void Top_LinkedStack(StackNode* s, datatype* x)
{
	if (Empty_LinkedStack(s))
		printf("\nStack is empty!\n");
	else
		*x = s->data;
	
}

汉洛塔问题

懒猫老师:https://www.bilibili.com/video/BV1jJ411a7AS?t=459.9




c 复制代码
void move(char c1, char c2)
{
	printf("%c -> %c\n",c1,c2);
}
void hanoi(int n, char x, char y, char z)
{
	if (n == 1)
		move(x,z);
	else
	{
		hanoi(n-1,x,z,y);
		move(x,z);
		hanoi(n-1,y,x,x);
	}
}
int main()
{
	hanoi(3, 'a', 'b','c');
	return 0;
}

台阶问题


队列

顺序队列

  • SeQuqu.h

    cpp 复制代码
    #ifndef __SEQUEUE_H__
    #define __SEQUEUE_H__
    
    #define  MAXSIZE 1024 
    typedef int datatype;
    
    // 循环队列
    // 队空:rear=front
    // 队满(损失一个元素):(rear+1)%MAXSIZE=front
    // 队列中的元素:(rear-front+MAXSIZE)%MAXSIZE
    typedef struct
    {
    	datatype data[MAXSIZE];  // 数据区:data[0]~data[MAXSIZE-1]
    	int rear, front; // front指向队头元素的前一个位置,rear指向队尾元素
    }SeQueue;
    SeQueue* Init_SeQueue();
    void In_SeQueue(SeQueue* q, datatype x);
    void out_SeQueue(SeQueue* q, datatype* x);
    int Empty_SeQueue(SeQueue* q);
    
    
    #endif // !__SEQUEUE_H__
  • SeQueue.cpp

    cpp 复制代码
    #include<stdlib.h>
    #include<string.h>
    #include"SeQueue.h"
    
    
    SeQueue* Init_SeQueue()
    {
    	SeQueue* p = (SeQueue*)malloc(sizeof(SeQueue));
    	p->rear = p->front = 0;
    	return p;
    }
    int Empty_SeQueue(SeQueue* q)
    {
    	return q->front == q->rear ? 1 : 0;
    }
    void In_SeQueue(SeQueue* q, datatype x)
    {
    	if ((q->rear + 1) % MAXSIZE == q->front) // 此时队列已满
    	{
    		printf("The Queue is full\n");
    		return;
    	}
    	q->rear = (q->rear + 1) % MAXSIZE;
    	q->data[q->rear] = x;
    }
    void out_SeQueue(SeQueue* q, datatype* x)
    {
    	if (Empty_SeQueue(q))
    	{
    		printf("Queue is Empty\n");
    		return;
    	}
    	q->front = (q->front + 1) % MAXSIZE;
    	*x = q->data[q->front];
    }

逆置


链式队列

  • LQueue

    cpp 复制代码
    #ifndef __LQUEUE_H__
    #define __LQUEUE_H__
    typedef int datatype1;
    typedef struct Lnode
    {
    	datatype1 data;
    	struct Lnode* next;
    }QNode;
    typedef struct
    {
    	QNode* front, * rear;
    }LQueue;
    
    LQueue* Init_LQueue();
    void In_LQueue(LQueue* q, datatype1 x);
    void out_LQueue(LQueue* q, datatype1* x);
    int Empty_LQueue(LQueue* q);
    #endif // !__LQUEUE_H__
  • LQueue.cpp

    cpp 复制代码
    #include<stdlib.h>
    #include<stdio.h>
    #include"LQueue.h"
    LQueue* Init_LQueue()
    {
    	LQueue* q = (LQueue*)malloc(sizeof(LQueue));
    	QNode *node = (QNode*)malloc(sizeof(QNode));
    	q->rear = q->front = node;
    	q->front->next = NULL;
    	return q;
    }
    int Empty_LQueue(LQueue* q)
    {
    	return q->front == q->rear ? 1 : 0;
    }
    void In_LQueue(LQueue* q, datatype1 x)
    {
    	QNode* node = (QNode*)malloc(sizeof(QNode));
    	node->data = x;
    	node->next = NULL;
    	q->rear->next = node;
    	q->rear = node;
    }
    void out_LQueue(LQueue* q, datatype1* x)
    {
    	if (Empty_LQueue(q))
    	{
    		printf("Queue is Empty \n");
    		return;
    	}
    	*x = q->front->next->data;
    	QNode* tmp = q->front->next;
    	q->front->next = tmp->next;
    	if (tmp == q->rear)
    		q->rear = q->front;
    	
    	free(tmp);
    	tmp = NULL;
    }

循环链表模拟队列

c 复制代码
// 循环队列模拟队列
void In_Lqueue(CyclLNode** rear, Linkeddatatype x)
{
	CyclLNode* tmp = (CyclLNode*)malloc(sizeof(CyclLNode));
	CyclLNode* h = (*rear)->next; // 保存头结点的地址    这个不要忘记
	tmp->data = x;
	tmp->next = NULL;
	(*rear)->next = tmp;
	*rear = tmp; // 尾指针后移
	(*rear)->next = h;
}
void Out_Lqueue(CyclLNode** rear, Linkeddatatype *x)
{
	if ((*rear)->next == *rear)
		printf("Queue is empty\n");
	else 
	{
		CyclLNode* tmp = (*rear)->next->next; // 指向队头元素
		*x = tmp->data;
		(*rear)->next->next = tmp->next;
		if ((*rear)->next->next == (*rear)->next)
			*rear = (*rear)->next; // 都指向头结点
		free(tmp);
	}
}
相关推荐
TitosZhang6 分钟前
排序算法稳定性判断
数据结构·算法·排序算法
xskukuku9 分钟前
华为技术有限公司 C语言编程规范
c语言·嵌入式
光子物联单片机13 分钟前
C语言基础开发入门系列(八)C语言指针的理解与实战
c语言·开发语言·stm32·单片机·mcu
是苏浙18 分钟前
零基础入门C语言之文件操作
c语言·开发语言
盈电智控20 分钟前
体力劳动反而更难被AI取代?物联网科技如何守护最后的劳动阵地
开发语言·人工智能·python
隔壁阿布都22 分钟前
Spring Boot中的Optional如何使用
开发语言·spring boot·python
小龙报24 分钟前
《C语言疑难点 --- C语内存函数专题》
c语言·开发语言·c++·创业创新·学习方法·业界资讯·visual studio
国服第二切图仔1 小时前
Rust开发实战之简单游戏开发(piston游戏引擎)
开发语言·rust·游戏引擎
ii_best1 小时前
安卓/IOS工具开发基础教程:按键精灵一个简单的文字识别游戏验证
android·开发语言·游戏·ios·编辑器
Shylock_Mister1 小时前
ESP32堆栈空间优化全攻略
c语言·嵌入式硬件·物联网