数据结构算法之栈
程序员文章站
2022-05-23 11:21:42
...
1.栈的定义与操作
1.1 定义
- 定义;即插入操作和删除操作都只能在一端实现,且要求Last in First out来实现的线性表;
- 实现:顺序表和单链表
1.2 栈的操作
1.入栈操作:只能将数据元素插入栈顶
2. 出栈操作:移除栈顶的数据元素
3. 获取栈顶元素:获得栈顶的元素
4. 是否为空:
5. 获得栈深:
6. 清空操作:
插曲:递归函数
定义:函数在定义函数内部调用自身,这个函数就是递归函数;
2 练习部分
练习1:进制转换:十进制转换八进制
#include <stdio.h>
#include <stdlib.h>
#include "stack.h" //文件包含栈操作的实现
void main(){
// 输出一个非负十进制整数,输出一个等值的八进制整数
STACK* s;
s = createStack(8); //栈的创建
//输入要转换的数
int N;
printf("请输入一个整数:\n");
scanf("%d",&N);
while(N){
push(N%8, s);
N = N / 8;
}
int e;
while(!isEmpty(s)){
e = topAndTop(s); //出栈并返回栈顶元素
printf("%d",e);
}
printf("\n");
//组合操作实现;
}
练习2:火车车厢排序问题
描述:讲一个无序的火车车厢,进入入轨处,通过缓冲轨,结果在出轨处实现正确的递增顺序;
代码实现:
#include <iostream>
using namespace std;
template<class T>
class My_stack;
template<class T>
class Node //结点类
{
private:
T data;
Node<T> *next;
public:
Node()
{
next=NULL;
}
Node(T d)
{
data=d;
next=NULL;
}
friend My_stack<T>;
};
template<class T>
class My_stack
{
private:
Node<T> *head;
public:
My_stack()
{
head=new Node<T>();
}
bool empty() const
{
return (head->next==0);
}
void push(T d) //入栈
{
Node<T> *p=new Node<T>(d);
p->next=head->next;
head->next=p;
}
T top() //返回栈顶元素
{
if(empty())
{
cout<<"stack is empty."<<endl;
exit(1);
}
Node<T> *p=head->next;
T temp=p->data;
return temp;
}
void pop() //弹出栈顶元素
{
Node<T> *p=head->next;
head->next=p->next;
delete p;
}
};
void OutPut(int& minH,int& minS,My_stack<int> H[],int k,int n);
bool Hold(int c,int& minH,int& minS,My_stack<int> H[],int k,int n);
bool Rail_Road(int p[],int n,int k)
{
//k个缓冲轨,车厢初始排序为p[1...n]
//创建与缓冲轨对应的链栈
My_stack<int> *H;
H=new My_stack<int>[k];
int NowOut=1; //下一次要出轨的车厢
int minH=n+1; //缓冲轨中编号最小的车厢
int minS=k; //编号最小的车厢所在缓冲轨的编号
//车厢重排序
for(int i=0;i<n;i++)
{
if(p[i]==NowOut)
{
cout<<"Move car "<<p[i]<<" from input to output"<<endl;
NowOut++;
//从缓冲轨中输出
while(minH==NowOut)
{
OutPut(minH,minS,H,k,n);
NowOut++;
if(NowOut==n+1) //输出全部车厢后返回,不然会造成内存非法访问
return true;
}
}
else
{
//将p[i]放入某个缓冲轨
if(!Hold(p[i],minH,minS,H,k,n))
return false;
}
}
return true;
}
void OutPut(int& minH,int& minS,My_stack<int> H[],int k,int n)
{
//该函数实现把一节车厢从缓冲轨送至出轨处
//同时修改minH minS的值
int c;
//从栈中pop掉编号最小的车厢minH
c=H[minS].top();
H[minS].pop();
cout<<"Move car "<<c<<" from holding track "<<minS+1<<" to output "<<endl;
//检查所有链栈,搜索新的minH minS
minH=n+1;
for(int i=0;i<k;i++)
if( (!H[i].empty()) && (H[i].top()<minH) )
{
minH=H[i].top();
minS=i;
}
}
bool Hold(int c,int& minH,int& minS,My_stack<int> H[],int k,int n)
{
//该函数是将车厢c放入缓冲轨中
//为车厢c寻找最优缓冲轨
int BestTrack=k;//初始化
int BestTop=n+1; //最优缓冲轨的栈顶车厢编号
int x;
//扫描缓冲轨
for(int i=0;i<k;i++)
{
if(!H[i].empty())
{
x=H[i].top();
if(c<x && x<BestTop)
{
BestTop=x;
BestTrack=i;
}
}
else
{
//H[i]为空时
if(BestTrack==k)
BestTrack=i;
}
}
if(BestTrack==k) //没有可用的缓冲轨
return false;
H[BestTrack].push(c);
cout<<"Move car "<<c<<" from input to holding track "<<BestTrack+1<<endl;
//必要时修改minH和minS
if(c<minH)
{
minH=c;
minS=BestTrack;
}
return true;
}
主函数
#include "mystack.h"
int main()
{
int p[9]={3,6,9,2,4,7,1,8,5};
if(Rail_Road(p,9,3))
cout<<"车厢重排序成功"<<endl;
else
cout<<"车厢重排序失败"<<endl;
return 0;
}
小结:多多做练习,做经典习题题目数,不能只停留在书本上,还要时间在代码上;
上一篇: 使用grappelli为django admin后台添加模板
下一篇: 应该从哪里学php怎么着手