1. 程式人生 > >某公司測試題(一)--奇數節點移動到偶數節點之前

某公司測試題(一)--奇數節點移動到偶數節點之前

題目:

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); } }