2015-11-03 132 views
0

對於這個程序,我創建了一個單詞詞典的AVL自平衡二叉搜索樹,這將使用戶能夠根據等級查找單詞,rank是數字在當前節點+ 1下找到的節點,或者他們可以選擇在樹中給出隨機單詞。不幸的是,當我運行這段代碼:編譯時C++ AVL二叉搜索樹問題

#include "DictionaryAVT.h" 
#include<string> 
#include<iostream> 
#include<sstream> 
#include<algorithm> 
#include<fstream> 
#include<time.h> 
#include<stdlib.h> 

using namespace std; 

Node:: Node() 
{ 

    left = right = NULL; 
} 

Node::~Node() 
{ 
    delete this->left; 
    delete this->right; 
    this->left = this->right = NULL; 
    height = 1; 
} 

Node:: Node(string str) 
{ 
    word = str; 
    height = 1; 
    left = NULL; 
    right = NULL; 
} 

void Node::toString() 
{ 
    cout << "Word: " << word; 
} 

BST::BST() 
{ 
    this->root = NULL; 
    createDictionary(); 
} 

string BST:: removePunctuation(string * str) 
{ 
    { 
      string temp = *str; 
      for(int i = 0; i < temp.size(); i++) 
      { 
       if(ispunct(temp[i])) 
        temp.erase(i--, 1); 
      } 
      return temp; 
     } 
} 

void BST:: clear(Node * n) 
{ 
    if(n->left != NULL) 
     clear(n->left); 
    if(n->right != NULL) 
     clear(n->right); 

    delete n; 
    n = NULL; 
    size--; 
} 


void BST:: toString(Node * r) 
{ 
    if(r) 
    { 
     r->toString(); 
     toString(r->left); 
     toString(r->right); 
    } 
} 

void BST:: toString() 
{ 
    if(root) 
    { 
     root->toString(); 
     toString(root->left); 
     toString(root->right); 
    } 
} 

int BST:: height(Node * n) 
{ 
    if(n) 
    { 
     return 1+(height(n->left) + height(n->right)); 
    } 

    else 
     return 0; 



} 

void BST::LR(Node*& k2) 
{ 
    Node* k1 = k2->left; 
    k2->left = k1->right; 
    k1 -> right = k2; 
    k2->height = (height(k2->left)+(height(k2->right)))+1; 
    k1->height = (height(k1->left) + (height(k1->right)))+1; 
    k2 = k1; 
} 

void BST::RR(Node*& k2) 
{ 
    Node* k1 = k2 -> right; 
    k2 -> right = k1 -> left; 
    k1 -> left = k2; 
    k1->height = (height(k1->left)+(height(k1->right)))+1; 
    k2->height = (height(k2->right)+(height(k2->left)))+1; 
    k2 = k1; 
} 

void BST::insert(string word, Node *& root) 
{ 

    if(!root) 
    { 
     root = new Node(word); 

    } 

    else if(word < root->word) 
    { 
     insert(word, root->left); 

     if(height(root->left)-height(root->right)>1) 
     { 
      if(height(root->left->left) >= height(root->left->right)) 
      { 

       LR(root); 
      } 

      else 
      { 
       RR(root->left); 
       LR(root); 
      } 
     } 

    } 

    else if(root->word < word) 
    { 
     insert(word, root->right); 
     if(height(root->right) - height(root->left) > 1) 
     { 
      if(height(root->right->right)>=height(root->right->left)) 
      { 

       RR(root); 
      } 

      else 
      { 

       LR(root->right); 
       RR(root); 
      } 
     } 
    } 
    root->height = 1 + (height(root->left)+height(root->right)); 

} 

string BST:: search(Node * root, int x) 
{ 
    if(!root) 
    { 
     return "No Node found"; 
    } 

    else if(x < root->height) 
     search(root->left, x); 
    else if(x > root->height) 
     search(root->right,x); 
    else 
     return root->word; 
} 

void BST:: addWord(string str) 
{ 
    insert(str, root); 
} 

string BST:: getWordOfDay(int x) 
{ 
    int m = 1+height(root->left); 
    if(m == x) 
     return root->word; 
    else if(m > x) 
     return search(root->left, x); 
    else 
     return search(root->right,(x-m)); 
} 

void BST:: createDictionary() 
{ 
    string str; 
    ifstream inFile("english.txt"); 
    if(inFile.is_open()) 
     { 
      getline(inFile, str); 
      while(inFile.eof() != true) 
      { 
       addWord(removePunctuation(&str)); 
       getline(inFile, str); 
      } 
     } 
} 

void BST:: driver() 
{ 
    string in; 
    cout << "Please input R for a word with said rank, or W if you would like the word of the day" << endl; 
    cin >> in; 
    while(in == "R" || in == "W") 
    { 
     BST *bst = new BST(); 
     if(in == "R" || in == "r") 
     { 
      int x; 
      cout << "Please input a rank: "; 
      cin >> x; 
      cout << x << endl; 
      cout << "Word at rank " << x << "is: " << bst->getWordOfDay(x) << endl; 
     } 

     else if(in == "W" || in == "w") 
     { 
      srand(time(NULL)); 
      int x = rand() % bst->numberOfWords() + 1; 
      cout << "Word of the day is: " << bst->getWordOfDay(x) << endl; 
     } 

     cout << "Please input R for a word with said rank, or W if you would like the word of the day" << endl; 
     cin >> in; 
    } 

} 

int main()//tester method 
{ 
    BST* bst = new BST(); 
    cout << bst->numberOfWords() << endl; 
    cout << bst->getWordOfDay(1) << endl; 
} 

我得到這個錯誤:

*** glibc detected *** ./DictionaryAVT: free(): invalid pointer: 0x402e1394 *** 
======= Backtrace: ========= 
/lib/libc.so.6(+0x6d6f4)[0x401e86f4] 
/lib/libc.so.6(+0x6f003)[0x401ea003] 
/lib/libc.so.6(cfree+0x6d)[0x401ed13d] 
/usr/lib/libstdc++.so.6(_ZdlPv+0x1f)[0x400a061f] 
/usr/lib/libstdc++.so.6(_ZNSs4_Rep10_M_destroyERKSaIcE+0x1b)[0x4010b11b] 
/usr/lib/libstdc++.so.6(+0xb8160)[0x4010b160] 
/usr/lib/libstdc++.so.6(_ZNSsD1Ev+0x2e)[0x4010b1ce] 
./DictionaryAVT[0x8049921] 
./DictionaryAVT[0x8049912] 
./DictionaryAVT[0x8049912] 
./DictionaryAVT[0x8049912] 
./DictionaryAVT[0x8049912] 
./DictionaryAVT[0x8049912] 
./DictionaryAVT[0x8049912] 
./DictionaryAVT[0x8049912] 
./DictionaryAVT[0x8049912] 
./DictionaryAVT[0x8049912] 
./DictionaryAVT[0x8049912] 
./DictionaryAVT[0x8049912] 
./DictionaryAVT[0x8049912] 
./DictionaryAVT[0x8049912] 
./DictionaryAVT[0x8049912] 
./DictionaryAVT[0x8049912] 
./DictionaryAVT[0x8049912] 
./DictionaryAVT[0x8049912] 
./DictionaryAVT[0x8049912] 
./DictionaryAVT[0x8049912] 
./DictionaryAVT[0x8049912] 
./DictionaryAVT[0x8049912] 
./DictionaryAVT[0x8049912] 
./DictionaryAVT[0x8049912] 
./DictionaryAVT[0x8049a59] 
./DictionaryAVT[0x8049f84] 
/lib/libc.so.6(__libc_start_main+0xe5)[0x40191c25] 
./DictionaryAVT[0x8048f51] 
======= Memory map: ======== 
08048000-0804b000 r-xp 00000000 00:13 8806711 /home/spsteph/C++/IT 279/Assignment 4/DictionaryAVT 
0804b000-0804c000 r--p 00002000 00:13 8806711 /home/spsteph/C++/IT 279/Assignment 4/DictionaryAVT 
0804c000-0804d000 rw-p 00003000 00:13 8806711 /home/spsteph/C++/IT 279/Assignment 4/DictionaryAVT 
0804d000-0829f000 rw-p 00000000 00:00 0   [heap] 
40000000-4001f000 r-xp 00000000 08:02 145836  /lib/ld-2.11.3.so 
4001f000-40020000 r--p 0001e000 08:02 145836  /lib/ld-2.11.3.so 
40020000-40021000 rw-p 0001f000 08:02 145836  /lib/ld-2.11.3.so 
40021000-40023000 rw-p 00000000 00:00 0 
40053000-40138000 r-xp 00000000 08:02 377022  /usr/lib/libstdc++.so.6.0.17 
40138000-4013c000 r--p 000e5000 08:02 377022  /usr/lib/libstdc++.so.6.0.17 
4013c000-4013d000 rw-p 000e9000 08:02 377022  /usr/lib/libstdc++.so.6.0.17 
4013d000-40144000 rw-p 00000000 00:00 0 
40144000-4016a000 r-xp 00000000 08:02 145851  /lib/libm-2.11.3.so 
4016a000-4016b000 r--p 00026000 08:02 145851  /lib/libm-2.11.3.so 
4016b000-4016c000 rw-p 00027000 08:02 145851  /lib/libm-2.11.3.so 
4016c000-40179000 r-xp 00000000 08:02 145962  /lib/libgcc_s.so.1 
40179000-4017a000 r--p 0000c000 08:02 145962  /lib/libgcc_s.so.1 
4017a000-4017b000 rw-p 0000d000 08:02 145962  /lib/libgcc_s.so.1 
4017b000-402de000 r-xp 00000000 08:02 145843  /lib/libc-2.11.3.so 
402de000-402e0000 r--p 00162000 08:02 145843  /lib/libc-2.11.3.so 
402e0000-402e1000 rw-p 00164000 08:02 145843  /lib/libc-2.11.3.so 
402e1000-402e7000 rw-p 00000000 00:00 0 
40300000-00 rw-p 00000000 00:00 0 
00-40400000 ---p 00000000 00:00 0 
bf88e000-bf8af000 rw-p 00000000 00:00 0   [stack] 
ffffe000-fffff000 r-xp 00000000 00:00 0   [vdso] 
make: *** [run] Aborted 

任何人都可以看到這是爲什麼happeneing?

+0

調試器說什麼? –

回答

0

您的錯誤引用了'無效指針',我在您的代碼中發現了可能出現此錯誤的兩個潛在問題。

1.析:

Node::~Node() 
{ 
    delete this->left; 
    delete this->right; 
    this->left = this->right = NULL; 
    height = 1; 
} 

當你不會初始化leftright,兩個變量是NULL,這將導致刪除無效的指針。我將其更改爲:

Node::~Node() 
{ 
    if (this->left!=NULL) 
     delete this->left; 
    if (this->left!=NULL) 
     delete this->right; 
} 

請注意,我沒有設置變量(如height=1)因爲當對象被刪除調用此函數。

2.功能明確:

void BST:: clear(Node * n) 
{ 
    if(n->left != NULL) 
     clear(n->left); 
    if(n->right != NULL) 
     clear(n->right); 

    delete n; 
    n = NULL; 
    size--; 
} 

你雖然檢查n->left != NULL,你不檢查,如果n爲NULL。你可以將其更改爲:

void BST:: clear(Node * n) 
{ 
    if (n != NULL) { 
     if(n->left != NULL) 
      clear(n->left); 
     if(n->right != NULL) 
      clear(n->right); 

     delete n; 
     size--; 
    } 
} 

當您使用new對象一定要刪除它,當你使用delete確保您傳遞的指針是有效的!

編輯:像Alex M.評論,delete NULL does nothing這使得我的第一點的變化沒有必要。第二個n!=NULL檢查仍然是必要的,因爲您訪問它的變量leftright

+2

空指針上的'delete'是一個空操作符。 – 2015-11-03 08:53:09

+0

謝謝,我不知道這一點。我改變了我的答案。 – agold