有序鏈表

  1. 有序鏈表數據結構(同單鏈表)前端

    有序鏈表添加新的元素:node

    頭插法 <新節點的數據項小於頭節點 或者 鏈表爲空>:算法

    開始插入以前<鏈表爲空>:數組

    開始插入以前<新節點數據項小於頭節點>:數據結構

    插入以後:工具

    鏈表元素個數>=1oop

    在某個特定元素後面添加元素:測試

    <在node1以後插入node2元素>this

    publicboolean insertAfter(LinkNode node1,LinkNode node2);spa

    有序鏈表刪除特定數據元素:

    刪除頭節點:

 

刪除非頭節點:

 

有序鏈表的查找:

Current 指針依次遍歷有序鏈表直到找到目標數據項

  1.  ADT
    • //有序鏈表:單鏈表節點實現 實質爲單鏈表
      public class  SortedList {
          private static LinkNode first;
       //構造方法 用LinkNode數組初始化 有序鏈表
          public   SortedList(LinkNode[] nodes);
          public static boolean isEmpty();
           //O[N] 從鏈表頭部插入一個元素 找到第一個比輸入參數大的節點插入該位置
          public void insert (LinkNode node);
          //O[1] 從鏈表頭部刪除一個元素
          public LinkNode deleteFirst();
          //O[N]從鏈表頭到尾部顯示每一個節點
          public void displayList();
          //O[N] 查找到某個特定節點
          public LinkNode findNode(double value);
          //o[N] 刪除某個特定節點
              public LinkNode deleteNode(LinkNode l);                                                                                           
           //o[N]在某個特定節點node1後插入一個節點node2
              public boolean insertAfter(LinkNode node1,LinkNode node2);
          }
  2. 程序
    • public class  SortedList {
          private static LinkNode first;
       
          public static LinkNode getFirst() {
              return first;
          }
           
          public   SortedList( ){
              first = null;
          }
          public   SortedList(LinkNode[] nodes){
              //initailize list copy arry to the SortedList
              first = null;
              for(int j=0;j<nodes.length;j++){ 
                  insert(nodes[j]);
              }
              
          }
          public static boolean isEmpty(){
              return (first==null);
          }
          //找到第一個比輸入參數大的節點插入該位置 
          public void insert (LinkNode node){//O[N]
              LinkNode current = first;
              LinkNode pre = null;
              while(current!=null&&current.iData<node.iData){
                  pre = current;
                  current = current.next;
              }
              node.next = current;
              if(pre==null){  
                  first = node; 
              }else{
                  pre.next = node;
              }
          }
          public LinkNode deleteFirst(){//O[1]
              if (isEmpty()){
                  return null;
              }
              LinkNode temp = first;
              first = first.next;
              return temp;
          }
          public void displayList(){
              System.out.println(" List (first-->last): ");
              LinkNode current = first;
              while (current!=null){
                  current.displayLink();
                  current = current.next;
              }
              System.out.println("");
          }
          public LinkNode findNode(double value){
              LinkNode current = first;
               while (current!=null){
              //     current.displayLink();
                   if(current.dData ==value){
                       return current;
                       }
                      current = current.next;
                   }
                  return null;
              }
              public LinkNode deleteNode(LinkNode l){     //o[n]                                                    
                    LinkNode current = first;                                                                   
                    LinkNode pre = current;                                                                     
                    while (current!=null){//the  loop end condition:traverse to the last node of the link       
                        if(current.dData == l.dData && current.iData==l.iData){//find the node                    
                          if(current == first) first = first.next;                                                
                            pre.next = current.next;                                                                
                            return current;                                                                         
                        }else{//go on to find it                                                                  
                            pre = current;                                                                          
                            current = pre.next;                                                                     
                        }                                                                                         
                    }                                                                                           
                    return null;                                                                                
                }                                                                                             
                                                                                                            
           
              public boolean insertAfter(LinkNode node1,LinkNode node2){
                  //找到這個特定節點
                   LinkNode  target = findNode(node1.dData);
                   System.out.println("target  ");
                   target.displayLink();
                   if (target!=null){
                       node2.next         = target.next; 
                       target.next= node2;
                       return true;
                   }
                  return false;
              }
          }
      public class SortedListApp {
          public static void main(String[] args) {
              //make a new list
              SortedList sl = new SortedList();
              sl.insert(new LinkNode(11,11.11));
              sl.insert(new LinkNode(33,33.33));    
              sl.insert(new LinkNode(44,44.44));
              sl.insert(new LinkNode(66,66.66));
              sl.insert(new LinkNode(55,55.55));
              sl.displayList();
          }
      }
  3. 有序鏈表的應用
    1. 表插入排序
      1. 概要
      • 有序鏈表能夠用於一種高效的排序機制。
        主要步驟:
        1 準備待排序數組
        1 初始化鏈表,將數組數據插入鏈表中 
        2  遍歷鏈表尋找插入位置  
        3 記錄插入鏈表中
        4 將鏈表數據元素刪除,並將刪除的元素記錄到數組之中
      1. 代碼
        1. LinkList 引用1.2.2 程序
          SortedList 引用 2.3 程序
        2. public class ListInsertionSortArray {
              private SortedList s1;//有序鏈表做爲工具屬性 
              private int[] arr;//待排序的數組
              //O[N^2] 
              /*構造方法:
              1 準備待排序數組
              2 初始化鏈表,將數組數據插入鏈表中 
              3  遍歷鏈表尋找插入位置  
              4 記錄插入鏈表中*/
              public ListInsertionSortArray(int[] arr){
                  this.arr = arr;
                  LinkNode[] linkNodes = new LinkNode[arr.length];
                  System.out.println("有序鏈表排序以前");
                  for(int i=0;i<arr.length;i++){
                      //將輸入參數 數組變成有序鏈表節點數組 Link[]
                      System.out.print(arr[i]+" ");
                      LinkNode link = new LinkNode (arr[i],arr[i]+0.1);
                      linkNodes[i] = link;
                  }
                  s1 = new SortedList(linkNodes);
                  System.out.println();
              }
              //4 將鏈表數據元素刪除,並將刪除的元素記錄到數組之中  算法時間複雜度 :O[N]
              public int[] sortArr(){
                  for(int j=0;j<arr.length;j++){
                      arr[j] = s1.deleteFirst().iData;
                  }
                  return arr;
              }
          }
        3. public class ListInsertionSortArrayApp {
              public static void main(String[] args) {
                  int[] arr = {10,20,78,67,6,1};//待排序數組
                  ListInsertionSortArray listSortArr =// 
                          new ListInsertionSortArray(arr);
                  arr = listSortArr.sortArr();
                  System.out.println("有序鏈表排序以後 :");
                  for(int i = 0;i<arr.length;i++){
                      System.out.print(arr[i]+"  ");
                  }
              }
          }
      2. 效率分析
      •  平均時間和最壞狀況下(待排序序列逆序)時間複雜度o(n^2),
         再來看一下最佳狀況(待排序序列有序), 關鍵字比較次數併爲o(1),時間複雜度爲o(n). 
    2. 優先級隊列
      • 根據有序鏈表的特色:在有序鏈表中,數據是按照關鍵值有序排列的,有序鏈表的刪除,經常只限定於刪除在鏈表頭部的最小或者最大的節點。
        若是一個應用頻繁的存取最小項(或者最大項) 且不須要快速的插入 .在搶佔式多任務操做系統中,程序就在優先級隊列中排序。.那麼考慮使用優先級隊列.
        優先級隊列和隊列的區別就是,優先級隊列是按關鍵字排序的。而每次新數據進入隊列,也會根據須要將數據插入到應該的位置,以便確保隊列的順序。
      • 優先級隊列特色:
            first in first out(先進先出)
        方法總結:
        Queue 
        insert() //鏈表尾部插入一個新的元素
        remove()//鏈表頭部刪除一個元素
        peekFront()//查詢鏈表最前端的一個元素
        size()//鏈表元素個數
      • ADT
        • class PriorityQ
             { //-------------------------------------------------------------
             public void insert(long item) ;   // insert item 
          //-------------------------------------------------------------
             public long remove()     ;        // remove minimum item 
          //-------------------------------------------------------------
             public long peekFront()          ;  // peek at minimum item 
          //-------------------------------------------------------------
             public boolean isEmpty()     ;    // true if queue is empty  
          //-------------------------------------------------------------
           }  // end class PriorityQ
      • 代碼
        • class PriorityQ
          {    //有序鏈表 
              private SortedList list;
              public PriorityQ(){
                  list = new SortedList();
              }
              //鏈表尾部插入一個新的元素
              public void insert(LinkNode node){
                  list.insert(node);
              } 
              //鏈表頭部刪除一個元素
              public LinkNode remove(){
                  return list.deleteFirst();
              }
              //查詢鏈表最前端的一個元素
              public LinkNode peekFront(){
                  return list.getFirst();
              }
              public void display(){
                  list.displayList();
              }
              public boolean isEmpty(){return list.isEmpty();}
          }  // end class PriorityQ
          ////////////////////////////////////////////////////////////////
          class PriorityQApp
          {
          public static void main(String[] args)
             {
                 PriorityQ thePQ = new PriorityQ( );
                    thePQ.insert(new LinkNode(30,30.1));
                    thePQ.insert(new LinkNode(50,50.1));
                    thePQ.insert(new LinkNode(10,10.1));
                    thePQ.insert(new LinkNode(40,40.1));
                    thePQ.insert(new LinkNode(20,20.1));
          
                    while( !thePQ.isEmpty() )
                       {
                       int item = thePQ.remove().iData ;
                       System.out.print(item + " ");  // 10, 20, 30, 40, 50
                       }  // end while
                    System.out.println("");
             }
            
          }  // end class PriorityQApp
          ////////////////////////////////////////////////////////////////
    3. 其餘應用程序
      1. 單詞字典順序排序
        • 編寫一個程序,將全部輸入的單詞按字典順序輸出,不區分大小寫。
          輸入:測試數據不超過5000行,每行不超過200個字符。EOF結束輸入。
          輸出:全部輸出皆爲小寫形式。每行輸出一個單詞。
          例如 : 
              輸入 : you are the best one
              輸出 : are best one the you
        • 1 將字符串拆分爲 String[]
          2 將字符數據轉化爲:數據域爲char數組類型的單鏈表節點
          3 將上述節點插入到有序數組之中
          4 將有序數組中的元素逐一刪除,並裝從新入String[]
          5 返回數據
        • 鏈表節點代碼
          • public interface Node {
                public Object data = null;
                public Node next=null;
                public void display();
            }
        • 有序鏈表
          • public class CharListNode  implements Node {
                public char[] data ;
                public CharListNode next;
                
                public CharListNode(char[] data) {
                    super();
                    this.data = data;
                    this.next = null;
                }
                public void display() {
                    System.out.print(new String(data)+"  ");
                }
            
            }
        • APP
          • public class OutPutWordInDictionaryOrder  {
                        /*
                        1 將字符串拆分爲 String[]
                        2 將字符數據轉化爲:數據域爲char數組類型的單鏈表節點
                        3 將上述節點插入到有序數組之中
                        4 將有序數組中的元素逐一刪除,並裝從新入String[]
                        5 返回數據*/
                //輔助工具類有序鏈表
                public static SortedCharListLink link = new SortedCharListLink();
                //輸入字符串
                public static String input = " ";
                //鏈表的各個節點組成的數組
                static CharListNode[] nodes ;
                public OutPutWordInDictionaryOrder(String input){
                    this.input = input;
                }
                public static String sortWordOrder( ){
                    String result ="";
                    String[] strs = input.split(" ");
                    nodes = new CharListNode[strs.length];
                    for(int i=0;i<strs.length;i++){
                        nodes[i] = new CharListNode(strs[i].toCharArray());
                        link.insert(nodes[i]);
                    }
                    for(int i=0;i<strs.length;i++){
                        char[] chars = (char[]) link.deleteFirst().data;
                         result += new String(chars)+" ";
                    }
                    return result;
                }
                public static void main(String[] args) {
                    String input = "you are not bad girl";
                    System.out.println("原始的字符串是 :"+input);
                    OutPutWordInDictionaryOrder o = new OutPutWordInDictionaryOrder("you are not bad girl");
                    String result = o.sortWordOrder();
                    
                    System.out.println("排序後的字符串是 :"+result) ;
                }
            }
      2. 反向輸出字符串
        1. 鏈表節點
          1. /*數據域爲 char 類型的單鏈表節點*/
            public class CharLinkNode implements Node{
                public char  data;
                public CharLinkNode next;
                
                public CharLinkNode(char data){
                    this.data = data; 
                }
                public void setData(char  data){
                    this.data = data;
                }
                public char  getData(){
                    return this.data ;
                }
             
                public void setNext(CharLinkNode next) {
                    this.next = next;
                }
                public void display(){
                    String str = new String();
                    System.out.print(data+"  ");
                }
            }
        2. /*有序單鏈表*/
          public class SortedCharLink {
              private CharLinkNode first;
              public SortedCharLink(){
                  
              }
              public SortedCharLink(CharLinkNode[] links){
                  //initailize list copy arry to the SortedList
                  first = null;
                  for(int i=0;i<links.length;i++){
                       insert(links[i]);
                  }
              }
              public boolean isEmpty(){
                  return first==null;
              }
              /*O[1]*/
              public CharLinkNode remove(){
                  CharLinkNode link = first;
                  first = first.next;
                  return link;
              }
              /*O[N]*/
              public void insert(CharLinkNode linkNode){
                  CharLinkNode current=first;
                  CharLinkNode pre = null;
                  //找出新節點的位置
                  while(current!=null&&current.getData()>linkNode.getData()){
                      pre = current;
                      current = current.next;
                  }
                  if(pre!=null){
                      pre.next= linkNode;
                      linkNode.setNext(current);
                  }else{
                      linkNode.next = first;
                      first  = linkNode;
                  }
              }
              public void displayList(){
                  CharLinkNode current=first;
                  System.out.println("Display Order: from front to end");
                  while(current!=null){
                      System.out.print
                      (current+" -- ");
                      current = current.next;
                  }
                  System.out.println();
              }
              public static void main(String[] args) {
                  System.out.println('a'>'b');
              }
          }
        3. /*利用棧的特性將字符串反向輸出
           * input :輸入的字符串
           * output:反向輸出的字符串
           * */
          public class Reverser {
              private String input;
              private String output;
              public Reverser(String in){
                  input=in;
              }
              public String doReverse(){
                  String result = "";
                  //將輸入字符串轉化爲char字符數組
                  char[] chars = input.toCharArray(); 
                  CharLinkNode[] nodes = new CharLinkNode[chars.length] ;
                  //將每一個 char字符分別裝入對應的鏈表節點當中
                  for(int i=0;i< chars.length;i++){
                      nodes[i] = new CharLinkNode(chars[i] ); 
                  }
                  SortedCharLink link = new SortedCharLink(nodes);
                  //初始化節點數組
                  for(int i=0;i<chars.length;i++){
                      chars[i]=link.remove().getData();
                  }
                  result = new String(chars);
                  this.output = result;
                  return output;
              }
          }
        4. public class ReverserApp {
              public static void main(String[] args) {
                  Reverser rs = new Reverser("abcdefg");
                  System.out.println(rs.doReverse());
              }
          }
相關文章
相關標籤/搜索