7-1 可以合并的堆栈!

在这里插入图片描述

分析:

一﹑题目大意:
在这里插入图片描述
二﹑方法选择
此次为大作业,我用了单向链表,我同学用了双向链表(双向链表我不是很清楚思路,因为是同学写的,仅供参考,谢谢!)

单向链表:
优势:
代码行数较数组而言短一点。
缺点:
占内存较大。

#include <stdio.h>
#include <stdlib.h>
struct Node{
    int Data;
    struct Node* Next;
};
struct Node*  S[300000];
struct Node* Create()
{
	struct Node*L;
	L=(struct Node*)malloc(sizeof(struct Node));
	L->Next=NULL;
	return L;
}
void Push(struct Node*L,int item)
{
	struct Node*P;
	P=(struct Node*)malloc(sizeof(struct Node));
	P->Data=item;
	P->Next=L->Next;
	L->Next=P;
}
int Pop(struct Node*L)
{
	int item;
	item=L->Next->Data;
	L->Next=L->Next->Next;
	return item;
}
int main ()
{
	int T,i,n,q,j,s,v,t,op,k;
	struct Node* p;
	S[0]=NULL;
	scanf("%d",&T);
	for(i=0;i<T;i++){
		scanf("%d%d",&n,&q);
		for(j=1;j<=n;j++){
			S[j]=Create();
		}
		for(k=0;k<q;k++){
			scanf("%d",&op);
			if(op==1){
				scanf("%d%d",&s,&v);
				Push(S[s],v);
			}
			else if(op==2){
				scanf("%d",&s);
				if(S[s]->Next==NULL) printf("EMPTY\n");
				else printf("%d\n",Pop(S[s]));
			}
			else if(op==3){
				scanf("%d%d",&s,&t);
				p=S[t];
				while(p->Next!=NULL) p=p->Next;
				p->Next=S[s]->Next;    
				S[s]->Next=S[t]->Next;
				S[t]->Next=NULL; 
			}
		}
		for(j=1;j<=n;j++){   /*这一步不能省略,否侧测试点3和4会超内存,因为每次多余的链表会造成空间浪费而使内存不够*/
			free(S[j]);      
		}
	}
	return 0;
}

在这里插入图片描述

双向链表:
优势:
1.时间更省一点。
2.占内存少一点。
缺点:
代码行数多一点

# include <stdio.h>
# include <stdlib.h>
struct shuzu {
	struct shuzu *shang;
	struct shuzu *next;
	int data;
	int top;
}*head3[300000],*tail3[300000];  /*定义n(1≤n≤300000)个堆栈时必须全局定义,局部定义时数组下标最多好像是100001,所以定义在主函数里边会段错误或者超内存*/
void cao1(struct shuzu *s,int v,struct shuzu *tail);
void cao2(struct shuzu *s,struct shuzu *tail);
void cao3(struct shuzu *s,struct shuzu *t,struct shuzu *tail1,struct shuzu *tail2);
void shanchu(struct shuzu *head,struct shuzu *tail);
int main (){
	int i,j,m,n,a,b,c,d,k;
	scanf("%d",&n);
	for(k=1;k<=300000;k++){
	head3[k]=(struct shuzu *)malloc(sizeof(struct shuzu));
	tail3[k]=(struct shuzu *)malloc(sizeof(struct shuzu));
	head3[k]->next=tail3[k];
	head3[k]->top=-1;
	tail3[k]->shang=head3[k];
	tail3[k]->next=NULL;
	head3[k]->shang=NULL;
	}
	for(i=1;i<=n;i++){
	scanf("%d %d",&d,&m);
	for(j=1;j<=m;j++){
		scanf("%d",&a);
		if(a==1){
			scanf("%d %d",&b,&c);
			cao1(head3[b],c,tail3[b]);
			}
		if(a==2){
			scanf("%d",&b);
			cao2(head3[b],tail3[b]);
			}
		if(a==3){
			scanf("%d %d",&b,&c);
			if(head3[c]->top!=-1)cao3(head3[b],head3[c],tail3[b],tail3[c]);
			}
		}
		for(k=1;k<=d;k++)
		shanchu(head3[k],tail3[k]);
	}
	return 0;
}
void cao1(struct shuzu *s,int v,struct shuzu *tail)
{
	struct shuzu *p,*q;
	p=(struct shuzu *)malloc(sizeof(struct shuzu));
	p->data=v;
	p->shang=tail->shang;
	q=tail->shang;
	q->next=p;
	p->next=tail;
	tail->shang=p;
	tail->next=NULL;
	s->top=s->top+1;
}
void cao2(struct shuzu *s,struct shuzu *tail)
{
	struct shuzu *p,*q;
	if(s->top==-1)
	printf("EMPTY\n");
	else{
		q=tail->shang;
		tail->shang=q->shang;
		(q->shang)->next=tail;
		tail->next=NULL;
		printf("%d\n",q->data);
		free(q);
		s->top=s->top-1;
	}
}
void cao3(struct shuzu *s,struct shuzu *t,struct shuzu *tail1,struct shuzu *tail2){
	tail1->shang->next=t->next;
    t->next->shang=tail1->shang;
    tail2->shang->next=tail1;
    tail1->shang=tail2->shang;
    s->top=s->top+t->top+1;
    t->next=tail2;
    tail2->shang=t;
    t->top=-1;
}
void shanchu(struct shuzu *head,struct shuzu *tail)
{
    struct shuzu *p,*q;
    while(head->top!=-1){
    q=tail->shang;
    tail->shang=q->shang;
    (q->shang)->next=tail;
    tail->next=NULL;
    free(q);
    head->top=head->top-1;
 }
}

在这里插入图片描述

总结:
1.从结果上看双向链表时间和空间相对更省一点。
2.个人更喜欢单向链表,因为是自己写的,而且短一点(嘻嘻!)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值