学习感悟:
1、学习的持之以恒说着简单,实则很难,就像笔者最近感冒大部分时间被浪费,好不容易建立习惯也全然忘记,实在是三天打鱼两天晒网。
2、学习应该及时复习,温故而知新,在回顾的过程中还会发现之前的错误。
3、刚开始的时候不要太追求精益求精,就算是依托答辩你只要做出来了,也是胜利,笔者现在就是这个状态,有点草草了事之嫌。
4、坚持下去就是成功。
5. 直面自己的不足和缺点,勇于改正,接纳自己好的或者坏的方面,我们要做的事是直面问题并解决问题而不是逃避问题。
6..对于指针的认识还是云里雾里,特别是数据结构的结构体也是不太明白。
内容:
1.栈的顺序存储实现
2.栈的链式存储实现(没有写,以后来补)
3.队列的顺序存储实现
4.队列的链式存储实现 带头结点 不带头结点(有的时候在计算机里面样子无所谓,只要在逻辑上面符合输出要求就行)
#pragma once
#include<stdio.h>
#include<string.h>
#include<stdbool.h>
#include<stdlib.h>
#define Maxsize 10 //定义栈中元素最大个数
//栈的结构体
struct Sq{
int data[Maxsize];//建立一个静态数组
int top;//栈顶指针因为这是一个数组可以直接用下表指示
};
typedef struct Sq SqStack;
//初始化栈
void InitStack(SqStack &S) {//&在c语言不能作为实参 在c语言中这只能通过指针来访问实参地址改变实参数值
S.top = -1;
}
//对栈进行判空
bool StackEmpty(SqStack S){
if (S.top == -1)
return true;
else
return false;
}
//新元素入栈
bool Push(SqStack& S, int x) {
if (S.top == Maxsize - 1)return false;//栈已经满了
S.top = S.top + 1;//先将栈指针向上移动
S.data[S.top] = x;//再将元素插入栈中
return true;//插入成功
}
//出栈操作
bool Pop(SqStack&S, int& x) {
if (S.top == -1)return false;//栈为空
x = S.data[S.top--];//先取数出栈然后栈顶指针-1
return true;
}
//共享栈
typedef struct {
int data[Maxsize];
int top0;
int top1;
}ShStack;
//初始化共享栈
void InitShStack(ShStack &S) {//初始化栈顶指针
S.top0 = 0;//指向低地址的指针
S.top1 = Maxsize - 1;//指向高地址指针
}
//对栈进行判空
bool StackEmpty(ShStack S) {
if (S.top0== 0&&S.top1==Maxsize-1)
return true;
else
return false;
}
//新元素入栈选择要插入的栈e
bool Push(ShStack& S, int x,int e) {
if (S.top0+1 ==S.top1 )return false;//栈已经满了
if (e == 0) {
S.data[S.top0++] = x;
return true;//插入成功
}//选择栈0先将元素插入栈中再将栈指针向上移动
if (e == 1) {
S.data[S.top1--] = x;//选择栈1先将元素插入栈中再将栈指针向下移动
return true;//插入成功
}
}
//链式存储的栈 使用头插法
typedef struct Node {
int data;
struct Node* next;
} Node;
typedef struct Stack {
Node* top; // 栈顶指针
} Stack;
// 初始化栈
void initStack(Stack* s) {
s->top = NULL;
}
// 入栈
void push(Stack* s, int data) {
Node* newNode = (Node*)malloc(sizeof(Node));
newNode->data = data;
newNode->next = s->top;
s->top = newNode;
}
// 出栈
int pop(Stack* s) {
if (s->top == NULL) {
printf("Stack is empty!\n");
return -1; // 或者其他错误值
}
Node* temp = s->top;
int poppedData = temp->data;
s->top = s->top->next;
free(temp);
return poppedData;
}
//方案1队列的顺序实现
typedef struct {//队列的结构体
int data[Maxsize];
int front, rear;//队头指针队尾指针
}SqQueue1;
//初始化队列
void InitQueue1(SqQueue1 Q) {//将队头指针和队尾指针都指向0
Q.front = Q.rear = 0;
}
//队空判断
bool QueueEmpty1(SqQueue1&Q) {
if (Q.front == Q.rear)return true;
else
return false;
}
//队满判断(取余循环%Maxsize)牺牲一个存储单元,保证了插入时不会将元素插入把留于判断的空格
bool QueueFull1(SqQueue1&S) {
/*if (S.front % Maxsize ==( S.rear+1) % Maxsize)return true; 这是不需要的*/
if(S.front==(S.rear+1)) return true;
else
return false;
}
//入队操作 逻辑上处理逻辑化
bool EnQueue1(SqQueue1& Q, int x) {
if (QueueFull1(Q) == true)return false;
Q.data[Q.rear] = x;
Q.rear=(Q.rear+1)%Maxsize;//保证了一种循环取余运算让存储空间在逻辑上成为了循环解构
return true;
}
//出队操作
bool DeQueue1(SqQueue1& S, int& x) {//删除对头元素,并输出该元素
if (QueueEmpty1(S) == true)//对队列进行判空操作
return false;
x = S.data[S.front];
S.front = (S.front + 1) % Maxsize;
return true;
}
//统计队列中有多少元素 数论模运算
int CountQueue1(SqQueue1& S,int&e) {
e = (S.rear + Maxsize - S.front) % Maxsize;
return e;
}
//方案2不浪费任何一个空间的方案 靠size变量区分队满和队空
typedef struct {
int data[Maxsize];
int front, rear;
int size;
}SqQueue2;
//初始化
void InitQueue2(SqQueue2& Q) {//将队头指针和队尾指针都指向0,将队列元素个数初始化为0
Q.front = Q.rear = 0;
Q.size = 0;
}
//队空判断
bool QueueEmpty2(SqQueue2& Q) {
if (Q.front == Q.rear&&Q.size==0)return true;
else
return false;
}
// 队满判断
bool QueueFull2(SqQueue2&Q) {
if (Q.front == Q.rear&&Q.size==Maxsize) return true;
else
return false;
}
//入队操作
bool EnQueue2(SqQueue2& Q, int x) {
if (QueueFull2(Q) == true)return false;
Q.data[Q.rear] = x;
Q.rear = (Q.rear + 1) % Maxsize;//保证了一种循环取余运算让存储空间在逻辑上成为了循环解构
Q.size++;
return true;
}
//出队操作
bool DeQueue(SqQueue2&Q, int& x) {//删除对头元素,并输出该元素
if (QueueEmpty2(Q) == true)//对队列进行判空操作
return false;
x = Q.data[Q.front];
Q.front = (Q.front + 1) % Maxsize;
Q.size--;
return true;
}
//方案3不浪费任何一个空间的方案 靠tag插入时tag=1 删除时tag=0
//只有删除操作才能队空,插入操作才能队满。
typedef struct {
int data[Maxsize];
int rear, front;
int tag;
}SqQueue3;
//队列的链式存储 和单链表区别 因为没有尾指针
typedef struct LinkNode {//链式队列结点
int data;
struct LinkNode* next;
}LinkNode;
typedef struct {//链式队列结构体
LinkNode* front, * rear;//队头指针和队尾指针
}LinkQueue;
//初始化一个队列(带头结点)
void InitQueue1(LinkQueue&Q) {
Q.front = Q.rear = (LinkNode*)(malloc(sizeof(LinkNode)));//初始时front rear 都指向头指针
Q.front->next = NULL;
}
//判断队列是否是空队列
bool IsEmpty(LinkQueue Q) {
if (Q.front == Q.rear)return true;
else return false;
}
//新元素入队(带头结点)
void EnQueue(LinkQueue& Q, int x) {
LinkNode* s = (LinkNode*)(malloc(sizeof(LinkNode)));
s->data = x;
s->next = NULL;
Q.rear->next = s;//新结点插入rear之后
Q.rear = s;//修改表尾指针
}
//出队(带头结点)
bool DeQueue(LinkQueue& Q, int& x) {
if (Q.front == Q.rear)
return false;//队空
LinkNode* p = Q.front->next;//一个指针p队头元素
x = p->data;//获取队头元素
Q.front->next = p->next;//将对头元素删除
if (Q.rear == p)//最后一个结点出队
Q.rear = Q.front;//修改rear指针
free(p);//释放待删除结点空间
return true;
}
//初始化一个队列(不带头结点)
void InitQueue2(LinkQueue& Q) {
Q.front = Q.rear = (LinkNode*)(malloc(sizeof(LinkNode)));//初始时front rear 都指向头指针
Q.front->next = NULL;
}
//新元素入队(不带头结点)
void EnQueue2(LinkQueue&Q,int x) {
LinkNode* s = (LinkNode*)(malloc(sizeof(LinkNode)));
s->data = x;
s->data = NULL;
if (Q.front == NULL) {//空列表中插入第一个元素,另类头结点
Q.front = s;//修改队头队尾指针
Q.rear = s;
}
else {
Q.rear->next = s;//新结点插入rear结点之后
Q.rear = s;//修改rear指针,确定新队尾
}
}
本人文章错误较多,以后回看可能不免发笑,但是贵在真实记录我的学习认识和过程,单纯的摘抄和引用确实错误更少,但是人总是要勇于面对自己的弱点。