栈
栈是一种 == 后进先出( LIFO)== 的数据结构,它是一种线性的、有序的数据结构。栈的基本操作有两个,即入栈和出栈。入栈指将元素放入栈顶,出栈指将栈顶元素取出。栈的本质是一个容器,它可以存储任何类型的数据,但是栈的大小是固定的,因为它的元素只能在栈顶添加或删除。
栈有许多应用场景,比如我们在浏览网页时,可以使用浏览器的 “返回” 功能,这就是栈的应用之一。当我们浏览网页时,每次点击链接都会将新的页面加入到栈中,而当我们点击 “返回” 按钮时,就会将栈顶的页面弹出,这样就可以回到之前的页面了。另外,栈还可以用于括号匹配、表达式求值等问题的解决。
队列
队列是一种==先进先出( FIFO )==的数据结构,它与栈相似,也是一种线性的、有序的数据结构。队列的基本操作有三个,即入队、出队和查看队首元素。入队指将元素放入队尾,出队指将队首元素取出。队列的本质也是一个容器,它可以存储任何类型的数据,但是队列的大小也是固定的。
队列也有很多应用场景,比如操作系统中的进程调度。操作系统中有很多进程需要运行,操作系统通过队列来管理这些进程。当一个进程需要运行时,就将它加入到队列的队尾,当操作系统分配到一个 CPU 时,就将队首的进程取出来运行,这样就可以保证每个进程都能得到运行的机会。
除了以上应用场景外,栈和队列还有很多其他的应用,比如栈还可以用于实现递归算法,队列用于广度优先搜索(BFS)等。
栈的基本操作
顺序栈
#include <iostream>
using namespace std;
#include <stdlib.h>
#define STACKSIZE 10
#define INCRE 2
struct sqstack
{int *base;int top;int stacksize;
};
//顺序栈的初始化:为顺序栈预分配STACKSIZE个空间
void initStack(sqstack &s)
{s.base = new int[STACKSIZE];if (!s.base){exit(1);}s.top = 0;s.stacksize = STACKSIZE;
}
//判断顺序栈是否为空栈,若是空栈,则返回true,否则返回false
bool stackEmpty(sqstack s)
{return s.top==0;
}
//判断顺序栈是否满,满则返回true,否则返回false
bool stackFull(sqstack s)
{return s.top>=s.stacksize;
}
//将数据元素e压入顺序栈
void push(sqstack &s,int e)
{if (stackFull(s)){int *newBase = new int[s.stacksize + INCRE];if (!newBase){exit(1); }for (int i = 0; i < s.stacksize; i++){newBase[i] = s.base[i];}s.base = newBase;s.stacksize += INCRE;}s.base[s.top++]=e;
}
//出栈,并返回出栈元素
int pop(sqstack &s)
{if (stackEmpty(s)){exit(1);}return s.base[--s.top];
}
//获取并返回栈顶元素
int gettop(sqstack &s)
{if (stackEmpty(s)){exit(1);}return s.base[s.top - 1];
}int main()
{sqstack s;initStack(s);for(int i=1; i<=20; i++){push(s,i);}while(!stackEmpty(s)){cout<<pop(s)<<" ";}return 0;
}
#include <iostream>
using namespace std;
#include <stdlib.h>
#define STACKSIZE 10
#define INCRE 2
struct sqstack
{int *base;int *top;int stacksize;
};
//顺序栈的初始化:为顺序栈预分配STACKSIZE个空间
void initStack(sqstack &s)
{s.base = new int[STACKSIZE];if (!s.base){exit(1); }s.top = s.base;s.stacksize = STACKSIZE;
}
//判断顺序栈是否为空栈,若是空栈,则返回true,否则返回false
bool stackEmpty(sqstack s)
{return s.top==s.base;
}
//判断顺序栈是否满,满则返回true,否则返回false
bool stackFull(sqstack s)
{return s.top-s.base>=s.stacksize;
}
//将数据元素e压入顺序栈
void push(sqstack &s,int e)
{if (stackFull(s)){int *newBase = new int[s.stacksize + INCRE];if (!newBase){exit(1);}for (int *p = s.base; p != s.top; ++p){newBase[p - s.base] = *p;}delete[] s.base;s.base = newBase;s.top = s.base + s.stacksize;s.stacksize += INCRE;}*(s.top++) = e;
}
//出栈,并返回出栈元素
int pop(sqstack &s)
{if (stackEmpty(s)){exit(1);}return *(--s.top);
}
//获取并返回栈顶元素
int gettop(sqstack &s)
{if (stackEmpty(s)){exit(1); }return *(s.top - 1);
}int main()
{sqstack s;initStack(s);for(int i=1; i<=20; i++){push(s,i);}while(!stackEmpty(s)){cout<<pop(s)<<" ";}return 0;
}
链式栈
#include <iostream>
using namespace std;
#include <stdlib.h>
struct SNode{int data;SNode *next;
};
typedef SNode *linkStack;
void initStack(linkStack& s) {s = NULL;
}
bool stackEmpty(linkStack s) {return s == NULL;
}
void push(linkStack& s, int e) {SNode* newNode = new SNode;newNode->data = e;newNode->next = s;s = newNode;
}
int pop(linkStack& s) {if (stackEmpty(s)) {exit(1); }int e = s->data;SNode* temp = s;s = s->next;delete temp; return e;
}
int main(){int m;linkStack s;initStack(s);cin>>m;do {push(s,m%2);m=m/2;} while(m!=0);while(!stackEmpty(s)){cout<<pop(s);}
}
链式栈的设计与实现
#include <iostream>
using namespace std;
#include <stdlib.h>
struct snode{int data;snode *next;
};
typedef snode *linkstack;
void initStack(linkstack &top){top=NULL;
}
void push(linkstack &top,int e){snode* newNode = new snode;newNode->data = e;newNode->next = top;top = newNode;
}
bool stackEmpty(linkstack top){return top==NULL;
}
int pop(linkstack &top){if (stackEmpty(top)) {exit(1); }int e = top->data;snode* temp = top;top = top->next;delete temp;return e;
}
void pop(linkstack &top,int &e){if (stackEmpty(top)) {exit(1);}e = top->data;snode* temp = top;top = top->next;delete temp;
}
int getTop(linkstack top){if (stackEmpty(top)) {exit(1);}return top->data;
}
void converse(int m,linkstack &s){initStack(s);do {push(s, m % 2);m = m / 2;} while (m != 0);
}
int main(){linkstack s;int m;cin>>m;converse(m,s);while(!stackEmpty(s)){cout<<pop(s);}return 0;
}
队列的基本操作
循环队列
#include <iostream>
using namespace std;
#include <stdlib.h>
#define MAX 100
struct circleQueue
{int data[MAX];int front,rear;int count;
};
void initQueue(circleQueue &Q)
{Q.front = Q.rear = 0;Q.count = 0;
}
bool queueEmpty(circleQueue &Q)
{return Q.count == 0;
}
bool queueFull(circleQueue &Q)
{return Q.count == MAX;
}
void enQueue(circleQueue &Q, int value)
{if (queueFull(Q)){exit(1);}Q.data[Q.rear] = value;Q.rear = (Q.rear + 1) % MAX;Q.count++;
}
int deQueue(circleQueue &Q)
{if (queueEmpty(Q)){exit(1);}int frontValue = Q.data[Q.front];Q.front = (Q.front + 1) % MAX;Q.count--;return frontValue;
}
int getFront(circleQueue &Q)
{if (queueEmpty(Q)){cout << "empty!" << endl;exit(1);}return Q.data[Q.front];
}
int main()
{int m;cin>>m;circleQueue Q;initQueue(Q);for(int i=1; i<=m; i++){enQueue(Q,i*2-1);}cout<<getFront(Q)<<endl;while(!queueEmpty(Q)){cout<<deQueue(Q)<<" ";}
}
链式队列
#include <iostream>
using namespace std;
#include <stdlib.h>
struct QNode
{int data;QNode *next;
};
struct LinkQueue
{QNode *front;QNode *rear;
};
void initQueue(LinkQueue &Q)
{Q.front = Q.rear = NULL;
}
bool queueEmpty(LinkQueue &Q)
{return Q.front == NULL;
}
void enQueue(LinkQueue &Q, int value)
{QNode *newnode = new QNode;newnode->data = value;newnode->next = NULL;if (queueEmpty(Q)){Q.front = newnode;Q.rear = newnode;}else{Q.rear->next = newnode;Q.rear = newnode;}
}
int deQueue(LinkQueue &Q)
{if (queueEmpty(Q)){cout << "empty!" << endl;exit(1);}int frontvalue = Q.front->data;QNode *temp = Q.front;Q.front = Q.front->next;delete temp;if (Q.front == NULL){Q.rear = NULL;}return frontvalue;
}
int getFront(LinkQueue &Q)
{if (queueEmpty(Q)){cout << "empty!" << endl;exit(1);}return Q.front->data;
}
int main()
{int m;cin>>m;LinkQueue Q;initQueue(Q);for(int i=1; i<=m; i++){enQueue(Q,i*2-1);}cout<<getFront(Q)<<endl;while(!queueEmpty(Q)){cout<<deQueue(Q)<<" ";}
}