有序鏈表數據結構(同單鏈表)前端
有序鏈表添加新的元素:node
頭插法 <新節點的數據項小於頭節點 或者 鏈表爲空>:算法
開始插入以前<鏈表爲空>:數組
開始插入以前<新節點數據項小於頭節點>:數據結構
插入以後:工具
鏈表元素個數>=1oop
在某個特定元素後面添加元素:測試
<在node1以後插入node2元素>this
publicboolean insertAfter(LinkNode node1,LinkNode node2);spa
有序鏈表刪除特定數據元素:
刪除頭節點:
刪除非頭節點:
有序鏈表的查找:
Current 指針依次遍歷有序鏈表直到找到目標數據項
//有序鏈表:單鏈表節點實現 實質爲單鏈表 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); }
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&¤t.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(); } }
有序鏈表能夠用於一種高效的排序機制。
主要步驟:
1 準備待排序數組
1 初始化鏈表,將數組數據插入鏈表中
2 遍歷鏈表尋找插入位置
3 記錄插入鏈表中
4 將鏈表數據元素刪除,並將刪除的元素記錄到數組之中
LinkList 引用1.2.2 程序
SortedList 引用 2.3 程序
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; } }
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]+" "); } } }
平均時間和最壞狀況下(待排序序列逆序)時間複雜度o(n^2),
再來看一下最佳狀況(待排序序列有序), 關鍵字比較次數併爲o(1),時間複雜度爲o(n).
根據有序鏈表的特色:在有序鏈表中,數據是按照關鍵值有序排列的,有序鏈表的刪除,經常只限定於刪除在鏈表頭部的最小或者最大的節點。
若是一個應用頻繁的存取最小項(或者最大項) 且不須要快速的插入 .在搶佔式多任務操做系統中,程序就在優先級隊列中排序。.那麼考慮使用優先級隊列.
優先級隊列和隊列的區別就是,優先級隊列是按關鍵字排序的。而每次新數據進入隊列,也會根據須要將數據插入到應該的位置,以便確保隊列的順序。
優先級隊列特色:
first in first out(先進先出)
方法總結:
Queue
insert() //鏈表尾部插入一個新的元素
remove()//鏈表頭部刪除一個元素
peekFront()//查詢鏈表最前端的一個元素
size()//鏈表元素個數
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 ////////////////////////////////////////////////////////////////
編寫一個程序,將全部輸入的單詞按字典順序輸出,不區分大小寫。
輸入:測試數據不超過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)+" "); } }
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) ; } }
/*數據域爲 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+" "); } }
/*有序單鏈表*/ 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&¤t.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'); } }
/*利用棧的特性將字符串反向輸出 * 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; } }
public class ReverserApp { public static void main(String[] args) { Reverser rs = new Reverser("abcdefg"); System.out.println(rs.doReverse()); } }