我有一个实现选择排序的功能。分拣工作正常。然而,不知何故,传入的头部从函数体的末尾变为函数调用。不要查看整个代码,只需查看函数调用和函数的最后一行。
import java.util.*;
public class Sorting<E>
{
public static void sort( ListNode<String> head )
{
if ( head == null )
return;
int eff_size;
int size = 0;
ListNode<String> last = null;
for ( ListNode<String> node = head; node != null; node = node.getNext() )
{
size++;
}
System.out.println( "size is " + size );
for ( eff_size = size; eff_size > 1; eff_size-- )
{
ListNode<String> biggest = head;
ListNode<String> node = head;
ListNode<String> biggestprevious = null;
for ( int i = 0; i < eff_size-1; i++ )
{
if ( node.getNext() == null )
break;
if ( node.getNext().getValue().compareTo( biggest.getValue() ) > 0 )
{
biggestprevious = node;
biggest = node.getNext();
}
node=node.getNext();
}
if (biggest.getNext()!=null){
if (biggestprevious!=null && biggest.getNext()!=last){
biggestprevious.setNext( biggest.getNext() );
}
if (head == biggest){
head = biggest.getNext();
}
biggest.setNext( last );
System.out.println(" node is " + node.getValue());
if (node != biggest){
node.setNext(biggest);
}
}
last = biggest;
}
System.out.println("head at function end is - " + head.getValue());
}
public static <E> ListNode<E> buildList( E[] values )
{
ListNode<E> head = null;
ListNode<E> tail = null;
for ( E value : values ) // for each value to insert
{
ListNode<E> node = new ListNode<E>( value, null );
if ( head == null )
{
head = node;
}
else
{
tail.setNext( node );
}
tail = node; // update tail
}
return head;
}
public static void main( String[] args )
{
Scanner kbd = new Scanner( System.in );
boolean done = false;
Sorting<String> ex = new Sorting<String>();
do
{
System.out.println();
System.out.println( " (D) sort( ListNode<String> head )" );
System.out.println( " (Q) Quit" );
System.out.println();
System.out.print( "Enter a choice: " );
String response = kbd.nextLine();
if ( response.length() > 0 )
{
System.out.println();
switch ( response.charAt( 0 ) )
{
case 'D':
case 'd':
ListNode<String> headD = buildList( new String[] {
"B", "F", "K", "Q", "Ant", "Aardvark",
"apple" } );
System.out.println("head before function call is - " + headD.getValue());
sort( headD );
System.out.println("head after function call is - " + headD.getValue());
break;
default:
if ( response.toLowerCase().charAt( 0 ) == 'q' )
{
done = true;
}
else
{
System.out.print( "Invalid Choice" );
}
break;
}
}
} while ( !done );
System.out.println( "Goodbye!" );
}
}
我得到的输出:
在功能结束时是 - Aardvark
函数调用前的是 - B
函数调用后的是 - B
我知道列表已经排序,因为在函数结束时我做了一个:
System.out.println("---------------------------------");
for ( ListNode<String> node = head; node != null; node = node.getNext() )
{
System.out.println(node.getValue());
}
我得到了:
Aardvark
Ant
B
F
K
Q
apple
然而不知怎的,头部搞砸了!
我不明白头部是如何保留为'B'。我是Java(高中)的初学者,根据我的理解,head通过引用传入,因此它应该在函数内部进行更改,并且应该反映出更改。 非常感谢任何帮助。
答案 0 :(得分:2)
您正在将引用传递给单个ListNode - 包含“B”的ListNode。这不应该与表示整个列表的对象混淆 - 这是列表处理库似乎没有提供的(与Java自己的List实现相反)。
在你的排序程序中,你需要跟踪包含最小值的节点并返回(猜测:return head;
),替换主程序中的headD:
headD = sort( headD );
请注意,在sort中更改head是没有用的:head是一个引用,它是通过值传递的,因此在调用时看不到任何更改。