posts - 12, comments - 3, trackbacks - 0, articles - 0
            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

          2009年12月29日

          快速排序介紹:
          快速排序(Quicksort)是對冒泡法的一種改進。由C. A. R. Hoare在1962年提出。

          基本思想是:
          通過一趟排序將要排序的數據分割成獨立的兩部分,其中一部分的所有數據都比另外一部分的所有數據都要小,然后再按此方法對這兩部分數據分別進行快速排序,整個排序過程可以遞歸進行,以此達到整個數據變成有序序列。

           1 package my.sort;
           2 
           3 public class QuickSort {
           4 
           5     static int a[] = { 101113164325456 };
           6 
           7     public static void sort(int L, int R) {
           8         int i = L - 1;
           9         int j = R;
          10         int tmp;
          11         if (L < R) {
          12             for (; i < R;) {
          13                 while (a[++i] > a[R]) {// 從i開始,從前往后掃描,如果發現大于a[R](數組最后一個值),與之對換
          14                     while (j > 0) {
          15                         if (j <= i) {// 如果i == j結束跳出循環
          16                             break;
          17                         }
          18                         if (a[--j] < a[R]) {// 從J開始,從后往前掃描,如果發現小于a[i],與之對換
          19                             tmp = a[j];
          20                             a[j] = a[i];
          21                             a[i] = tmp;
          22                         }
          23                         
          24                     }
          25                     
          26                     tmp = a[i];
          27                     a[i] = a[R];
          28                     a[R] = tmp;
          29                     
          30                     for(int b : a) {
          31                         System.out.print(b + " ");//打印沒一趟排序結果
          32                     }
          33                     System.out.println();
          34                     
          35                     //把數組分成兩段排序
          36                     sort(L, i-1);//基準數前面的數據進行排列
          37                     sort(i, R);//基準數后面的數據排列
          38                 }
          39             }
          40         }
          41 
          42     }
          43 
          44     public static void main(String[] args) {
          45         System.out.println("排序前:");
          46         for (int b : a) {
          47             System.out.print(b + " ");
          48         }
          49         System.out.println("\n排序過程:");
          50         sort(0, a.length - 1);
          51         System.out.println("排序后:");
          52         for (int b : a) {
          53             System.out.print(b + " ");
          54         }
          55         System.out.println();
          56     }
          57 }
          58 

          posted @ 2010-01-17 16:14 創意恒動力 閱讀(348) | 評論 (0)編輯 收藏

          自我理解java linkedlist插入數據的算法:
          首先看一下,linkedlist插入源代碼:

           1 public class LinkedList
           2     extends AbstractSequentialList
           3     implements List, Deque, Cloneable, java.io.Serializable
           4 {
           5     private transient Entry header = new Entry(nullnullnull);//初始化時先實例一個header,鏈表頭
           6 
           7 
           8     /**
           9      * Constructs an empty list.//構造一個空鏈表
          10      */
          11     public LinkedList() {
          12         header.next = header.previous = header; //把鏈表頭和尾先連到自己(1)
          13         addBefore(e, header);(2
          14 
          15     }
          16 
          17 .
          18 
          19  public boolean add(E e) {//插入鏈表方法
          20             return true;
          21     }
          22 .
          23 
          24 private static class Entry {//每個數據存放,所要用到的靜態內部類
          25      E element;
          26      Entry next;//后一個節點
          27      Entry previous;//接一個節點
          28 
          29      Entry(E element, Entry next, Entry previous) {
          30          this.element = element;
          31          this.next = next;
          32          this.previous = previous;
          33      }
          34 }
          35 
          36 
          37 //插入操作方法
          38     private Entry addBefore(E e, Entry entry) {
          39          Entry newEntry = new Entry(e, entry, entry.previous);(3
          40          newEntry.previous.next = newEntry;(4
          41          newEntry.next.previous = newEntry;(5
          42          size++;(6
          43          modCount++;
          44          return newEntry;
          45     }
          46 
          47 
          48 /*其他方法~~*/
          49 
          50 
          
          

          以上部分就是算法所在:(一個簡單的公式替換過程)

          算法步驟(對應上面的編號):

          (1)實例化一個header (Entry)

          header.next = header

          header.previous = header

          當有第一條數據插入鏈表:

          (3)實例化一個 Entry newEntry (以下簡稱E1)

          E1.next = header

          E1.previous = header.previous

          E1.previous.next = header.previous.next = header.next

          (4)由上面可得:

          newEntry.previous.next = newEntry;

          作用:

          相當于 E1.previous.next = header.next = E1

          其實就是,讓上一個節的next指向下一個節點數據

          所以header.next 的下一個節點就是E1

          (5)E1.next.previous = header.previous = E1(這里用得巧妙)

          其實這個用法單從E1.next.previous= E1單這么看,很直觀因為E1的下一個節點數據的上一個節點就應該是E1

          從上面可知,E1.next == header,為什么要把header.previous = E1呢?

          其實包含著一個遞歸在里面。

          如果再新增一個數據 Entry E2 :

          從上面的代碼可以看出,E2的實例化過程是:(其實linkedlist每次新增一個數據,都通過header傳值)

          Entry E2 = new Entry(data, header, header.previous);

          注意代碼部分的負值。關鍵就是這里,實例化的時候,E2.previous = header.previous = E1
          簡單得完成了負值過程。

          然后 E2.previous.next = E1.next = E2
          E2.next.previous = header.previous = E2 .......(接著插入下一條數據,如此遞歸)

          (6)記錄鏈表位數


          涉及到了一個小小的遞歸算法。

          linkedlist記錄一。完畢。。


          posted @ 2010-01-04 19:23 創意恒動力 閱讀(2533) | 評論 (0)編輯 收藏

          弄了一段時間的tokyocabinet btree結構數據庫。
          存儲的時候發現,tokyocabinet sync同步時,先讓數據存放在內存,然后對比同步文件和內存的數據,使數據達到一直。
          sync()這個tc方法易用,但不好控制。
          稍有不慎就會使持久化文件容量以幾何級數遞增。

          之前自己用mina框架做了一個btree的網絡鏈接端口,起初內存一直飆升。弄了很久都不明白。
          開始以為是mina造成的,而且cpu占用率居高不下。

          后來拆分測試。發現單獨mina的數據傳輸,內存并不高,非常低。
          但是tc的單獨測試發現,寫文件的cpu占用率特高,多線程寫入的情況下,會有明顯阻塞。
          初步了解了jvm gc的算法,如果cpu占用率搞,gc回收內存的能力會明顯下降。
          為了解決這一點,修改了一下網絡端口的框架結構。

          把數據接受端跟數據處理端分開:
          1.接受端可以接受多個socket多線程傳輸,而數據處理端鎖定只接受從接收端的一個或不超過5個scoket傳輸數據。
          對tc的操作,單線程寫入,感覺上比多線程處理流暢,特別在同步優化文件那一刻。
          優化文件,需要的cpu和內存都比較厲害。
          2.tc接受數據以后,不要馬上寫文本。等接受一批(100-10000)數據后,再使用同步方法。
          3.參照第2條,定期優化文件,這樣不至于文件過大。但是數據量增大,文件雖然優化了,寫入速度不會怎么改變。
          4.優化同步文件后,特別在數據量在不斷增大的情況下。不要以為沒有回收內存,其實gc已經很努力回收(長時間觀察jprofiler的統計數據證明了這一點)當你向tc取數據的時候,你會發現,內存會逐級遞減。


          經過一番調整,用jprofiler測試,自己搭建的網絡框架,內存鎖定在250m左右。
          可能到實際運行的時候,內存占用量會增加,但是只會達到一個相當的穩定值。
          現用于公司的隊列系統,內存總量不超過600m,偶爾超過是由于同步文件造成的,等數據穩定后,內存會回到穩定值。以后再作優化,希望能把內存壓制200m左右。

          初學nio,以此為記。

          posted @ 2009-12-29 10:22 創意恒動力 閱讀(767) | 評論 (0)編輯 收藏

          主站蜘蛛池模板: 乐清市| 景德镇市| 东乡族自治县| 古浪县| 密山市| 日照市| 宣汉县| 明光市| 喀喇| 从化市| 嘉善县| 平昌县| 喀喇沁旗| 万盛区| 武功县| 涞水县| 藁城市| 广灵县| 宝清县| 阳原县| 家居| 搜索| 临夏市| 恩施市| 都昌县| 慈溪市| 津南区| 赫章县| 慈利县| 河津市| 屯留县| 五指山市| 胶州市| 定西市| 桑植县| 峨山| 义马市| 南投市| 霍林郭勒市| 察隅县| 元氏县|