数据结构严蔚敏(c语言版)课后算法题答案-线性表

( 1 ) 将两个递增的有序链表合并为一个递增的有序链表。要求结果链表仍使用原来两个
链表的存储空间,不另外占用其它的存储空间。表中不允许有重复的数据。

#include<stdio.h> 
typedef struct Lnode
{
	int data;
	struct Lnode *next;
 } Lnode,*Link;
void createlist(Link &L,int n,int z[]);
void listput(Link &L1,Link &L2,Link &L3);
main()
{   
    Link a1,a2,a3;
    int an=5,bn=6;
    int a[an]={2,4,7,3,9};
	int b[bn]={5,12,13,1,15,2};
	createlist(a1,an,a);
	createlist(a2,bn,b);
	listput(a1,a2,a3);
}
void createlist(Link &L,int n,int z[])
{
	Lnode *p,*r,*L1;
	L=new Lnode; //分配一个Londe类型的动态内存空间,指针变量L指向这个空间地址。
	L->next=NULL;
	L1=L;
	p=new Lnode;
	p->data=z[0];
	p->next=NULL;
	L->next=p;
	for(int i=1;i<n;i++)
	{
	   r=L;
	   p=new Lnode;
	   p->data=z[i];
	   for(int j=0;j<i;j++)
	   {   if(p->data<r->next->data)
	   	    { 
			p->next=r->next;
	   	    r->next=p;
	   	    break;
			   }
	   	else{  r=r->next;
	   		   if(!r->next)
	   		{  r->next=p; p->next=NULL;  }	
		    }}
    }
    printf("序列:");
    while(L1->next){L1=L1->next;printf("%d ",L1->data);} 
	printf("\n");
}
void listput(Link &L1,Link &L2,Link &L3)
{
	Lnode *s1,*s2,*r1,*q; 
	s1=L1->next;
	s2=L2->next;
	L3=L1; 
	r1=L3;
	while(s1&&s2)
	{ if(s1->data<s2->data) {  r1->next=s1; r1=s1; s1=s1->next;  }
	  else if(s1->data>s2->data)
	{   
    	r1->next=s2;
	    r1=s2; 
		s2=s2->next; }
     else 
    {
    	r1->next=s1;
	    r1=s1; 
		s1=s1->next;
		q=s2->next;
		delete s2;
		s2=q;	 }
}
	r1->next=s1?s1:s2;/*?:是一个条件运算符,比如P=A?B:C,它表示---若A为真,则用P=B,若A为假,则用P=C.*/
	delete L2;	
	printf("结果:");
	while(L3->next)
	{ L3=L3->next; printf("%d ",L3->data);}   
}

( 2 ) 将两个非递减的有序链表合并为一个非递增的有序链表。要求结果链表仍用原
两个链表的存储空间, 不另外占用其它的存储空间。表中允许有重复的数据。

int listreverse(Link &L)  //单链表递归倒序输出
{
	 L=L->next;
	 Lnode *r;
	 r=L;
	 if(!L)
       return 0;
     else
       listreverse(L);
     printf("%d ",r->data); 
}

void listreverse(Lnode *L)  //前插法倒序输出 
{
	 Lnode *r,*p,*L1;
	 p=L->next;
	 L1=L;
	 L1->next=NULL; 
	 while(p)  
	 {   
	     r=p->next;
	     p->next=L1->next;
	     L1->next=p;
	     p=r;
	}
	 printf("结果:");  
	 while(L1->next)   
     {  L1=L1->next; printf("%d ",L1->data);  }
}

( 3 ) 巳知两个链表A 和B 分别表示两个集合, 其元素递增排列。请设计算法求出A 与
B 的交集, 并存放于A 链表中。

void listputmix(Link &L1,Link &L2,Link &L3) //两个单链表的交集
{
	Lnode *p1,*p2,*r,*q;
	p1=L1->next;
	p2=L2->next;
	L3=L1;
	r=L3;
    while(p1&&p2)
    {
    	if(p1->data<p2->data)
    	  {  q=p1; p1=p1->next;  delete q;  }
    	else if(p1->data>p2->data)
    	  {  q=p2; p2=p2->next;  delete q; }
    	else if(p1->data==p2->data)
    	   { r->next=p1;
    	     r=p1;
    	     p1=p1->next;
    	     q=p2;
    	     p2=p2->next;  delete q; }
	}
	while(p1) { q=p1; p1=p1->next, delete q;  }
	while(p2) { q=p2; p2=p2->next, delete q;  }
	r->next=NULL;
	delete L2;
	printf("结果:");
	while(L3->next)
	{ L3=L3->next; printf("%d ",L3->data);   }
}

( 4 ) 巳知两个链表A 和B 分别表示两个集合, 其元素递增排列。请设计算法求出两个
集合A 和B 的差集( 即仅由在A 中出现而不在B 中出现的元素所构成的集合), 并以同样的
形式存储, 同时返回该集合的元素个数。

int listputdef(Link &L1,Link &L2,Link &L3) //两个单链表的差集(只出现在A中而不在B中出现)
{
	Lnode *p1,*p2,*r,*q;
	p1=L1->next;
	p2=L2->next;
	L3=L1;
	r=L3;
	int n=0; 
    while(p1&&p2)
    {
    	if(p1->data<p2->data)
    	  {  r->next=p1; 
		     r=p1; 
			 p1=p1->next; n++;}
    	else if(p1->data>p2->data)
    	  {  q=p2; p2=p2->next; delete q;}
    	else if(p1->data==p2->data)
    	   { q=p1;
    	     p1=p1->next;  delete q; 
			 q=p2;
    	     p2=p2->next;  delete q; 
			 }
	}
	while(p1) {  r->next=p1; r=p1; p1=p1->next; }
	while(p2) { q=p2; p2=p2->next, delete q;  }
	r->next=NULL;  //一定要把最后一个结点的next指向为NULL,因为它原本的next指向的结点已经删除 
	delete L2;
	printf("结果:");
	while(L3->next)
	{ L3=L3->next; printf("%d ",L3->data);   }
	return n;
}

( 5 ) 设计算法将一个带头结点的单链表A 分解为两个具有相同结构的链表B 、C , 其中
B 表的结点为A 表中值小于零的结点, 而C 表的结点为A 表中值于零的结点( 链表A 中的
元素为非零整数, 要求B 、C 表利用A 表的结点) 。

#include<stdio.h> //创建结点,作为另一条链表的头节点,前插法输出
typedef struct Lnode
{
	int data;
	struct Lnode *next;
 } Lnode,*Link;
void createlist(Link &L,int n,int z[]);
void DifCompose(Link &L);
main()
{   
    Link a1;
    int an=10;
    int a[an]={-2,5,-6,7,-1,12,-5,8,-9,10};
	createlist(a1,an,a);
	DifCompose(a1);
}
void createlist(Link &L,int n,int z[])
{
	Lnode *p,*r,*L1;
	L=new Lnode;
	L->next=NULL;
	r=L;
	L1=L;
	for(int i=0;i<n;i++)
	{
	   p=new Lnode;
	   p->data=z[i];
	   p->next=NULL;
	   r->next=p;
	   r=p;
    }
    printf("A:");
   while(L1->next) { L1=L1->next;printf("%d ",L1->data);} 
	printf("\n");
}
void DifCompose(Link &L)
{
	Lnode *L1,*L2,*p,*r;
	L2=new Lnode;
	L2->next=NULL;
	p=L->next;
	L1=L;
	L1->next=NULL;
	while(p)
	{  r=p->next;
	if(p->data<0)
	    {
		p->next=L1->next;
		L1->next=p;
	    }
	else{	
		p->next=L2->next;
		L2->next=p;
	    }
	    p=r;
    }
	printf("B:");
	while(L1->next)
	{   L1=L1->next;  printf("%d ",L1->data);  } 
    printf("\n");
    printf("C:");
	while(L2->next)
	{   L2=L2->next;  printf("%d ",L2->data);} 
}

void DifCompose(Link &L) //不创建结点,记录另一条链表的首元节点,后插法输出
{
	Lnode *p,*r1,*r2,*L1,*L2;
	p=L->next;
	r1=L;
	L1=L;
	int n=1;
	while(p)
	{  if(p->data>0)
	    {	
		r1->next=p;
		r1=p;
		p=p->next;
	    }
	else{	
	    if(n>0){ r2=p; L2=p; p=p->next;n=0;}
		else {
		r2->next=p;
		r2=p;
		p=p->next;} 
	    }
	}
	r1->next=NULL;
	r2->next=NULL;
	printf("B:");
	while(L2)
	{     printf("%d ",L2->data);L2=L2->next;} 
	printf("\n");
    printf("C:");
	while(L1->next)
	{   L1=L1->next;  printf("%d ",L1->data);} 
}

( 6 ) 设计一个算法, 通过一趟遍历在单链表中确定值最大的结点。

void listmax(Link &L) //遍历单链表最大值
{
	Lnode *p;
	int max;
	p=L->next;
	max=p->data;
	while(p->next)
	{
		p=p->next;
		if(p->data>max)
		max=p->data;
	}
	printf("最大值:%d",max);
}

( 7 ) 设计一个算法, 通过遍历一趟, 将链表中所有结点的链接方向逆转, 仍利用原表的
存储空间。

void listreverse(Lnode *L)  //单链表所有结点的链接方向"原地"逆置
{
	 Lnode *r,*p,*q;
	 p=L;
	 r=q=NULL;
	 while(p)  //使得原来的每个后一结点指向前一结点,头结点的next指向空
	 {    q=p->next;
	      p->next=r;
	      r=p;
	      p=q;
	}
	 printf("结果:");  
	 while(r->next)   
     {  printf("%d ",r->data); r=r->next; }
}

( 8 ) 设计一个算法, 删除递增有序链表中值大于mink 且小于maxk 的所有元素( mink
和是给定的两个参数, 其值可以和表中的元素相同, 也可以不同)。

void Diflist(Link &L,int mink,int maxk) //无序单链表删除符合条件的元素 
{
	Lnode *p,*r,*L1;
	L1=L;
	p=L->next;
	while(p)
	{
		r=p->next;
		if(p->data>mink&&p->data<maxk)   {
			delete p; 
			L1->next=r;
		}
		else
		{
		L1->next=p;
		L1=p; 
			}	
		p=r;
	}
	while(L->next) { L=L->next;printf("%d ",L->data);} 
}

void Diflist(Link &L,int mink,int maxk) //有序单链表删除符合条件的元素 
{
	Lnode *p,*r,*L1;
	L1=L;
	p=L->next;
	while(p)
	{
		while(p->data>mink&&p->data<maxk)
		{
			r=p->next;
			delete p;
			p=r;
		 } 
		 L1->next=p;
		 L1=p;
		 p=p->next;
	}
	while(L->next) { L=L->next;printf("%d ",L->data);} 
}

( 9 ) 已知指向双向循环链表中的一个结点, 其结点结构为data 、prior 、next 三个域,
写出算法p 所指向的结点和它的前结点的顺序。

#include<stdio.h>  //在双向循环链表中,第n个结点和前驱结点交换位置
typedef struct Lnode
{
	int data;
	struct Lnode *prior;
	struct Lnode *next;
 } Lnode,*Link;
void createlist(Link &L,int n,int z[]);
void change(Link &L,int n); 
main()
{   
    Link a1;
    int n=6;
    int an=10;
    int a[an]={-2,5,-6,7,-1,12,-5,8,-9,10};
	createlist(a1,an,a);
	change(a1,n);
}
void createlist(Link &L,int n,int z[])
{
	Lnode *p,*r,*L1;
	L=new Lnode;
	r=L;
	L1=L;
	for(int i=0;i<n;i++)
	{
	   p=new Lnode;
	   p->data=z[i];
	   r->next=p;
	   p->prior=r;
	   r=p;
    }
    p->next=L;
    L->prior=p;
    printf("双向循环链表:");
    while(L1->next!=L) { L1=L1->next;printf("%d ",L1->data);} 
	printf("\n");
}
void change(Link &L,int n)
{
	Lnode *p,*r,*k1,*k2,*L1;
	p=L; 
	L1=L;
	for(int i=0;i<n;i++) { r=p;p=p->next; }
	k1=r->prior;
	k2=p->next;
	k1->next=p;
	p->next=r;
	r->next=k2;
	k2->prior=r;
	r->prior=p;
	p->prior=k1;
	printf("转变之后链表:");
	while(L1->next!=L) { L1=L1->next;printf("%d ",L1->data);} 
}

第1章 绪论 1.1 数据结构的基本概念和术语 1.1.1 引言 1.1.2 数据结构有关概念及术语 1.1.3 数据结构和抽象数据类型(ADT) 1.2 算法描述与分析 1.2.1 什么是算法 1.2.2 算法描述工具——C语言 1.2.3 算法分析技术初步 习题一 第2章 线性表 2.1 线性表的定义及其运算 2.1.1 线性表的定义 2.1.2 各种运算简介 2.2 线性表的顺序存储结构(向量) 2.2.1 顺序存储结构(向量) 2.2.2 向量中基本运算的实现 2.3 线性表的链表存储结构 2.3.1 单链表与指针 2.3.2 单链表的基本运算 2.4 循环链表和双向链表 2.4.1 循环链表 2.4.2 双向链表 2.4.3 顺序存储结构与链表存储结构的综合分析与比较 2.5 多项式相加问题 2.5.1 多项式相加的链表存储结构 2.5.2 多项式相加的算法实现 2.6 线性表算法实现举例 2.6.1 实现线性表顺序存储结构及运算的C语言源程序 2.6.2 单链表处理的C语言源程序 习题二 第3章 栈和队列 3.1 栈 3.1.1 栈的定义及其运算 3.1.2 栈的顺序存储结构(向量) 3.1.3 栈的链表存储结构 3.1.4 栈的应用 3.2 队列 3.2.1 队列的定义及运算 3.2.2 队列的顺序存储结构(向量) 3.2.3 队列的链表存储结构 3.3 栈和队列的算法实现举例 习题三 第4章 串 4.1 串的基本概念 4.2 串的存储结构 4.2.1 串的顺序存储 4.2.2 串的链表存储 4.2.3 串变量的存储映象 4.3 串的运算 4.3.1 串的运算简介 4.3.2 串的匹配运算 4.4 文本编辑 习题四 第5章 数组和广义表 5.1 数组的基本概念 5.1.1 数组的概念 5.1.2 数组的顺序表示 5.1.3 特殊矩阵的压缩存储 5.2 稀疏矩阵的三元组存储 5.2.1 三元组表 5.2.2 稀疏矩阵的运算 5.3 稀疏矩阵的十字链表存储 5.3.1 十字链表的组成 5.3.2 十字链表的有关算法 5.4 广义表 5.4.1 广义表的概念和特性 5.4.2 广义表的存储结构 5.4.3 求广义表的深度 5.4.4 广义表的输出 5.4.5 建立广义表的存储结构 5.5 迷宫问题 习题五 第6章 树 6.1 树的基本概念和术语 6.1.1 树的定义 6.1.2 树的常用术语 6.1.3 树的表示方法 6.2 二叉树 6.2.1 二叉树的定义 6.2.2 二叉树的重要性质 6.2.3 二叉树的存储结构 6.2.4 二叉树二叉链表的一个生成算法 6.3 遍历二叉树 6.3.1 先根遍历 6.3.2 中根遍历 6.3.3 后根遍历 6.3.4 二叉树遍历算法的应用 6.4 线索二叉树 6.4.1 线索二叉树的基本概念 6.4.2 线索二叉树的逻辑表示图 6.4.3 中根次序线索化算法 6.4.4 在中根线索树上检索某结点的前趋或后继 6.4.5 在中根线索树上遍历二叉树 6.5 二叉树、 树和森林 6.5.1 树的存储结构 6.5.2 树与二叉树之间的转换 6.5.3 森林与二叉树的转换 6.5.4 一般树或森林的遍历 6.6 树的应用 6.6.1 二叉排序树 6.6.2 哈夫曼树及其应用 6.7 二叉树的建立和遍历C语言源程序示例 习题六 第7章 图 7.1 图的基本概念和术语 7.1.1 图的基本概念 7.1.2 路径和回路 7.1.3 连通图 7.1.4 顶点的度 7.2 图的存储结构 7.2.1 邻接矩阵 7.2.2 邻接链表 7.3 图的遍历和求图的连通分量 7.3.1 图的建立 7.3.2 图的遍历 7.3.3 求图的连通分量 7.4 图的生成树 7.4.1 生成树的概念 7.4.2 最小生成树 7.4.3 普里姆(Prim)算法和克鲁斯卡尔(Kruskal)算法 7.5 最短路径 7.5.1 单源顶点最短路径问题求解 7.5.2 求有向网中每对顶点间的路径 7.6 有向无环图及应用 7.6.1 拓扑排序 7.6.2 关键路径 7.7 图的算法C语言程序实现举例 7.7.1 无向图的邻接表的建立和遍历 7.7.2 有向无环图的拓扑排序和求关键路径 习题七 第8章 查找 8.1 基本概念
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

超级码立

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

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

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

打赏作者

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

抵扣说明:

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

余额充值