将链表中的所有元素为奇数的节点移到元素为偶数节点的前面,并保证奇数之间顺序不变,偶数之间顺序不变。

2.将链表中的所有元素为奇数的节点移到元素为偶数节点的前面,并保证奇数之间顺序不变,偶数之间顺序不变。

示例:

交换前链表的顺序             交换后链表的顺序

4→5→3→1→2   ==>  5→3→1→4→2

1 ==> 1                   (链表仅含一个元素)

2→1 ==>1→2

==>         (链表为空)

C/C++:

链表节点定义为:

struct node {

struct node *next;

int value;

};

struct node *swap(struct node *list);

Java:

链表节点定义为:

class Node {

public Node next;

public int value

}

Node swap(Node list)

注意点和要求如下:

1. swap函数要求对节点的指针/引用进行操作(不得创建任何新的链表节点)

2. 不得使用任何库函数/API,如需使用类似功能, 请自行实现

3. 不得将链表转化为其他类型数据结构再进行交换,如数组等

package offer;
/**
 * 树结构
 * @author cxx
 *
 */
public class ListNode {

	int val;
	ListNode next = null;

	ListNode(int val) {
		this.val = val;
	}

	ListNode() {

	}

}

package offer;

/**
 * 将链表中的所有元素为奇数的节点移到元素为偶数节点的前面,并保证奇数之间顺序不变,偶数之间顺序不变。
 * @author cxx
 *
 */
public class Main {

	public static void main(String[] args) {
		ListNode listNde1 = new ListNode(4);
		ListNode listNde2 = new ListNode(5);
		ListNode listNde3 = new ListNode(3);
		ListNode listNde4 = new ListNode(1);
		ListNode listNde5 = new ListNode(2);

		listNde1.next = listNde2;
		listNde2.next = listNde3;
		listNde3.next = listNde4;
		listNde4.next = listNde5;

		Main main = new Main();

		ListNode listNde = main.swap(listNde1);

		// 53142
		while (listNde != null) {

			System.out.println(listNde.val);
			listNde = listNde.next;
		}

	}

	/**
	 * 链表元素的交换方法  奇数的节点移到元素为偶数节点的前面
	 * 1.查找尾元素,确定程序的结束点
	 * 1.找到第一个奇数元素,并将该元素之前的偶数放到尾部
	 *
	 *
	 *
	 * @param listNode
	 * @return
	 */
	public ListNode swap(ListNode listNode) {
		if(listNode == null){
			return null;
		}
		if(listNode.next == null){
			return listNode;
		}

		ListNode end = listNode;//尾元素
		ListNode prev = null;//指针移动的前一个节点
		ListNode curr = listNode;//指针移动的当前节点

		/**
		 * 循环,查找尾节点
		 */
		while (end.next != null) {
			end = end.next;
		}
		ListNode newEnd = end;// 新的尾节点,不断的存放接收的偶数元素。

		// 将第一个奇数前的偶数放到链尾
		while (curr.val % 2 == 0 && curr != end) {
			newEnd.next = curr;
			curr = curr.next;
			newEnd.next.next = null;
			newEnd = newEnd.next;
		}

		// 元素是奇数
		if (curr.val % 2 != 0) {
			/* 头结点为第一个奇数 */
			listNode = curr;

			while (curr != end) {
				if ((curr.val) % 2 != 0) {//奇数
					prev = curr;
					curr = curr.next;
				} else {
					// 将pre指向后一个节点
					prev.next = curr.next;
					curr.next = null;
					newEnd.next = curr;// 将当前的偶数放到链尾
					// 链尾后移
					newEnd = curr;
					// 继续判断
					curr = prev.next;
				}
			}
		} else {
			//根据理论,此时curr只有可能是尾节点,有while (curr.val % 2 == 0 && curr != end) 判断
			prev = curr;
		}

		// 尾节点的特殊处理
		if ((end.val) % 2 == 0) {
			prev.next = end.next;
			end.next = null;
			newEnd.next = end;
		}

		return listNode;
	}

}

  

时间: 2024-08-24 16:28:20

将链表中的所有元素为奇数的节点移到元素为偶数节点的前面,并保证奇数之间顺序不变,偶数之间顺序不变。的相关文章

【算法】 调整数组顺序,使得奇数在前偶数在后,分别保证奇数和偶数之间的相对位置不变

题目:输入一个整形数组,将数组重新排序,使得所有奇数在前偶数在后,并使奇数之间和偶数之间的相对位置爆出不变. 思想:从数组开头开始遍历所有数组.当碰到偶数时,将偶数打包,即记录到目前为止偶数的个数,把这些偶数看成一个整体:当碰到奇数时,将这个奇数与前面的偶数整体对调位置. #include <stdio.h> #include <stdlib.h> void nuo(int *a,int j,int nu)                     //将奇数与前面所有偶数调换位置

22 链表中倒数第k个节点(第3章 高质量的代码-代码的鲁棒性)

题目描述: 输入一个链表,输出该链表中倒数第k个结点. 尾节点是倒数第一个节点 测试用例:   功能测试(第k个节点在中间.是头节点.是尾节点) 特殊输入测试(链表头节点是nullptr指针.链表的头节点个数小于k.k=0) 解题思路: 1)使用两个指针,一个指针先移动k步,如果链表小于k,终止返回nullptr.然后两个指针同时移动,知道后一个指针移出最后一个节点 //实现1/* struct ListNode { int val; struct ListNode *next; ListNod

203. 移除链表中的元素 Remove Linked List Elements

Remove all elements from a linked list of integers that have value val. ExampleGiven: 1 --> 2 --> 6 --> 3 --> 4 --> 5 --> 6, val = 6Return: 1 --> 2 --> 3 --> 4 --> 5 题意:移除链表中指定val的元素 注意:考虑删除节点在尾部,以及连续删除两个相邻节点的情况 /** * Definit

javascript中的链表结构—从链表中删除元素

1.概念 上一个博文我们讲到链表,其中有一个方法remove()是暂时注释的,这个方法有点复杂,需要添加一个Previous()方法找到要删除的元素的前一个节点,这一个博文我们来分析一下这个remove()方法. 从链表中删除节点的时候,需要先找到这个待删除节点的前面的节点.找到这个节点之后修改它的next属性,使其指向待删除节点的下一个节点,这样就把待删除节点给删除了,是不是很简单呢?但是问题来了,我们是不是要找到待删除节点的前面一个节点呢?这样就需要添加一个findPrevious()方法来

实现一个算法从一个单链表中返回倒数第n个元素(keep it up)

我们维护两个指针, 它们之间的距离为n.然后,我将这两个指针同步地在这个单链表上移动,保持它们的距离 为n不变.那么, 当第二个指针指到空时,第一个指针即为所求. #include <iostream> struct Node { int data; Node* next; }; void initList(Node* vNode) { for (int i=0; i < 20; ++i) { Node* TempNode = new Node; TempNode->data =

13.删除单链表中重复的元素

13.删除单链表中重复的元素 思路: 用Hashtable辅助,遍历一遍单链表就能搞定.同高级函数9的原因,我不太会使用C++STL中的hash.而如果使用set集合来存储链表中的所有的值,实际上效率和每次重新遍历单链表是一样的.“用了c++标准库中的set来保存访问过的元素,所以很方便的就可以判断当前节点是否在set集合中,直接使用set提供的find函数就可以了.而且使用set的查找在时间复杂度上比较低.”我不太清楚STL中set集合的实现方式,如果是基于类似hash结构的话,那自然效率O(

【LeetCode-面试算法经典-Java实现】【203-Remove Linked List Elements(删除单链表中的元素)】

[203-Remove Linked List Elements(删除单链表中的元素)] [LeetCode-面试算法经典-Java实现][所有题目目录索引] 代码下载[https://github.com/Wang-Jun-Chao] 原题 Remove all elements from a linked list of integers that have value val. Example Given: 1 --> 2 --> 6 --> 3 --> 4 --> 5

【LeetCode-面试算法经典-Java实现】【082-Remove Duplicates from Sorted List II(排序链表中删除重复元素II)】

[082-Remove Duplicates from Sorted List II(排序链表中删除重复元素II)] [LeetCode-面试算法经典-Java实现][所有题目目录索引] 原题 Given a sorted linked list, delete all nodes that have duplicate numbers, leaving only distinct numbers from the original list. For example, Given 1->2->

LintCode Python 简单级题目 452.删除链表中的元素

原题描述: 删除链表中等于给定值val的所有节点. 您在真实的面试中是否遇到过这个题? Yes 样例 给出链表 1->2->3->3->4->5->3, 和 val = 3, 你需要返回删除3之后的链表:1->2->4->5. 标签 链表 题目分析: 删除链表中等于给定值val的所有节点. 遍历链表,找到其中next.val等于val的节点,删除. 注意的地方就是可能链表中的所有元素val都等于val,循环的开始需要从表头开始删除,需要新增一个头节点.