有序列表
有序列表的java代码
// sortedList.java
// demonstrates sorted list
// to run this program: C>java SortedListApp
class Link
{
public long dData; // data item
public Link next; // next link in list
// -------------------------------------------------------------
public Link(long dd) // constructor
{ dData = dd; }
// -------------------------------------------------------------
public void displayLink() // display this link
{ System.out.print(dData + " "); }
} // end class Link
class SortedList
{
private Link first; // ref to first item
// -------------------------------------------------------------
public SortedList() // constructor
{ first = null; }
// -------------------------------------------------------------
public boolean isEmpty() // true if no links
{ return (first==null); }
// -------------------------------------------------------------
public void insert(long key) // insert, in order
{
Link newLink = new Link(key); // make new link
Link previous = null; // start at first
Link current = first;
// until end of list,
while(current != null && key > current.dData)
{ // or key > current,
previous = current;
current = current.next; // go to next item
}
if(previous==null) // at beginning of list
first = newLink; // first --> newLink
else // not at beginning
previous.next = newLink; // old prev --> newLink
newLink.next = current; // newLink --> old currnt
} // end insert()
// -------------------------------------------------------------
public Link remove() // return & delete first link
{ // (assumes non-empty list)
Link temp = first; // save first
first = first.next; // delete first
return temp; // return value
}
// -------------------------------------------------------------
public void displayList()
{
System.out.print("List (first-->last): ");
Link current = first; // start at beginning of list
while(current != null) // until end of list,
{
current.displayLink(); // print data
current = current.next; // move to next link
}
System.out.println("");
}
} // end class SortedList
class SortedListApp
{
public static void main(String[] args)
{ // create new list
SortedList theSortedList = new SortedList();
theSortedList.insert(20); // insert 2 items
theSortedList.insert(40);
theSortedList.displayList(); // display list
theSortedList.insert(10); // insert 3 more items
theSortedList.insert(30);
theSortedList.insert(50);
theSortedList.displayList(); // display list
theSortedList.remove(); // remove an item
theSortedList.displayList(); // display list
} // end main()
} // end class SortedListApp
有序列表的效率
在有序列表中,插入和删除一项最多需要O(N)次比较(平均N/2),因为必须沿着链表上一步一步走才能找到正确的位置,然而,可以在O(1)的时间内找到或删除最小值,因为它总在表头,如果一个应用频繁的存取最小值且不需要快速的插入,那么有序链表是一个有效的方案选择,例如,优先级队列可以用有序链表来实现。
表插入排序
有序链表可以用于一种高效的排序机制,假设有一个无需数组,如果从这个数组中去除数据,然后一个一个的插入有序链表,他们自动的按排序排列,把他们从有序链表中删除,重新放入数组,那么数组就会排好序了。这种方式总体上比在数组中用的插入排序效率更高一些,这是因为这种方式进行的复制次数少一些。它仍然是一个时间级为O(N2)的过程,因为有序链表中每插入一个新的链接点,平均要与一半已存在的数据进行比较,如果插入N个新数据,就进行了N2/4次比较,每一个链接点只进行两次复制,一次从数组到链表,一次从链表到数组,在数组中进行插入排序需要N2此移动,相比之下,2*N次移动更好。
表插入排序的代码(利用了插入节点数组的方式排序)
// listInsertionSort.java
// demonstrates sorted list used for sorting
// to run this program: C>java ListInsertionSortApp
class Link
{
public long dData; // data item
public Link next; // next link in list
// -------------------------------------------------------------
public Link(long dd) // constructor
{ dData = dd; }
// -------------------------------------------------------------
} // end class Link
class SortedList
{
private Link first; // ref to first item on list
// -------------------------------------------------------------
public SortedList() // constructor (no args)
{ first = null; } // initialize list
// -------------------------------------------------------------
public SortedList(Link[] linkArr) // constructor (array
{ // as argument)
first = null; // initialize list
for(int j=0; j<linkArr.length; j++) // copy array
insert( linkArr[j] ); // to list
}
// -------------------------------------------------------------
public void insert(Link k) // insert (in order)
{
Link previous = null; // start at first
Link current = first;
// until end of list,
while(current != null && k.dData > current.dData)
{ // or key > current,
previous = current;
current = current.next; // go to next item
}
if(previous==null) // at beginning of list
first = k; // first --> k
else // not at beginning
previous.next = k; // old prev --> k
k.next = current; // k --> old currnt
} // end insert()
// -------------------------------------------------------------
public Link remove() // return & delete first link
{ // (assumes non-empty list)
Link temp = first; // save first
first = first.next; // delete first
return temp; // return value
}
// -------------------------------------------------------------
} // end class SortedList
class ListInsertionSortApp
{
public static void main(String[] args)
{
int size = 10;
// create array of links
Link[] linkArray = new Link[size];
for(int j=0; j<size; j++) // fill array with links
{ // random number
int n = (int)(java.lang.Math.random()*99);
Link newLink = new Link(n); // make link
linkArray[j] = newLink; // put in array
}
// display array contents
System.out.print("Unsorted array: ");
for(int j=0; j<size; j++)
System.out.print( linkArray[j].dData + " " );
System.out.println("");
// create new list
SortedList theSortedList = new SortedList(linkArray);
for(int j=0; j<size; j++) // links from list to array
linkArray[j] = theSortedList.remove();
// display array contents
System.out.print("Sorted Array: ");
for(int j=0; j<size; j++)
System.out.print(linkArray[j].dData + " ");
System.out.println("");
} // end main()
} // end class ListInsertionSortApp
注意:和基于数组的排序相比,表插入排序有一个缺点,就是他要开辟差不多两倍的空间:数组和链表必须同时在内存中存在,但是如果有线程的有序链表类可用,那么表插入排序对不太大的数组排序是比较便利的。