0

連結リストのコードを書きます: 連結リストの定義:

struct Node {
    // data is used to store an integer value in this node
    int data;
    // a pointer points to the next node
    Node* link;
    // inializes the node with a 0 value in data and a null pointer in link
    Node() : data(0), link(NULL) {};
    // destructor release space allocated to the linked list
    ~Node() {delete link;}
};

リンクされたリストを表示:

void display_and_count(Node* aLink) {
    cout << "Entries: ";
    int nodeNumber = 0;                         // elements number of linked list
    for(Node* iterator = aLink; iterator->link != NULL; iterator=iterator->link) {
        cout << iterator->data << ", ";
        nodeNumber++;
    }
    cout << "contans " << nodeNumber << " nodes." << endl;
}// end display_and_count

ここで、しきい値に基づいて 1 つの連結リストを 2 つの LESS と MORE に分割し、元の連結リストのノードを削除する関数を作成します。

void split_them_up(Node* aLink, Node* less, Node* more, int threshold) {
    Node* lessHead = less;                              // head of less
    Node* moreHead = more;                              // head of more
    bool isThresholdInALink = false;                    // store if threshold is an element of aLink
    for(Node* iterator = aLink; iterator->link != NULL; iterator = iterator->link) {
        if(iterator->data < threshold) {
            less->data = iterator->data;
            less->link = new Node;
            less = less->link;
        }
        else if(iterator->data > threshold) {
            more->data = iterator->data;
            more->link = new Node;
            more = more->link;
        }
        else {
            isThresholdInALink = true;
        }
    } // end for(Node* iterator = aLink; iterator->link != NULL; iterator = iterator->link)

    less = lessHead;
    more = moreHead;

    delete aLink;
    // If threshold is an element of aLink, then the new linked list contains the only threshold.
    // If threshold isn't in aLink, then the new linked list contains nothing
    aLink = new Node;
    if(isThresholdInALink) {
        aLink->data = threshold;
        aLink->link = new Node;
    } // end if(isThresholdInALink)*/
} // end split_them_up

次に、これが主な機能です。

int main() {
    Node* ENTRIES = new Node;           // define a linked list

    get_input(ENTRIES);
    display_and_count(ENTRIES);

    Node* less = new Node;              // define less list
    Node* more = new Node;              // define more list
    cout << "Enter a threshold: ";
    int thd;                            // threshold
    cin >> thd;
    split_them_up(ENTRIES, less, more, thd);

    cout << "Less list: " << endl;
    display_and_count(less);
    cout << "More list: " << endl;
    display_and_count(more);
    cout << "ENTRIES: " << endl;
    display_and_count(ENTRIES);
}

get_input 関数は、ユーザーから整数を取得し、最後に -1 を取得します。

void get_input(Node* aLink) {
    Node* head = aLink;                 // head of linked list
    int capacity=1;                     // the capacity of intArray
    int* intArray = new int[capacity];  // an array stores user input
    int size=0;                         // actual number of elements stored in the intArray

    cout << "Input some integers, -1 to end: ";
    while(true) {
        int input;
        cin >> input;
        if(input == -1) break;
        if(!isContained(intArray, size, input)) {
            intArray[size]=input;
            size++;
            // if size meets capacity, double capacity
            if(size >= capacity) {
                int* temp = new int[capacity];
                int oldCapacity = capacity;
                for(int i=0; i < oldCapacity; i++) temp[i]=intArray[i];
                delete[] intArray;
                capacity = 2*capacity;
                intArray = new int[capacity];
                for(int i=0; i < oldCapacity; i++) intArray[i]=temp[i];
                delete[] temp;
            } // end if(size >= capacity)
        } // end if(!contained(intArray, size, input))
    } // end while(true)

    for(int i=0; i<size; i++) {
        aLink->data = intArray[i];
        aLink->link = new Node;
        aLink = aLink->link;
    }
    delete[] intArray;
    aLink = head;
} // end get_input

含まれています:

bool isContained(int* array, int aSize, int n) {
    for(int i=0; i<aSize; i++) {
        if(array[i] == n) return true;
    }
    return false;
} // end isContained

Linux システムで実行する場合、すべて問題ありません。しかし、Windows では、split_them_up の後に ENTRIES にランダムな値が表示され、プログラムがクラッシュして「アクセス違反の読み取り場所」が表示されます。

4

2 に答える 2

1

これで問題が解決するかどうかはわかりませんが、ノードにそのようなデストラクタが必要ないことは確かです。

  1. 新しくないので、削除する必要はありません。
  2. 次のノード、次のノード、次のノードの削除をトリガーする場合、リストの特定のノードの削除をどのように実装しますか?
于 2013-03-28T20:53:28.417 に答える
0

もちろん、操作するとクラッシュしますENTRIES。関数は、それが指すオブジェクトをsplit_them_up削除しました。Node

見た目からすると、aLinkポインタからポインタへの値を実際に変更しENTRIESて、新しく宣言されたものを指すようにすることを意図してNodeいました(現時点ではリークしています)。

または、削除する代わりにaLink、子ノードを削除して再利用できますaLink。つまり、これを置き換えます。

delete aLink;
aLink = new Node;
if(isThresholdInALink) {
    aLink->data = threshold;
    aLink->link = new Node;
}

これとともに:

delete aLink->link;
if(isThresholdInALink) {
    aLink->data = threshold;
    aLink->link = new Node;
} else {
    aLink->data = 0;
    aLink->link = NULL;
}

悪いコードが Linux で機能するのはなぜですか? 推測では、新しく宣言Nodeされたノードは、元の削除されたノードと同じ場所に偶然作成されているため、ENTRIES誤って正しい場所を指しています。

lessHeadorは必要ないこともコメントしますmoreHead。彼らは何の役にも立ちません。それらを完全に削除します。と同様aHeadに、lessmoreはポインターへのポインターとして宣言されていないため、呼び出し元の関数の値は の内部で発生したことの影響を受けませんsplit_them_up

追加:デストラクタ、

~Node() {delete link;}

リンクが大きい場合、スタックがオーバーフローする可能性があります。再帰は素晴らしいことですが、極端に実行するとそうではありません。:-)

于 2013-03-31T07:36:44.430 に答える