【问题标题】:Insertion Sort from T Cormen BookT Cormen 书中的插入排序
【发布时间】:2012-01-02 14:34:00
【问题描述】:

我正在阅读 Cormen 的“算法简介”一书,并从伪代码创建了以下内容。但是,Array 的前两个元素似乎没有排序。我无法发现错误(可能是因为它迟到了)。所以我想知道是否有人可以第一眼看到。

#include <iostream>
#include <stdlib.h>

using namespace std;

int main(){
  int input;
  cout << "Enter length of desired array." << "\n";
  cin >> input;
  cout << "\n";

  int A [input];

  //Populate and print the Array.
  for(int i=0; i<input; i++){
    A[i] = rand()%99-1;
    cout << A[i] << " ";
  }

  cout << "\n";

  //Insertion sort.
  for(int j=2; j<input; j++){ //Iterate through the Array.
    int key = A[j]; //Store the current element into key.
    int i = j-1; //Iterator for while loop.
    while(i>0 && A[i]>key){ //Loop to insert A[j] into the sorted sequence.
      A[i+1] = A[i]; //Move the element.
      i=i-1; //New value of i.
      A[i+1] = key; //Update the key
    }
  }

  for(int i=0; i<input; i++){
    cout << A[i] << " ";
  }
  return 0;
}

【问题讨论】:

  • 你试过调试这个吗?您是否在最小数据集上运行?
  • 那本书使用基于 1 的索引 iirc,这将是您的问题。

标签: c++ algorithm sorting insertion-sort


【解决方案1】:

更改为for (int j = 1; ...)

【讨论】:

    【解决方案2】:

    我没有仔细看,但我认为这本书的伪代码使用从 1 开始的索引,而对于用 C(或大多数现代语言)进行编码,您需要将其调整为从 0 开始的索引。

    主要嫌疑人是

    for(int j=2; j<input; j++)
    

    您可能希望从 1 而不是 2 开始。

    终止条件

    while(i>0 && A[i]>key)
    

    可能还需要更改以确保您高于 -1 而不是 0。

    编辑:

    仔细观察后,我很确定您确实还必须调整while

    当然,您还应该查看类似的一对一问题的所有上限。

    【讨论】:

      【解决方案3】:

      实际上您的代码是正确的,但问题在于您的 for 循环初始化。插入排序的伪代码是:

      for j ←1 to length(A)-1
       key ← A[ j ]
       > A[ j ] is added in the sorted sequence A[0, .. j-1]
       i ← j - 1
       while i >= 0 and A [ i ] > key
           A[ i +1 ] ← A[ i ]
           i ← i -1
       A [i +1] ← key
      

      实际上您的代码没有考虑数组的第一个元素。它只是从数组的第二个元素开始排序,你会得到那种类型的结果。

      只要把j的初始化改成1就可以正常运行了。

      【讨论】:

        【解决方案4】:

        您可以使用此代码,我已更正您的错误

        #include<iostream>
        #include<stdlib.h>
        #include<cstdlib>
        
        using namespace std;
        
        int main(){
            int input;
        
            cout<< "Enter length of desired array";
            cin>>input;
        
            cout<<"\n";
        
            int A[input];
        
            for(int i = 0 ;i <input ; i++)
            {
                A[i] = rand() % 100;   
                cout<<A[i] << "\t";
            }
        
            cout<<"\n";
        
            for(int j =1; j<input ; j++)
            {   int i;
                int key = A[j];
                i = j-1;
                while( i >=0 && A[i] > key)
                {
                    A[i+1] = A[i];
                    i = i-1;
                    A[i+1] = key;
                }
            }
        
            for(int i = 0 ;i <input ; i++)
            {
                cout<<A[i] << "\t";
            }
        }
        

        【讨论】:

          【解决方案5】:

          看一下java翻译的CLRS插入排序算法。

          int a[] = {5,2,4,3,1};
              int key;
              int i;
              for(int j = 0; j < 5; j++)
              {
                  key = a[j];
                  i = j - 1;
          
                  while(i>=0 && a[i]>key)
                  {
                      a[i+1]= a[i];
                      i--;
                  }
                  a[i+1] = key;
          
                  System.out.println("i in for loop "+i);
          
                  for(int k=0; k<a.length;k++)
                  {
                      System.out.print(a[k]+" ");
                  }
              }
          

          【讨论】:

          • 第一个 for 循环不应该从 1 开始(即 j=1)。在插入排序中,总是对第一个元素进行排序。因此,我们从第二个元素开始。在 Java 中,数组索引是从 0 开始的。所以,它必须从 j=1 开始
          【解决方案6】:
          Book's pseudocode uses one-based indexing, and for coding in C (or most modern languages) you need to adjust it to zero-based indexing.  
          Make the following changes and it will work:
          
              for(int i=1; i<input+1; i++){
                  A[i] = rand()%99-1;
                  cout << A[i] << " ";
                }
          
          
            for(int j=2; j<input+1; j++){ //Iterate through the Array.
              int key = A[j]; //Store the current element into key.
              int i = j-1; //Iterator for while loop.
              while(i>0 && A[i]>key){ //Loop to insert A[j] into the sorted sequence.
                A[i+1] = A[i]; //Move the element.
                i=i-1; //New value of i.
                A[i+1] = key; //Update the key
              }
            }
          
              for(int i=1; i<input+1; i++){
                  cout << A[i] << " ";
                }
          

          【讨论】:

            【解决方案7】:

            这是答案,请先阅读 Don Roby 的解释。

            开始 j = 1 和 while 循环应该有 i &gt;= 0

            【讨论】:

              猜你喜欢
              • 2013-07-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2011-12-27
              • 1970-01-01
              • 2011-07-07
              相关资源
              最近更新 更多