数据结构 线性表 习题练习与答案 线性表解决约瑟夫问题

本文介绍了线性表的两种主要存储结构——顺序存储和链式存储,详细阐述了它们的工作原理、优缺点。在顺序存储中,元素通过在内存中的相对位置表示逻辑关系,优点是存储密度大但插入和删除效率低。而在链式存储中,元素通过链接指针表示关系,虽然存储密度小但操作灵活。此外,文章还讨论了Josephus问题的解决方案,通过单链表实现,展示了如何动态地插入和删除节点以解决该问题。
摘要由CSDN通过智能技术生成

作业一

什么是线性表?线性表主要采用哪两种存储结构?它们是如何存储数据元素的?

各有什么优缺点?

答案一

线性表是由n个类型相同的数据元素组成的有限序列,其中,元素类型可以是基本类型或类;

主要采用的有顺序存储结构和链式存储结构

顺序存储结构

是通过数据元素的存储对应一块连续的存储空间,数据元素之间的前驱和后续关系通过数据元素在存储器的相对位置来反映。

链式存储结构

数据元素的存储对应的是不连续的存储空间,每个存储节点对应一个需要存储的元素,,元素之间的逻辑关系通过存储节点之间的链接关系反映出来。

顺序存储的优点和缺点

优点:存储密度大(=1),存储空间利用率高

缺点:插入或删除元素时不方便,内存占用大效率不高

链式存储的优点和缺点

优点:插入或删除元素时很方便,使用灵活。

缺点:存储密度小(<1),存储空间利用率低。

作业二

为什么顺序表的插入和删除操作必须移动元素?平均需要移动多少元素?

答案二

顺序表是连续的,采用的顺序存储结构,那么就意味着在 插入与删除的时候都要将顺序表的顺序进行重新排列

意味的是,在进行插入操作的时候,必须要将插入值之后的所有值的下标进行重新排列,那么就意味这要占用很大的内存空间去做这样的一件事;再删除操作的时候,也必须要将插入值之后的所有值进行重新排列,和插入操作一样,同样是要占用很大的内存空间

如果在每一个位置插入元素的概率相同,那么意味着其要做的操作的时间复杂度为O(n),且平均需要移动的元素为n/2

作业三

采用单链表求解Josephus问题,写出关键使用的程序代码

答案三

问题是这样的,创建一个单链表,里面有n个数据,数据从s开始循环,循环数为d,做出的结构就是每次进行循环都删除一个数据。最后剩下的数据就是逃逸数据

我将其实例化,瓜田里有n个西瓜,将其围成圆形,每次走过d个西瓜,从第s个西瓜开始吃,走过d个西瓜就将其脚下的吃掉。最后剩下的西瓜成为幸存瓜。

设计思路

用一个没有头节点的循环链表处理,先生成一个带有n个节点的单循环链表,然后从s 节点起,从1开始计数,记到d时,将其对应节点从链表中删除,然后被删除节点的下一个节点继续从1开始计数,只到剩下最后一个。

代码部分

首先我们肯定要先创建一个瓜的类,为了便于理解,将其命名成了“瓜”

package Josephus;

public class gua {
	private int guanum;
	private gua next;
	
	public gua(int num) {
		this.guanum = num;
	}
	public int getGuanum() {
		return guanum;
	}
	public void setGuanum() {
		this.guanum = guanum;
	}
	public gua getNext() {
		return next;
	}
	public void setNext(gua next) {
		this.next = next;
	}

}

现在开始编写一下first节点

package Josephus;

public class chigua {
	gua first  = new gua(-1);
}

接下来我们向约瑟夫环里添加数据

public void add(int num) {
		if (num<1) {
			System.out.println("你指定有点毛病,里面没瓜吃个啥");
		}
		//这一步是为了保证输入的数值正确并添加娱乐效果
		gua temp = null;
		for(int i =1;i<=num;i++) {
			gua g = new gua(i);
			if(i==1) {
				first = g;
				first.setNext(first);
				temp = first;
			}else {
				temp.setNext(g);
				g.setNext(first);
				temp = g;
				
			}
		}
	}

好,那么现在让约瑟夫环开始转圈

public void zhuanquan(int start, int length, int guanum) {
				if(start>guanum||start<1||first==null) {
					System.out.println("能不能吃点阳间的瓜");
				}
				gua temp =first;
				while(true) {
					if(temp.getNext()==first) {
						break;
					}
					temp=temp.getNext();
				}
				for(int i=0;i<start-1;i++) {
					first=first.getNext();
					temp=temp.getNext();
				}
				while(true) {
					if(first==temp) {
						break;
					}
					for(int j=0;j<length-1;j++) {
						first=first.getNext();
						temp=temp.getNext();
					}
					System.out.println("西瓜"+first.getGuanum()+"被吃掉了");
					first=first.getNext();
					temp.setNext(first);
				}
				System.out.println("最后留下的西瓜就是西瓜"+first.getGuanum());

		
		
	}

现在就是最简单的main函数的部分了,开始直接实例化并调用了,那么我们开始吃瓜吧

package Josephus;

public class test01 {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		chigua g = new chigua();
		g.add(100);
		g.zhuanquan(1,3,5);
}
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值