一道算法题:分离数列中的奇偶项
算法 优化?java?
public class SeparateOddEven
{
public static void main(String[] args)
{
int[] arr = {0, 1, 2, 3, 4, 5 ,6 ,7 ,8 ,8 ,9 ,10, 12, 15 ,17};
display(arr);
Separate(arr);
display(arr);
}
//输出数组
public static void display(int[] arr)
{
for(int i = 0; i < arr.length; i++)
{
System.out.print("[" + arr[i] + "]");
}
System.out.println();
}
//交换数组中两个元素的位置
private static void swap(int[] arr, int a, int b)
{
int temp;
temp = arr[a];
arr[a] = arr[b];
arr[b] = temp;
}
//判断给定数组元素是否为奇数
private static boolean isOdd(int[] arr, int pos)
{
if(arr[pos] % 2 == 1)
{
return true;
}
else
{
return false;
}
}
//将数组中的奇偶数分离
public static void Separate(int[] arr)
{
int i, j;
i = 0;
j = arr.length - 1;
while(i < j)
{
if(isOdd(arr, i) == true && isOdd(arr, j) == false)//前奇后偶情况
{
i++;
j--;
}
if(isOdd(arr, i) == false && isOdd(arr, j) == true)//前偶后奇情况(需交换两个元素的位置)
{
swap(arr, i, j);
i++;
j--;
}
if(isOdd(arr, i) == true && isOdd(arr, j) == true)//前奇后奇情况
{
i++;
}
if(isOdd(arr, i) == false && isOdd(arr, j) == false)//前偶后偶情况
{
j--;
}
}
}
}
import org.junit.Test;
/**
* 二叉排序树的节点类
*
*/
class Node{
/**
* 关键字
*/
private int data;
/**
* 左孩子
*/
private Node leftCh;
/**
* 右孩子
*/
private Node rightCh;
/**
* 相同关键字出现的次数
*/
private int count;
public int getData() {
return data;
}
public void setData(int data) {
this.data = data;
}
public Node getLeftCh() {
return leftCh;
}
public void setLeftCh(Node leftCh) {
this.leftCh = leftCh;
}
public Node getRightCh() {
return rightCh;
}
public void setRightCh(Node rightCh) {
this.rightCh = rightCh;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
public Node(int data, Node leftCh, Node rightCh) {
super();
this.data = data;
this.leftCh = leftCh;
this.rightCh = rightCh;
this.setCount(1);
}
public Node(int data) {
super();
this.data = data;
this.setCount(1);
}
public Node() {
super();
this.setCount(1);
}
@Override
public String toString() {
return "Node [data=" + data + "]";
}
}
public class JiAndOu {
/**
* 根节点
*/
private Node root;
public Node getRoot() {
return root;
}
public void setRoot(Node root) {
this.root = root;
}
/**
* 主要算法:
* 1、构建根节点、根节点的左子树、根节点的右子树
* 2、遍历数组,并调用BST的插入算法
* i如果是奇数,插入左子树;否则插入右子树
* 3、插入完成之后,设置全局变量index,分别递归遍历根节点的左、右子树,把关键字放入数组
* 4、输出数组
*/
public void arrayToTree(int[] array){
root=new Node();
for(int i:array){
if(i%2!=0){
this.insertOneNode(i,root.getLeftCh());
}else{
this.insertOneNode(i, root.getRightCh());
}
}
this.midOrder(array, root.getLeftCh());
this.midOrder(array, root.getRightCh());
System.out.println("排序之后:");
for(int i:array){
System.out.print(i+",");
}
}
/**
* 全局变量index,用于把关键字放入目标数组
*/
private int index;
public int getIndex() {
return index;
}
public void setIndex(int index) {
this.index = index;
}
/**
* 中序遍历递归算法
*/
public void midOrder(int[] array,Node p){
if(p!=null){
//递归左子树
this.midOrder(array, p.getLeftCh());
for(int i=1;i<=p.getCount();i++){
//依次把关键字放入数组
array[index]=p.getData();
index++;
}
//递归右子树
this.midOrder(array, p.getRightCh());
}
}
/**
*在BST中插入一个节点
*和《严蔚敏数据结构》的例题基本一致,就是多了个功能:当关键字相同时,相应节点的count++
*/
public void insertOneNode(int i,Node p){
if(p==null){
p=new Node(i);
if(i%2!=0){
root.setLeftCh(p);
}else{
root.setRightCh(p);
}
}else{
Node point=p;
while(true){
if(i<point.getData()){
if(point.getLeftCh()==null){
Node yezi=new Node(i);
point.setLeftCh(yezi);
break;
}else{
point=point.getLeftCh();
continue;
}
}else if(i>point.getData()){
if(point.getRightCh()==null){
Node yezi=new Node(i);
point.setRightCh(yezi);
break;
}else{
point=point.getRightCh();
continue;
}
}else{
int count=point.getCount();
count++;
point.setCount(count);
break;
}
}
}
}
@Test
public void test(){
int[] array={10,11,8,7,2,5,0,9,4,11,8,5,2,7,0,19,14,16};
this.arrayToTree(array);
}
}
public class SortByOddEven {
public static void main(String[] args) {
int[] array = new int[20];
Random rand = new Random();
for (int i = 0; i < array.length; i++) {
array[i] = rand.nextInt(100);
}
System.out.println(Arrays.toString(array));
sort(array);
System.out.println(Arrays.toString(array));
}
public static void sort(int[] array) {
int head = 0;
int tail = array.length - 1;
boolean headIsEven = false;
while (head < tail) {
if (headIsEven) {
if (isOdd(array[tail])) {
swap(array, head, tail);
head++;
headIsEven = false;
}
tail--;
} else {
if (isEven(array[head])) {
headIsEven = true;
} else {
head++;
}
}
}
}
private static boolean isEven(int n) {
return (n & 1) == 0;
}
private static boolean isOdd(int n) {
return (n & 1) != 0;
}
private static void swap(int[] array, int index1, int index2) {
array[index1] ^= array[index2];
array[index2] ^= array[index1];
array[index1] ^= array[index2];
}
}