数据结构习题1

这篇博客讨论了如何在两个无头结点的单链表中,从一个链表删除指定范围的元素并将它们插入到另一个链表的特定位置。作者提供了一个C++实现,包括创建链表、删除和插入操作。代码通过查询函数优化,提高了可读性。运行结果显示,删除和插入操作成功执行,实现了预期的功能。
摘要由CSDN通过智能技术生成

题目

设指针la和lb分别指向两个无头结点单链表中的首结点,试设计从表la中删除自第i个元素起共len个元素,并将它们插入到表lb的第j个元素之后的算法。

根据题目可知我们可以使用查询函数找到第一个删除的地方(保存它的前驱结点以方便将这一段链表在la中删除掉)然后依据len的长度找到最后一个删除的位置,然后按照删除操作的代码正常对其进行删除即可。插入时也可以使用查询函数对要插在第几个之后进行查找,找到插入结点的前一个结点然后将被删除的结点一个个插入到lb表中即可。

我首先以自己的思考写了一个这样的代码:

运行起来是可以使用的,仅供大家参考使用:

#include<iostream>
#include<stdlib.h>
using namespace std;

typedef struct stu
{
	int n;
	struct stu *next;	
}de;
int Len=0;    //判断删除操作是否可以正常运行
de *create1()	//与正常的创建链表内容一样 创建La链表
{
	de *head,*s,*r;
	head=(de *)malloc(sizeof(de));
	cout<<"请输入内容:"<<endl;
	r=head;
	s=(de *)malloc(sizeof(de));
	cin>>s->n;
	Len++;
	while(s->n!=0)
	{
		r->next=s;
		s->next=NULL;
		r=s;
		s=(de *)malloc(sizeof(de));
		cin>>s->n;
		Len++;
	}
	free(s);
	return head;
}

de *create2()	//创建Lb的链表
{
	de *head,*s,*r;
	head=(de *)malloc(sizeof(de));
	cout<<"请输入内容:"<<endl;
	r=head;
	s=(de *)malloc(sizeof(de));
	cin>>s->n;
	while(s->n!=0)
	{
		r->next=s;
		s->next=NULL;
		r=s;
		s=(de *)malloc(sizeof(de));
		cin>>s->n;
	}
	free(s);
	return head;
}

void Delete(de **La,de **Lb,int n,int m,int j)	//**指的是二级指针,为链表的地址,可以直接更改链表的值 
{
	if(Len<n+m)
		cout<<"输入的n和m出现问题!"<<endl;
	else
	{ 
		de *p,*q;	//q为前驱结点,p为当前节点 
		de *h,*r,*s,*b;
		h->next=NULL;
		s=h;
		p=(*La)->next; 
		while(n-1>0)	//找到要删除的第一个元素的结点和它的前驱结点方便后续删除操作 
		{
			q=p;
			p=p->next;
			n--;
		}
		r=p;
		int x=m;	//保存m的值不变化 
		while(m-1>0)
		{
			p=p->next;	//找到要删除的最后一个结点 
			m--;
		}
		q->next=p->next;	//将一段元素从链表La中删除 
		m=x;	 //将保存的m值再次赋给m可以再次循环使用
		b=(*Lb);
		while(j--)
			b=b->next;
		while(m--)		//将删除的链表一个一个的插入Lb链表中 
		{
			s=r->next;
			r->next=b->next;
			b->next=r;
			r=s;
		}
        cout<<"修改后的链表:"<<endl;
	    cout<<"La:"<<endl; 
	    print(La);
	    cout<<"Lb"<<endl;
	    print(Lb);
	}
}

void print(de *h)
{
	de *t;
	t=h->next;
	while(t)
	{
		cout<<t->n<<" ";
		t=t->next;
	}
	cout<<endl;
}

int main()
{
	de *La,*Lb,*Lc;
	int m,n,j;
	La=create1();
	cout<<"La:"<<endl;
	print(La);
	Lb=create2();
	cout<<"Lb:"<<endl;
	print(Lb);
	cout<<"请输入从第几个元素删除->";
	cin>>n;
	cout<<"请输入要删除多少个数据->";
	cin>>m;
	cout<<"请要b链表中呢个位置插入->";
	cin>>j;
	Delete(&La,&Lb,n,m,j);
	return 0;
}

对此代码运行的结构如下图所示:

 

 但在此代码中查询一直是在删除的函数里进行,这个函数的内容有些冗长了,我们可以把查询的函数单独放出来形成一个函数对其进行调用返回最后一个结点的值即可。

更改后的代码如下所示;

#include<iostream>
#include<stdlib.h>
using namespace std;
typedef struct stu
{
	int n;
	int Len; 
	struct stu *next;	
}de;

de *search(de *p1,int i);
void Delete(de **La,de **Lb,int n,int m,int j);
void print(de *phead); 

int Len=0;	//判断删除是否可以正常运行 

de *create1()	//与正常的创建链表内容一样 
{
	de *head,*s,*r;
	head=(de *)malloc(sizeof(de));
	cout<<"请输入内容:"<<endl;
	r=head;
	s=(de *)malloc(sizeof(de));
	cin>>s->n;
	Len++;
	while(s->n!=0)
	{
		r->next=s;
		s->next=NULL;
		r=s;
		s=(de *)malloc(sizeof(de));
		cin>>s->n;
		Len++;
	}
	free(s);
	return head;
}


de *create2()	//与正常的创建链表内容一样 
{
	de *head,*s,*r;
	head=(de *)malloc(sizeof(de));
	cout<<"请输入内容:"<<endl;
	r=head;
	s=(de *)malloc(sizeof(de));
	cin>>s->n;
	while(s->n!=0)
	{
		r->next=s;
		s->next=NULL;
		r=s;
		s=(de *)malloc(sizeof(de));
		cin>>s->n;
	}
	free(s);
	return head;
}
void Delete(de **La,de **Lb,int n,int m,int j)	//**指的是二级指针,为链表的地址,可以直接更改链表的值 
{
	if(Len<n+m)
		cout<<"输入的n和m出现问题!"<<endl;
	else
	{ 
		de *p,*q;	//q为前驱结点,p为当前节点 
		de *h,*r,*s,*b;
		h->next=NULL;
		s=h;
		p=(*La); 
		while(n--)	//找到要删除的第一个元素的结点和它的前驱结点方便后续删除操作 
		{
			q=p;
			p=p->next;
		}
		r=p;	//保存着删除的第一个节点位置,插入时有用 
		int x=m;	//保存m的值不变化 
		p=search(p,m-1);
		q->next=p->next;	//将一段元素从链表La中删除 
		m=x;	 
		b=search((*Lb),j);
		while(m--)		//将删除的链表一个一个的插入Lb链表中 
		{
			s=r->next;
			r->next=b->next;
			b->next=r;
			r=s;
		}
		cout<<"修改后的链表:"<<endl;
		cout<<"La:"<<endl; 
		print((*La));
		cout<<"Lb"<<endl;
		print((*Lb)); 
	}
}

de *search(de *p1,int i)
{
	de *t;
	t=p1;
	while(i--)
	{
		t=t->next;
	}
	return t;
} 

void print(de *h)
{
	de *t;
	t=h->next;
	while(t)
	{
		cout<<t->n<<" ";
		t=t->next;
	}
	cout<<endl;
}

int main()
{
	de *La,*Lb,*Lc;
	int m,n,j;
	La=create1();
	cout<<"La:"<<endl;
	print(La);
	Lb=create2();
	cout<<"Lb:"<<endl;
	print(Lb);
	cout<<"请输入从第几个元素删除->";
	cin>>n;
	cout<<"请输入要删除多少个数据->";
	cin>>m;
	cout<<"请要b链表中呢个位置插入->";
	cin>>j;
	Delete(&La,&Lb,n,m,j);
	return 0;
}

此代码运行的结果也与上面一致,同时我们也可以进行尾插方式插入,该代码中使用的是头插的方式将被删除的数据存入Lb链表之中因为代码在创建链表时使用的是尾插方式,所以这里我选择使用头插方式插入。

综合题及答案,帮助大家更好的复习.25、用一组地址连续的存储单元存放的元素一定构成线性表。( ) A ) 平均情况下,快速排序法最快,堆积排序法最节省空间 若线性表采用顺序存储结构,每个数据元素占用4个存储单元,第12个数据元素的存储地址为144,则第1个数据元素的存储地址是101。Loc(ai)=locl+(i—1)( ) 若长度为n的线性表采用顺序存储结构,删除表的第i个元素之前需要移动表n-i+1个元素。( )【这是插入的,删除的n-i】 确定串T在串S首次出现的位置的操作称为串的模式匹配。( 深度为h的非空二叉树的第i层最多有2i-1 个结点。 散列表的查找效率主要取决于所选择的散列函数与处理冲突的方法。 稀疏矩阵压缩存储后,必会失效掉随机存取功能 若一个有向图的邻接矩阵,对角线以下元素均为0,则该图的拓扑有序序列必定存在。( ) 二叉树可以用0≤度≤2的有序树来表示。 非空双向循环链表由q所指的结点后面插入一个由p指的结点的动作依次为:p->prior=q, p->next=q->next,q->next=p,q->prior->next&larr;p。( ) 删除非空链式存储结构的堆栈(栈顶指针为top)的一个元素的过程是依次执行:p=top,top= p->next,free (p)。( ) 排序是计算机程序的一种重要操作,它的功能是将一个数据元素(或记录)的任意序列,重新排列成一个按关键字有序的序列。( ) 在索引顺序表上实现分块查找,在等概率查找情况下,其平均查找长度不与表的个数有关,而与每一块的元素个数有关 无向图的邻接矩阵是对称的有向图的邻接矩阵是不对称的。( _ D _ C B D D C C A B ( C A B D D C B. C C D 如果某图的邻接矩阵是对角线元素均为零的上三角矩阵,则此图是 D D D C A D A D D B A D A B D B C B ( D A B D C 6___ ( C D D __ C A B D 针q所指 C A A D A D B  D A② D A、 )的有限集合 C _B A  C A  C A D ( D C A D B ( B D ( D _ A A ) ( C A ( B ( B D 只有在初始数据为逆序时,冒泡排序所执行的比较次数最多。(
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小侯不躺平.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值