数据结构与算法学习task03

0.理论部分

用数组实现一个顺序栈。
0.1 栈的定义

插入(入栈)和删除(出栈)操作只能在一端(栈顶)进行的线性表。即先进后出(First In Last Out)的线性表。

例1 :线性表(a0,a1,…,an) 进栈与出栈演示。
在这里插入图片描述
在这里插入图片描述
如上所示,栈有两种实现一种是顺序栈一种是链栈,这两种实现方式有什么区别呢,其实与顺序表和链表是一样的:

顺序栈是静态分配的但是链栈是动态分配的,所以比较起来链栈对于空间的利用率更高。因为顺序栈可能申请了较大的空间但是并没有全部都存储元素。
顺序栈虽然不用存储指针相比较链栈来说较为节省内存空间,但是链栈却可以将零碎的内存空间利用起来。
而且对于存储量未知的情况下,链栈更加适合,因为链栈通常不会出现栈满的情况。
对于顺序表和链表来说,链表对于插入和删除效率更高,顺序表对于查找效率更高。但是对于栈来说只能在栈顶进行操作,所以无法体现链表的效率更高。
0.2 栈的操作

  1. 入栈操作:将数据元素值插入栈顶。
  2. 出栈操作:移除栈顶的数据元素。
  3. 是否为空:判断栈中是否包含数据元素。
  4. 得到栈深:获取栈中实际包含数据元素的个数。
  5. 清空操作:移除栈中的所有数据元素。
  6. 获取栈顶元素。

用链表实现一个链栈。
在这里插入图片描述
在这里插入图片描述
理解递归的原理。
如果一个函数在内部调用自身本身,这个函数就是递归函数。

Sample:斐波那契数列

f(n)=f(n-1)+f(n-2), f(0)=0 f(1)=1

循环:

以下代码为Python版本:

i = 0
j = 1
lst = list([i, j])
for k in range(2, 11):
    k = i + j
    lst.append(k)
    i = j
    j = k
print(lst)  
# [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
递归:

以下代码为Python版本:

def recur_fibo(n):
    if n <= 1:
        return n
    return recur_fibo(n - 1) + recur_fibo(n - 2)


lst = list()
for k in range(11):
    lst.append(recur_fibo(k))
print(lst)  
# [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55]

1.练习部分

  1. 根据要求完成车辆重排的程序代码

假设一列货运列车共有n节车厢,每节车厢将停放在不同的车站。假定n个车站的编号分别为1至n,货运列车按照第n站至第1站的次序经过这些车站。车厢的编号与它们的目的地相同。为了便于从列车上卸掉相应的车厢,必须重新排列车厢,使各车厢从前至后按编号1至n的次序排列。当所有的车厢都按照这种次序排列时,在每个车站只需卸掉最后一节车厢即可。

我们在一个转轨站里完成车厢的重排工作,在转轨站中有一个入轨、一个出轨和k个缓冲铁轨(位于入轨和出轨之间)。图(a)给出一个转轨站,其中有k个(k=3)缓冲铁轨H1,H2 和H3。开始时,n节车厢的货车从入轨处进入转轨站,转轨结束时各车厢从右到左按照编号1至n的次序离开转轨站(通过出轨处)。在图(a)中,n=9,车厢从后至前的初始次序为5,8,1,7,4,2,9,6,3。图(b)给出了按所要求的次序重新排列后的结果。
在这里插入图片描述
编写算法实现火车车厢的重排,模拟具有n节车厢的火车“入轨”和“出轨”过程。

// re-arrangement of train.cpp : 
//


#include "stdafx.h"
#include<iostream>
#include<vector>
#include<stack>
#include<deque>
#include<iterator>
#include<algorithm>
using namespace std;


//辅函数update:更新缓冲铁轨上的min_buf(缓冲铁轨上最小的车厢号)、min_tra(最小的车厢所在的缓冲铁轨编号)
void updata(vector<stack<int>> & tracks_buf, int & min_buf, int & min_tra)
{
	for (int i = 0; i<tracks_buf.size(); i++)
	{
		if (!tracks_buf[i].empty() && min_buf>tracks_buf[i].top())
		{
			min_buf = tracks_buf[i].top();
			min_tra = i;
		}
	}
}
//辅函数trans:将车厢移到缓冲铁轨上
bool trans(int n, int d, vector<stack<int>> & tracks_buf, int & min_buf, int & min_tra)
{
	//先查找最优缓冲铁轨
	int min_gap = n + 1;//d与个缓冲铁轨顶端上大于的车厢与d之间的最小间隔
	int prefer_track = -1;//最优铁轨
	for (int i = 0; i<tracks_buf.size(); i++)
	{
		if (!tracks_buf[i].empty() && tracks_buf[i].top()>d && (tracks_buf[i].top() - d)<min_gap)
		{
			min_gap = tracks_buf[i].top() - d;
			prefer_track = i;
		}
	}
	if (-1 != prefer_track)//找到最优缓冲铁轨
	{
		tracks_buf[prefer_track].push(d);
		updata(tracks_buf, min_buf, min_tra);
		return true;
	}
	else
	{
		//再查找是否存在空铁轨
		for (int i = 0; i<tracks_buf.size(); i++)
		{
			if (tracks_buf[i].empty())
			{
				tracks_buf[i].push(d);
				updata(tracks_buf, min_buf, min_tra);
				return true;
			}
		}
		//否则返回false;
		return false;
	}
}

/*  火车车厢重排问题
*	datas:火车车厢在入轨上时的序列
*   n : 火车车厢的总节数
*	k :缓冲铁轨的条数
*/
//主要函数
bool fun(vector<int> &datas, deque<int> & results, int n, int k)
{
	int min_buf = n + 1;//缓冲铁轨上最小的车厢号
	int min_tra = 0;//最小的车厢所在的缓冲铁轨编号
	vector<stack<int>> tracks_buf(k);//缓冲铁轨数组

	int need = 1;//出轨处需要挂上的车厢号
	while (!datas.empty())
	{
		int d = datas.back();
		datas.pop_back();
		if (d == need)//符合要求直接移到出轨
		{
			results.push_front(need);
			need++;
			//再到缓冲铁轨中查找是否有下一个符合的车厢
			while (min_buf == need)//找到了
			{
				results.push_front(need);
				need++;
				//移除缓冲铁轨
				tracks_buf[min_tra].pop();
				//更新min_buf、min_tra
				min_buf = n + 2;
				min_tra = 0;
				updata(tracks_buf, min_buf, min_tra);
			}
		}
		else//不符合要求移到缓冲铁轨上
		{
			if (!trans(n, d, tracks_buf, min_buf, min_tra))
			{
				return false;
			}
		}
	}
	return true;
}


int main()
{
	int array[] = { 5,8,1,7,4,2,9,6,3 };
	deque<int> results;
	vector<int> vec(array, array + sizeof(array) / sizeof(array[0]));
	int n = vec.size();
	int k = 3;//3条缓冲铁轨

	if (fun(vec, results, n, k))
	{
		cout << k << "条缓冲铁轨可以将按照";
		copy(vec.begin(), vec.end(), ostream_iterator<int>(cout));
		cout << "此序列的" << n << "节车厢重新排好挂到火车头上。" << endl;
		cout << "排好后的序列是:" << endl;
		copy(results.begin(), results.end(), ostream_iterator<int>(cout));
		cout << endl;
	}
	else
	{
		cout << "重排失败!" << endl;
	}
}

参考:https://blog.csdn.net/yyc1023/article/details/38689425

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值