某公司測試題(一)--奇數節點移動到偶數節點之前
阿新 • • 發佈:2019-01-29
題目:
1將連結串列中的所有元素為奇數的節點移到元素為偶數節點的前面,並保證奇數之間順序不變,偶數之間順序不變。
示例:
交換前連結串列的順序 交換後連結串列的順序
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 tuyamobile;
/**
*
* @author huangbin
*
* 基本思想:動態規劃
*
* 每次從頭結點向後查詢奇數節點,如果找到,那麼向前移動,然後繼續重複該種操作。
*
*/
class Node
{
public Node next;
public int value;
public Node(int value){
this.value = value;
}
}
public class TestOne
{
public Node swap(Node list)
{
if(list==null){
return null;
}
Node[] a = new Node[1];
a[0] = list;
int Ocount = 0;//偶節點計數
int length = 0 ;//長度計數
Node temp = list;
while(temp!=null){
length++;
if(jO(temp))
Ocount++;
temp = temp.next;
}
boolean flag = true;
int need = length-Ocount+1;//需要操作的次數
System.out.println("****");
Node pren = list;
int preflag = 0;
for(int i = 0;i<need;i++){
swap2(a[0],a,flag,pren,preflag);
pren = a[0];
}
return a[0];
}
/**
*
* @param flag a[0]中儲存首節點,只有首節點發生交換時才需要重新調整a[0]的值,flag的值是是否需要調整a[0]的判斷依據。
* @param list,以一對節點進行操作,list代表該對節點的第一個節點
* @param a,只有一個元素的陣列,用於儲存連結串列的首節點(因為在操作過程中,list可能不斷後移,因此需要儲存首節點)
* @return boolean, 代表操作是否成功。
*/
public boolean swap2(Node list, Node[] a,boolean flag,Node pren,int preflag)// 用boolean判斷是否到達尾部
{
// 這裡將本節點和下一節點為空的情況攔截。如果有一個為空的情況出現,說明到達尾部,停止操作。
if (list == null)
return true;
if (list.next == null)
return true;
/**
* 下面是非空情況的討論,共分四種情況,奇奇、偶偶、奇偶的情況都採取後移一個節點 而偶奇的情況採取交換處理。
*/
// 偶偶,則後移。
if (jO(list.next) && jO(list))
{
if(preflag==0||preflag==1){
}else{
pren = pren.next;
}
preflag++;
list = list.next;
flag = false;
}
// 奇X的情況均後移。
if (!jO(list))
{
if(preflag==0||preflag==1){
}else{
pren = pren.next;
}
preflag++;
list = list.next;
flag =false;
}
// 偶奇,則交換。
if ((list!=null)&&(list.next!=null)&&!jO(list.next) && jO(list))
{
Node end = list.next.next;//存第三個節點
Node pre = list;//存第一個節點
list = list.next;
list.next = pre;
pre.next = end;
if(preflag!=0){
pren.next = list;
}else{
pren = list;
}
if(flag){
a[0] = list;//只有出現交換的情況,才需要重新確定首節點。
flag = false;
}
}
preflag++;
// 一次調整完畢,再次開始調整。
return swap2(list, a,flag,pren,preflag);
}
//奇偶判斷的輔助方法
public boolean jO(Node node)
{
if (node.value % 2 == 0)
{
return true;
}
return false;
}
//測試
public static void main(String[] args)
{
Node e1 = new Node(73);
Node e2 = new Node(70);
e1.next = e2;
System.out.println((new TestOne().swap(e1)).value);
}
}