算法(四) 链表、栈与队列

算法(四) 链表、栈与队列

1.链表

题目描述
试图编写一个链表,实现插入后,试着编写一下删除操作。(这种使用数组的方式可能会浪费内存,但是请暂时忽略这点)
作为练习的判断,请输出删除链表内所有元素x后的序列。数组保证删除后仍不为空。
输入
第一行包括一个数字n(n<100000),表示链表内元素的个数。
接下来一行,共n个整数,表示链表内的数据
接下来一个数字x,表示要删除的元素。
输出
一行,表示删除后的序列。
样例输入
8
2 3 4 4 4 5 3 8
4
样例输出
2 3 5 3 8

#include
#include
using namespace std;
struct shuju
{
	int num;
	struct shuju *next;
}shuju;
int main()
{
	int n,i,k;
	struct shuju *p1,*p2,*p3,*p4,*head;
	cin>>n;
	p1=p2=(struct shuju *)malloc(sizeof(struct shuju));
	cin>>p1->num;
	head=p1;
	p2->next=p1;
	p2=p1;
	for(i=1;i<n;i++)
	{

		p1=(struct shuju *)malloc(sizeof(struct shuju));
		cin>>p1->num;
		p2->next=p1;
		p2=p1;
	}
	p1->next=NULL;

	//删除指定数据
	cin>>k;
	p4=head;
	p3=p4->next;
	while(p3!=NULL)
	{
		if(p3->num==k) //若相等,跳过
			p3=p3->next;
		else   //若不等,连接
		{
			p4->next=p3;
			p4=p3;
			p3=p3->next;
		}
	}


	//输出
	p1=head;
	while(p1!=NULL)
	{
		cout<<p1->num<<" ";
		p1=p1->next;
	}
}

2.栈

栈是一种特殊的线性表。其特殊性在于限定插入和删除数据元素的操作只能在线性表的一端进行。结论:后进先出(Last In First Out),简称为LIFO线性表。
在日常生活中,有许多类似栈的例子,如刷洗盘子时,依次把每个洗净的盘子放到洗好的盘子上,相当于进栈;取用盘子时,从一摞盘子上一个接一个地向下拿,相当于出栈。又如向枪支弹夹里装子弹时,子弹被一个接一个地压入,则为进栈;射击时子弹总是从顶部一个接一个地被射出,此为子弹出栈。
栈的STL用法:
头文件: #include//栈
定义方式: stack s;//参数也是数据类型,这是栈的定义方式
常用操作:
s.empty()//如果栈为空返回true,否则返回false
s.size()//返回栈中元素的个数
s.pop()//删除栈顶元素但不返回其值
s.top()//返回栈顶的元素,但不删除该元素
s.push(X)//在栈顶压入新元素 ,参数X为要压入的元素

题2026
题目描述
小A有一些糖块,他的某些糖,如果相邻放置,过一段时间会进行粘合,粘合后会形成一块新的糖,糖因此融化后宽度为1。
他使用一个带底的管子(长度足够长)一样的东西放他的糖块,现在他想知道,他依次放入这些糖之后,管中的糖果会变成什么状态

输入
第一行是两个数字n(n<1000)和m(m<100),表示糖块的种类和糖块粘合的组合数
接下来m行,每行三个数x1,x2和y,表示糖块x1和x2相连会粘合变成y
接下来一行是一个数字k(k<100000),表示依次放入糖果数
接下来一行一共k个数,表示放入的糖果
输出
输出数据包括一行,表示管子中糖果的状态
样例输入
6 3
1 2 3
2 3 1
4 4 1
11
1 3 2 3 3 5 2 4 4 6 5
样例输出
1 1 3 3 5 3 6 5
提示
1(3 2)3 3 5 (2(4 4))6 5

#include
#include
using namespace std;
int jud[1005][1005];
int p[100005];
int main()
{
	int n,m,k,a,b,c;
	stack<int> s;  //定义栈s
	cin>>n>>m;
	for(int i=0;i<m;i++)
	{//利用hash思想 
		cin>>a>>b>>c;
		jud[a][b]=c;
		jud[b][a]=c;
	}
	cin>>k;
	int x;
    for(int i=0;i<k;i++)  //循环向栈内压入元素
	{
		cin>>x;
        if(s.empty())
           s.push(x);  //栈顶压入新元素x
        else
           while(1)
        if(jud[x][s.top()]==0)  //如果加入的与栈顶的元素不会融合
		{//利用hash思想 
			s.push(x);
            break;
        }
        else  //如果会融合
		{
            int y=s.top();  //定义此时栈顶元素为y
            s.pop();        //删除栈顶元素
            x=jud[x][y];    //重新定义x为二者融合后元素
            if(s.empty())
			{
				s.push(x);    //压入融合后的x
                break;
            }
		} 
	}
	int len=s.size();
	for(int i=len-1;i>=0;i--)  //一个一个将栈元素取出给p[i],然后输出p[i]即可
	{
		p[i]=s.top();  //将此时栈顶元素赋给数组P[i]
        s.pop();       //删除栈顶元素,进行下一个
	}
	for(int i=0;i<len;i++)  //输出
		cout<<p[i]<<" ";
	return 0;
}

4. 队列

队列(Queue)也是一种运算受限的线性表,它的运算限制与栈不同,是两头都有限制,插入只能在表的一端进行(只进不出),而删除只能在表的另一端进行(只出不进),允许删除的一端称为队尾(rear),允许插入的一端称为队头 (Front)。
举个例子:超市付账的时候排队,先来的先排在最前面,后来的后排在队伍最后面,付账时排在队伍前面的先付账,排在后面的后付账。
队列的STL用法:
头文件: #include// 队列
定义方式: queue q; //参数是数据类型,这是队列的定义方式
常用操作:
q.empty()// 如果队列为空返回true,否则返回false
q.size() // 返回队列中元素的个数
q.pop() //删除队列首元素但不返回其值
q.front() // 返回队首元素的值,但不删除该元素
q.push(X) //在队尾压入新元素 ,X为要压入的元素
q.back() //返回队列尾元素的值,但不删除该元素

题2027
题目描述
小A喜欢锻炼记忆,他准备了n个书上的内容准备背下来。然而,他的记忆总是有限的,他只能记住m个东西。在记住多余的东西的时候,他会把最先前记忆的东西给忘掉,于是他只能再看看书,重新背下来。
这里我们用不同的数字代表不同的记忆的内容。那么,请计算出,小A重新看书的次数。
输入
第一行是两个数n(n<=10000)和m(m<=100)表示书的内容和他的记忆力
接下来是n个数k1,k2…kn,表示他要依次记忆的东西(ki<=3000)。
输出
一个数,表示他看书的次数
样例输入
9 3
1 3 2 8 1 3 2 1 8
样例输出
8
提示
小A脑中的内容依次是:
1 0 0
1 3 0
1 3 2
3 2 8
2 8 1
8 1 3
1 3 2
1 3 2(仅这一次他没有看书)
3 2 8
太好了,小A看了8次书……
==提示:大脑中若已有该元素则无需翻书,题目要求统计总翻书次数 ==

#include
#include
using namespace std;
int main()
{
	int n,m,i,x,count=0,hash[100055]={0}; //hash数组用来记录大脑中是否已有该元素
	queue<int> q;
	cin>>n>>m;
	for(i=0;i<n;i++)
	{
		cin>>x;
		if(q.size()<m)    //如果比记忆力长度小,不用删除
		{
			if(hash[x])   //先判断大脑中有无
				continue;
			else          //如果没有
			{
				q.push(x);  //放入
				count++;
				hash[x]=1;  //将此元素标记
			}
		}
		else               //如果比记忆力长度大,则需删除与放入
		{
			if(hash[x])
				continue;
			else
			{
				hash[q.front()]=0;  //将删除的队首元素重新标记为0
				q.pop();            //删除队首
				q.push(x);          //队尾压入元素
				count++;
				hash[x]=1;
			}
		}
	}
	cout<<count<<endl;
	return 0;
}

你可能感兴趣的:(算法)