有序链表数据结构(同单链表)前端
有序链表添加新的元素: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()); } }