錦標賽排序演算法 java版

來源:互聯網
上載者:User

今天在做遊戲的聯賽系統,假如有N 人報名參加聯賽,伺服器記錄下報名人數,並對這些人的戰鬥後的結果進行排序,決出前16強或者8強。

網上找了下錦標賽排序演算法,內容真少。總結下:

1:建樹:這裡說的建樹是建立一顆完全二叉樹。當參加排序的數組不足2的N次冪,將其補足。直到滿足建立一個完全二叉樹

2:當某結點的比較對手的參選標誌為“不再參選”,該結點自動升入雙親結點,此動作不計入排序碼比較次數。每次比較出來的第一名都標記為不參賽。

3:最終結果是返回到原來的數組之中

4:堆排序,資料很多,不多說。

/** * 聯賽系統分組 *  * @author Administrator */public class Competition {/** * Player改為玩家ID儲存 */private Player[] playerArray;public Competition() {int playerNum = World.getIns().getCompetition().size();Player[] playerArray = (Player[]) World.getIns().getCompetition().toArray();TournamentSort(playerArray,playerNum);//比賽後結果排序按照數組順序,放入playerArray中}/** * 建立一顆樹 * @param a * @param n */public static void TournamentSort(Player[] player, int n) {TournamentPlayer[] tree;int bottomRowSize = nearestPowerOfTwo(n);// 計算滿足>=n的2的最小次冪的數:int TreeSize = 2 * bottomRowSize - 1;int loadindex = bottomRowSize - 1; // 外結點開始位置:從根節點開始往下數tree = new TournamentPlayer[TreeSize];for (int i = 0; i < TreeSize; i++) {tree[i] = new TournamentPlayer();}int j = 0; // 在數組player中取資料指標for (int i = loadindex; i < TreeSize; i++) { // 複製數組資料到樹的外結點中tree[i].setIndex(i); // 下標if (j < n) {tree[i].setActive(1);tree[i].setData(player[j++]);} // 複製資料else {tree[i].setActive(0); // 後面的結點為空白的外結點}// System.out.println(tree[i].getIndex()+" "+ tree[i].getData());}int i = loadindex; // 進行初始比較尋找最小的項while (i != 0) {j = i;while (j < 2 * i) { // 處理各對比賽者Player playerRight = tree[j].getData();Player playerLeft = tree[j + 1].getData();// @ TODO 計算戰鬥,返回左邊贏boolean isLeftWin = true;if (tree[j + 1].getActive() == 0 || isLeftWin == true)tree[(j - 1) / 2] = tree[j]; // 勝者送入雙親elsetree[(j - 1) / 2] = tree[j + 1];// System.out.println(tree[(j - 1) / 2].getIndex()+" "+ tree[(j// - 1) / 2].getData());j += 2; // 下一對參加比較的項}i = (i - 1) / 2; // i退到雙親, 直到i=0為止// System.out.println(tree[(j - 1) / 2].getIndex() + " "// + tree[(j - 1) / 2].getData());}for (i = 0; i < n - 1; i++) { // 處理其它n-1元素player[i] = tree[0].getData(); // 當前最小元素送數組aSystem.out.println(player[i]);tree[tree[0].getIndex()].setActive(0); // 該元素相應外結點不再比賽UpdateTree(tree, tree[0].getIndex()); // 從該處向上修改}player[n - 1] = tree[0].getData();System.out.println(player[n - 1]);// return tree;}/** * 每次比較出勝者之後,更新得到下一次比較的勝者 * i是表中當前最小元素的下標, 即勝者。從它開始向上調整。 * @param tree * @param i */public static void UpdateTree(TournamentPlayer[] tree, int i) {if (i % 2 == 0)tree[(i - 1) / 2] = tree[i - 1]; // i為偶數, 對手為左結點elsetree[(i - 1) / 2] = tree[i + 1]; // i為奇數, 對手為右結點// 最小元素輸出之後, 它的對手上升到父結點位置i = (i - 1) / 2;int j = 0;// i上升到雙親結點位置while (i != 0) {if (i % 2 == 0)j = i - 1; // 確定i的對手是左結點還是右結點elsej = i + 1;if (tree[i].getActive() == 0 || tree[j].getActive() == 0) {// 比賽對手中間有一個為空白if (tree[i].getActive() != 0)tree[(i - 1) / 2] = tree[i];elsetree[(i - 1) / 2] = tree[j];}// 非空者上升到雙親結點else // 比賽對手都不為空白{Player playerRight = tree[i].getData();Player playerLeft = tree[j].getData();// @ TODO 計算戰鬥,返回左邊贏boolean isLeftWin = true;if (isLeftWin)tree[(i - 1) / 2] = tree[i];elsetree[(i - 1) / 2] = tree[j]; // 勝者上升到雙親結點i = (i - 1) / 2; // i上升到雙親結點}}}/** * 得到最接近且大於 * number的2的N的方 * @param number * @return */public static int nearestPowerOfTwo(int number) {--number;number |= number >> 16;number |= number >> 8;number |= number >> 4;number |= number >> 2;number |= number >> 1;++number;return number;}public static void main(String[] args) {Player[] relust =  new Competition().getPlayerArray();}public Player[] getPlayerArray() {return playerArray;}public void setPlayerArray(Player[] playerArray) {this.playerArray = playerArray;}}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.