【问题标题】:bubble sort implementation on linked lists链表上的冒泡排序实现
【发布时间】:2013-04-08 15:59:48
【问题描述】:

我必须在链表而不是数组上实现 BubbleSort 算法。我是java新手,所以我真的不知道如何将它放入代码中。但我试了一下,结果如下:

SinglyNode.java

public class SinglyNode
{
public Object names;
public SinglyNode next;

public SinglyNode (Object name1)
{
    names = name1;
}

public SinglyNode (Object name2, SinglyNode next1)
{
    names = name2;
    next = next1;
}

Object getObject()
{
    return names;
}

SinglyNode getNext()
{
    return next;
}

void displayLink()
{
    System.out.print("{" + names + "}");
}
}

LinkList.java 我认为我的问题出在方法上。我不知道如何实现 BubbleSort,所以它会按升序对对象名称进行排序。

public class LinkList
{
SinglyNode first;

public boolean isEmpty()
{
    return (first == null);
}

void insertFirst(Object name1)
{
    SinglyNode newNode1 = new SinglyNode(name1);
    newNode1.next = first;
    first = newNode1;
}

SinglyNode delete(Object name2)
{
    SinglyNode temp = first;
    first = first.next;
    return temp;
}

void display()
{
    System.out.print("LIST: \n");
    SinglyNode current = first;
    while(current != null)
    {
        current.displayLink(); // print data
        current = current.next; // move to next link
    }
    System.out.println("\n");
}
//////////////////////////////////////////////////////    
void bubbleSort()
{ 
    Object n = first;
    Object temp = first;

    if (na.compareTo(first) < first.compareTo(na))
    {
        temp = na.compareTo(first);
    } else {
        temp = first.compareTo(na);
    }
    System.out.println(temp);

}

private void swap(Object one, Object two)
{ 
    Object temp = one.names;
    one.names = two.names;
    two.names = temp; 
}
}

SinglyLinkList.java

public class SinglyLinkList
{
public static void main (String args[])
{
    LinkList list = new LinkList();

    list.insertFirst("Squirtle");
    list.insertFirst("Bulbasaur");
    list.insertFirst("Charmander");
    list.insertFirst("Pichu");
    list.insertFirst("Ghastly");
    list.insertFirst("Mewtwo");
    list.insertFirst("Dialga");

    list.display();
    list.bubbleSort();
    list.display();

}
}

【问题讨论】:

    标签: java linked-list bubble-sort


    【解决方案1】:

    对于冒泡排序,两个循环都必须从 0 开始。该算法的某些版本在外循环所在的位置开始内循环。这样做会导致某些数据出现问题。

    如果...您有一个包含以下要排序的数组:

    23,3,1,2,3,4,5

    如果两个循环都从 0 开始,则排序后的数组将是:1、2、3、3、4、5、23

    但如果内循环从 j=i 开始,排序后的数组将是 23、1、2、3、3、4、5。这是因为内循环从第一个元素(即 3 ) 在它把 23 放在正确的位置之后,再也不知道把 3 放在哪里了

    【讨论】:

      【解决方案2】:

      示例链表冒泡排序不使用 elementAt() 函数模拟随机访问,而是通过节点之间的链接进行操作,因此时间复杂度为 O(n^2),而不是更糟。 “end”用于跟踪列表末尾的排序节点从哪里开始。我使用了问题中的示例代码,并没有费心将类更改为可比较的,而是使用 toString() 进行比较。我使用了一个虚拟节点来简化代码。

      void bubbleSort()
      { 
          if(first == null)
              return;
          SinglyNode dmy = new SinglyNode("dummy");  // dummy node
          dmy.next = first;
          // end == null or first sorted node at end of list
          SinglyNode end = null;
          int swap;
          do{
              swap = 0;
              SinglyNode prv = dmy;           // previous node
              while(true){
                  SinglyNode cur = prv.next;  // current node
                  SinglyNode nxt = cur.next;  // next node
                  if(nxt == end){             // if at end node
                      end = cur;              //  update end = cur
                      break;                  //  and break
                  }
                  // if out of order, swap nodes
                  if(cur.names.toString().compareTo(nxt.names.toString()) > 0){
                      cur.next = nxt.next;
                      nxt.next = cur;
                      prv.next = nxt;
                      swap = 1;
                  }
                  prv = prv.next;             // advance to next node
              }
          }while(swap != 0);                  // repeat untl no swaps
          first = dmy.next;                   // update first
      }
      

      【讨论】:

        【解决方案3】:

        在您的列表中,有一个大小字段将有助于存储列表中元素的数量。还要创建类SinglyNode implement Comparable,以便compareTo 方法按照您的意愿运行。 Single LinkedList 中两个元素的就地交换其实是相当麻烦的,而且性能真的很差!

        public void bubbleSort
        {
          for (int i = 0; i < size; i++)
          {
            for (int j = i; j < size; j++)
            {
               if (elementAt(j).compareTo(elementAt(j+1)) > 0)
               {
                  swap(j, j + 1);
               }
            }
          }
        }
        
        public SinglyNode elementAt(int index)
        {
           SinglyNode temp = first;
        
           for (int i = 0, i < index; i++)
           {
              temp = temp.getNext();
           }
        
           return temp;
        }
        
        public void swap(int firstIndex, int secondIndex)
        {
           SinglyNode secondNext = elementAt(secondIndex).getNext();       
           SinglyNode second = elementAt(secondIndex);
           SinglyNode first = elementAt(first);
           SinglyNode firstPrevious = elementAt(first - 1);
        
        
           firstPrevious.setNext(second);
           first.setNext(secondNext);
           second.setNext(first);
        }
        

        【讨论】:

        • 嗯,这仍然适用于字符串吗?我得到错误。也许我不知道如何使用它
        • 也许SinlgyNode 应该包含String 而不是Object。当您implement Comparable 时,您可以返回name.compareTo(other.name),这将使用String 比较。
        【解决方案4】:

        1) 你需要实现 Comparable

        2) 您还需要使用冒泡排序中的交换方法。目前您没有使用它,它只会比较两个对象而不在实际列表中交换它们。

        使用tutorial 表示可比项

        【讨论】:

        • 在不创建数组的情况下我还能使用 Comparable 吗?
        • 你要比较的对象,应该实现Comparable!与数组无关!
        【解决方案5】:

        由于是家庭作业/作业,我将给出提示而不是直接解决方案。冒泡排序可以抽象为这两个操作:对集合的迭代和交换元素。这些操作使用数组或链表实现不同,但算法是相同的。您在display 中进行了迭代,现在您需要实现交换然后执行(非常抽象的伪代码:

        iterate {
         iterate {
          if el.Compare(elNext) > 0 {
            swap(el, el.Next);
          }
         }
        }
        

        【讨论】:

          【解决方案6】:

          你需要在SinglyNode中实现Comparable接口,并在实现内部使用字符串比较方法。比如:

          public void compareTo(SinglyNode node){
              return this.names.toString.compareTo(node.getNames().toString());
          }
          

          或者更好的是this.names.compareTo(node.getNames());

          但是,我会为那些通配符对象使用 Comparable 接口,而不是只使用 Object 类。

          【讨论】:

            猜你喜欢
            • 2014-02-20
            • 1970-01-01
            • 2017-03-11
            • 1970-01-01
            • 2012-07-23
            • 1970-01-01
            • 2011-09-04
            相关资源
            最近更新 更多