【算法与数据结构复习】| 链表类

        今天跟着左程云算法课007-012,07和08讲了【时空复杂度】和【算法与数据结构的概念】,简单复习了一下。重点在于009-012课程链表类题目的学习。总结记录一下,以下是单链表结点的通用代码:

	//单链表节点
	public static class ListNode{
		public int val;
		public ListNode nextListNode;
		
		public ListNode(int n) {
			this.val=n;
		}
		public ListNode(int n,ListNode next) {
			this.val=n;
			this.nextListNode=next;
		}
	}

一、单链表和双链表的逆置

(1)单链表逆置

        链表逆置是链表类最基础的算法。head头结点要移动,除了head指向当前结点之外,要另外设置两个变量pre和next分别指向当前结点的前一个结点和后一个结点。

	public static ListNode ListReverse(ListNode head) {
		ListNode pre=null;
		ListNode next=null;
		
		while(head!=null) {
			next=head.nextListNode;
			head.nextListNode=pre;
			pre=head;
			head=next;
		}
		
		return pre;
	}

(2)双链表的逆置

        双链表的逆置和单链表逆置思路一样,只是在当年节点的next变动时要pre和next一起变动,思路和上述的单链表逆置一模一样。

	//双链表节点
	public static class DoubleListNode{
		public int val;
		public DoubleListNode pre;
		public DoubleListNode next;
		
		public DoubleListNode(int n) {
			this.val=n;
		}
		
		public DoubleListNode(int n, DoubleListNode pre, DoubleListNode next) {
			this.val=n;
			this.pre=pre;
			this.next=next;
		}
	}
	
	//逆置双链表
	public static DoubleListNode reverDoubleListNode(DoubleListNode head) {
		DoubleListNode pre=null;
		DoubleListNode next=null;
		while(head!=null) {
			next=head.next;
			head.next=pre;
			head.pre=next;
			pre=head;
			head=next;
		}
		return pre;
	}

二、有序链表的合并

        对于有序链表的合并,进行边缘条件判定之后,比较两个链表头结点大小,然后将返回的head指向小头,这里的head之后不变,用于返回合并链表的头。之后设置一个cur指向合并链表的最后一个结点(也就是说只要有一个结点兜进来,就用cur指向这个结点),分别用cur1和cur2在两个链表上移动。比较cur1和cur2的大小,哪个小哪个链到cur后面,直到其中一个链表走完。走完后接着把没链上的链进来,然后返回最开的head结点。

        代码测试链接:. - 力扣(LeetCode)

	public static ListNode MergeList(ListNode h1,ListNode h2) {
		
		if(h1==null||h2==null) {
			return h1==null?h2:h1;
		}
		ListNode head=h1.val>h2.val?h2:h1;
		ListNode cur=head;
		ListNode cur1=h1.val>h2.val?h1:h1.next;
		ListNode cur2=h1.val>h2.val?h2.next:h2;
		
		while(cur1!=null && cur2!=null) {
			if(cur1.val<cur2.val) {
				cur.next=cur1;
				cur1=cur1.next;
				
			}
			else {
				cur.next=cur2;
				cur2=cur2.next;
			}
			
			cur=cur.next;
		}
		
		if(cur1!=null || cur2!=null) {
			cur.next= cur1==null?cur2:cur1;
		}
		
		return head;
		
	}

三、两个链表相加

        对于两个链表相加,要返回的数据类型也是NodeList,所以要重开一个链表来存储相加结果,用ans返回结果链表头,用cur来指向结果链表尾。写一个循环开始加,循环条件是h1或h2不为空即可。相加得到sum的时候要把h1、h2和carry都考虑上,加出来的结果处理后往结果链表放。代码如下。

        代码测试链接:. - 力扣(LeetCode)

	public static ListNode AddTwoNumbers(ListNode h1,ListNode h2) {
		ListNode ans=null,cur=null;
		int carry=0;
		for(int sum,val;
				h1!=null||h2!=null;
				h1= h1==null?null:h1.next,
				h2= h2==null?null:h2.next) {
			sum=(h1==null?0:h1.val)+(h2==null?0:h2.val)+carry;
			val=sum%10;
			carry=sum/10;
			
			if(ans==null) {
				ans=new ListNode(val);
				cur=ans;
			}
			else {
				cur.next=new ListNode(val);
				cur=cur.next;
			}
			
		}
		
		if(carry==1) {
			cur.next=new ListNode(1);
		}
		return ans;
		
	}

四、链表划分

        这个题目要以x为分界点,分成左右两个区域。那么我们就设置4个变量,分别是smallHead,smallTail,表示小头和小尾。bigHead和bigTail,表示大头和大尾。然后设置一个cur,我们在对于当下节点head的时候,用cur指向head.next,然后后面发货的时候把head.next断开,方便当前head发货完还能接着原来的顺序往后遍历继续走。思路很简单,head拿到一个数,判断然后发货,发往大区或者小区。最后要注意判断一下小区里面是否有元素存在,如果没有直接返回大头,如果有元素的话,把小尾和大头连接起来然后返回小头。代码如下:

        代码测试链接:. - 力扣(LeetCode)

	public static ListNode PartList(ListNode head,int x) {
		
		ListNode smallHead=null,smallTaiListNode=null;
		ListNode bigHead=null,bigTaiListNode=null;
		ListNode cur=null;
		
		if(head==null) {
			return null;
		}
		
		while(head!=null) {
			cur=head.next;
			head.next=null;
			//发货
			if(head.val<x) {
				//发货给小区
				if(smallHead==null) {
					smallHead=head;
				}
				else {
					smallTaiListNode.next=head;
					
				}
				smallTaiListNode=head;
			}
			else {
				//发货给大区
				if(bigHead==null) {
					bigHead=head;
				}
				else{
					bigTaiListNode.next=head;
				}
				
				bigTaiListNode=head;
				
			}
			
			head=cur;
		}
		
		if(smallHead==null) {
			return bigHead;
		}
		else {
			smallTaiListNode.next=bigHead;
			return smallHead;
		}
		
		
	}
好的,针对您的问题,我可以给您一些思路建议: 1. 首先,您需要安装 xlsx file-saver 两个库。您可以使用 npm 进行安装,命令如下: ``` npm install xlsx file-saver --save ``` 2. 接下来,您需要将数据按照相同项进行合并。您可以使用 JavaScript 的 Array.reduce() 方法来实现。例如,假设您的数据如下: ``` const data = [ { name: 'Alice', age: 25, gender: 'female' }, { name: 'Bob', age: 30, gender: 'male' }, { name: 'Alice', age: 35, gender: 'female' }, { name: 'Bob', age: 40, gender: 'male' }, { name: 'Alice', age: 45, gender: 'female' } ]; ``` 您可以使用以下代码将数据按照姓名进行合并: ``` const mergedData = data.reduce((acc, cur) => { const key = cur.name; if (!acc[key]) { acc[key] = { name: key, age: cur.age, gender: cur.gender }; } else { acc[key].age += cur.age; } return acc; }, {}); ``` 最终,您会得到如下的合并后的数据: ``` { "Alice": { "name": "Alice", "age": 105, "gender": "female" }, "Bob": { "name": "Bob", "age": 70, "gender": "male" } } ``` 3. 最后,您可以使用 xlsx file-saver 库将数据导出Excel 文件。具体步骤如下: - 将合并后的数据转换为 Excel 的工作簿对象: ``` const workbook = XLSX.utils.book_new(); const sheet = XLSX.utils.json_to_sheet(Object.values(mergedData)); XLSX.utils.book_append_sheet(workbook, sheet, 'Sheet1'); ``` - 将工作簿对象保存为 Excel 文件: ``` const buffer = XLSX.write(workbook, { bookType: 'xlsx', type: 'array' }); const blob = new Blob([buffer], { type: 'application/octet-stream' }); saveAs(blob, 'data.xlsx'); ``` 其中,saveAs() 方法来自于 file-saver 库,用于将 Blob 对象保存为文件。 希望以上的思路代码可以帮助到您。如果您有任何问题或疑问,请随时向我提出。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值