对传递给java函数的变量的值感到困惑

时间:2015-01-16 05:49:08

标签: java sorting

我有一个实现选择排序的功能。分拣工作正常。然而,不知何故,传入的头部从函数体的末尾变为函数调用。不要查看整个代码,只需查看函数调用和函数的最后一行。

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通过引用传入,因此它应该在函数内部进行更改,并且应该反映出更改。 非常感谢任何帮助。

1 个答案:

答案 0 :(得分:2)

您正在将引用传递给单个ListNode - 包含“B”的ListNode。这不应该与表示整个列表的对象混淆 - 这是列表处理库似乎没有提供的(与Java自己的List实现相反)。

在你的排序程序中,你需要跟踪包含最小值的节点并返回(猜测:return head;),替换主程序中的headD:

headD = sort( headD );

请注意,在sort中更改head是没有用的:head是一个引用,它是通过值传递的,因此在调用时看不到任何更改。